Skip to content

Commit

Permalink
Added tests for mapping records with nested records.
Browse files Browse the repository at this point in the history
Process Feedback in preparation of release.

- Renamed RecordConstruct, to BeanRecordConstruct, to comply with
  naming conventions.
- Renamed RecordConstructMode, to BeanRecordConstructMode, to comply
  naming conventions.
- Replaced FlushAfterClearInstruction-enum with the more widely-usable
  Trinary-enum.
- Retouched DefaultBeanInitializer, to use BeanMapper's utility methods
  as much as possible.
- Updated CHANGELOG.md

Added arbitrarily deep Optional Mapping

- BeanMapper#map(Optional, Class) should now allow for mapping of
  Optional<Optional<?>> to a target class. Every Optional may also
  contain another Optional. The only limit is the recursion limit.
- It is now possible to automatically map Optional<X> to Optional<Y>,
due to changes in the OptionalToObjectConverter.
- Supports mapping Optional<List<X>> to Optional<List<Y>>. Same for
  Sets.
- Added mapping Optional<Map<X>> to Optional<Map<Y>>.

Fixes FieldShadowingException for ignored fields.

- Ignoring fields with BeanIgnore-annotation when detecting field
  shadowing.
- Fixed problem with getting a class using the name of an accessor.

Fix for #132

- Added BeanMatchStore#detectBeanPropertyFieldShadowing(PropertyAccessor
  , io.beanmapper.annotations.BeanProperty), which detects field
  shadowing and throws a FieldShadowingException when appropriate.

Added Mapping to and from Record-classes

- Improved the use of generics in BeanConverter, and its derived
  classes.
- Changed AbstractBeanConverter#convert, to allow the mapping of null to
  primitives, by using the default value for the relevant primitive,
  using Configuration#getDefaultValuesForClass(Class).
- Modified AbstractMapStrategy#convert, to offer null-values to
  BeanConverters.
- Added AssertionUtils to tests, containing some useful macros for
  certain tedious-to-write assertions.
- Added documentation to BeanAlias, to - hopefully - make it easier to
  understand its purpose, and map its valid use-cases.
- Improved the use of generics in the BeanMapper-class.
- Added the RecordToAnyConverter to the default converters in
  BeanMapperBuilder#addDefaultConverters().
- Added BeanMapperBuilder#addCustomDefaultValue(Class, Object), which
  allows users to set their own defaults, even allowing defaults for
  complex objects.
- Added MappingException, to create a common super-class for exceptions
  relating to bean-mapping and record-mapping.
- Replaced conditionals where an annotation is compared with null with
  usages of Class#isAnnotationPresent(Class).
- Added ClassGenerator#createClassDerivedFromRecord(Class, Set<String>),
  which dynamically creates a class based off of a Record-class, setting
  the field-modifiers to public.
- Added PropertyAccessor#isAnnotationPresent(Class), which checks
  whether the given annotation-class is present on the accessor.
- Added Configuration#addCustomDefaultValueForClass(Class, Object),
  which allows users to set default values for any type during runtime.
- Added Configuration#getDefaultValueForClass(Class), which allows the
  user to retrieve a default value mapped to a given class. This method
  will search the custom default values first, the default values in the
  DefaultValues-class second, and lastly, if no value is found, will
  return null.
- Added check to ConstructorArguments-constructor, to ensure that the
  constructorArgs-array is never null.
- Added a Map<Class, Object> to CoreConfiguration and
  OverrideConfiguration, to allow for the storing of custom default
  values.
- Modified DefaultBeanInitializer#mapParameterizedArguments, to pass a
  ParameterizedType to BeanMapper#map(Object, ParameterizedType) when
  appropriate.
- Added defaults for Optional, List, Set and Map to DefaultValues.
- Using unsupported methods in the PropertyAccessor-implementations now
  result in an UnsupportedOperationException being thrown.
- Improved usage of generics in MapStrategy and implementing classes.
- Modified MapToClassStrategy#map(Object) to let the
  RecordToAnyConverter handle a source Record.
- Added MapToRecordStrategy, which is used to map a source to a Record.
  Somewhat similar to the way a class annotated with BeanConstruct is
  mapped.
- Instances where Field#setAccessible(boolean) is called, are now
  preceded by a check to make certain that those fields are
  inaccessible.
- PrimitiveConvert will no longer throw an Exception when null is passed
  as the source to
  PrimitiveConverter#convert(BeanMapper, Object, Class,
  BeanPropertyMatch). Rather, the default value for the target-class is
  retrieved and returned.
- Added PropertyAccessors#findPropertyDescriptorsForRecord(Class), which
  compiles a Map<String, PropertyDescriptor>, based on the names of the
  RecordComponent-objects of the Record, and their accessors.
- Added RecordConstruct, which provides runtime-instructions to
  BeanMapper.
- Added RecordConstructMode, can be used to set which constructor in a
  Record should be used, or excluded, by BeanMapper, while mapping to a
  Record.
- Added RecordConstructorConflictException, which will be thrown while
  attempting to map to a record which has multiple constructors set with
  the constructMode-option set to RecordConstructMode.FORCE. Notifies
  the user of the constructors with the conflicting constructors.
- Added RecordToAnyConverter, which is used to dynamically create a
  class, based off of the source Record. The dynamically generated class
  is then used as an intermediary between the Record and the
  target-class.
- Added SourceFieldAccessException, which is thrown when the
  MapToRecordStrategy cannot access a field in the target Record.
- Replaced all instances of String#format with String#formatted.
- Removed slf4j-api dependency, as it is transitive through
  jcl-over-slf4j.
- Added tests to improve coverage.
- Updated CHANGELOG.md.

Fix for issue #168

- By catching Throwable, and saving Throwable in the List, rather than
  exception, the test should work correctly, and fail when it should.

Fix for issue #166

- Modified ClassGenerator#createClass, to check whether a generated
  field is annotated with BeanAlias. If so, the name of the generated
  field will be set to the value on the BeanAlias-annotation, and the
  annotation will be removed from the generated field.

Fix for issue #130

- Added DefaultBeanInitializer#mapParameterizedArguments(Type[],
  Object[]), allowing BeanMapper to properly map constructor parameters
  with a type-parameter, when using the @BeanConstruct-annotation.
- Using @sptdevos' tests to confirm proper functionality.
- Updated CHANGELOG.md

Added array-mapping

- Added BeanMapper#map(Object[], Class) allowing users to map an array
  to a new array of the given type.
- Added tests.
- Updated CHANGELOG.md

Added Queue-mapping

- Added BeanMapper#map(Queue, Class)
- Improved BeanMapperTest#mapQueueToTarget_PriorityQueue()
- Updated CHANGELOG.md

Set jackson-databind version to latest stable

Removed deprecated

- Removed BeanMapper#config().
- Removed BeanMapper#wrapConfig().
- Removed BeanMapperAware.java.
- Updated CHANGELOG.md

Converted BeanMapper from record, back to class.

Auto-reformat using MAD-style

Replaced NOPs in OverrideConfiguration with suitable Exceptions.

- OverrideConfiguration#withoutDefaultConverters throws a
  BeanConfigurationOperationNotAllowedException(String).
- OverrideConfiguration#addLogicSecuredCheck throws a
  BeanConfigurationOperationNotAllowedException(String).
- OverrideConfiguration#addCollectionHandler throws a
  BeanConfigurationOperationNotAllowedException(String)
- OverrideConfiguration#addProxySkipClass throws a
  BeanConfigurationOperationNotAllowedException(String).
- OverrideConfiguration#addPackagePrefix(Class<?>) throws a
  BeanConfigurationOperationNotAllowedException(String).
- OverrideConfiguration#addPackagePrefix(String) throws a
  BeanConfigurationOperationNotAllowedException(String).
- OverrideConfiguration#addAfterClearFlusher throws a
  BeanConfigurationOperationNotAllowedException(String).
- OverrideConfiguration#setRoleSecuredCheck throws a
  BeanConfigurationOperationNotAllowedException(String).
- OverrideConfiguration#setBeanUnproxy throws a
  BeanConfigurationOperationNotAllowedException(String).
- Updated tests.
- Updated CHANGELOG.md.

Replaced usages of Boolean-class, with primitive or enum.

- Replaced the OverrideConfiguration#flushAfterClear-Boolean with enum
  FlushAfterClearInstruction. The FlushAfterClearInstruction-enum, just
  like the Boolean-wrapper, allows for three values:
  FlushAfterClearInstruction#FLUSH_ENABLED (true),
  FlushAfterClearInstruction#FLUSH_DISABLED (false) and
  FlushAfterClearInstruction#UNSET (null). Using this enum mitigates the
  unpleasant usage of the Boolean-class, and should prevent NPEs.
- Replaced the usage of Boolean with the primitive boolean, wherever
  possible.
- Updated tests where necessary.
- Updated CHANGELOG.md

Methods that return a collection will always return a non-null object.

- Every method that returns a collection that may be null, will check
  whether the collection is null. If the collection is null, the method
  will return an empty, immutable collection of the correct type.
- Updated relevant tests to reflect that methods returning a collection
  will never return null when a collection is required.
- Updated CHANGELOG.md

Added Collection and Queue mapping

- Added BeanMapper#map(Collection, Class), allowing users to map from a
  Collection to the actual type of the Collection automatically.
- Added QueueCollectionHandler, allowing mapping of subtypes of the
  Queue-interface.

Bumped jackson-databind dependency

- Bumped the jackson-databind dependency up to version 2.14.0-rc1, due
  to a transitive vulnerability.
- Extracted plugin-versions to properties.

Updated dependencies and CHANGELOG.md
  • Loading branch information
marcus-talbot42 committed Nov 9, 2022
1 parent af478af commit fde6bd9
Show file tree
Hide file tree
Showing 218 changed files with 4,448 additions and 1,127 deletions.
72 changes: 67 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,82 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## Unreleased

### Updated

- Upgraded JUnit 5.8.2 to 5.9.0
- Upgraded SLF4J 2.0.0 to 2.0.3
- Upgraded Javassist 3.29.1-GA to 3.29.2-GA
- Upgraded jackson-databind 2.13.4 to 2.13.4.2

### Fixed

- Issue [#130](https://github.com/42BV/beanmapper/issues/130) **@BeanConstruct does not map collection constructor arguments**; Added
DefaultBeanInitializer#mapParameterizedArguments(Type[], Object[]), allowing BeanMapper to properly map constructor parameters with a type-parameter, when
using the @BeanConstruct-annotation.
- Issue [#132](https://github.com/42BV/beanmapper/issues/132) **Mapping the same field twice ignores one of the mappings.**; Whenever a field is mapped, a check
will be performed to detect field shadowing in this way. If field shadowing is detected, a FieldShadowingException is thrown. However, a
BeanProperty-annotation may take on the name of a field that is non-public and for which an accessor is not exposed. Fields annotated with BeanIgnore are not
considered when checking for shadowing.
- Issue [#149](https://github.com/42BV/beanmapper/issues/149) **Support mapping of JDK 16+ records to classes.**; Added support for mapping record through the
usual BeanMapper#map(Object, Class<?>)-method.
- Issue [#152](https://github.com/42BV/beanmapper/issues/152) **Methods that return a Collection should never return null.**; All methods that return a
Collection, will return an empty Collection of the target type, rather than returning null.
- Issue [#153](https://github.com/42BV/beanmapper/issues/153) **https://github.com/42BV/beanmapper/issues/153**; Rather than using the Boolean-wrapper, all
occurrences of Boolean that are not absolutely necessary due to generics, have been replaced with the primitive boolean, or the
Trinary-enum.
- Issue [#166](https://github.com/42BV/beanmapper/issues/166) **Source with BeanAlias-annotated fields cannot be downsized.**; Modified
ClassGenerator#createClass, to check whether a generated field is annotated with BeanAlias. If so, the name of the generated field will be set to the value on
the BeanAlias-annotation, and the annotation will be removed from the generated field.
- Issue [#168](https://github.com/42BV/beanmapper/issues/168) **ClassGeneratorTest#shouldNotFailConcurrently always succeeds.**; By catching Throwable, and
saving Throwable in the List, rather than exception, the test should work correctly, and fail when it should.

### Added

- BeanMapper#map(Collection, Class) allowing users to map from a Collection to the type actual type of the
- Support for mapping Queue. A Queue will be mapped to an ArrayDeque by default. The order of elements is guaranteed to be preserved, except when the Queue is
mapped to a Queue that inherently modifies the order of elements (e.g. PriorityQueue).
- BeanMapper#map(Queue, Class) allowing users to map a Queue to a new Queue, mapping the elements of the source to the target class.
- BeanMapper#map(Object[], Class) allowing users to map an array to an array with elements of the type of the target class. Also works for primitive arrays.
- Support for mapping to and from JDK16 record-classes.
- @BeanRecordConstruct-annotation, used to give BeanMapper instructions on how to map a record.
- BeanRecordConstructMode-enum, which allows the user to exclude certain constructors from being used to map a record, or force one to be used.
- Configuration#addCustomDefaultValueForClass(Class<?>, Object value) and Configuration#getDefaultValueForClass(Class<?>), which can be used to define default
values for classes during runtime.
- RecordToAnyConverter, which creates a dynamic class based off of the given Record, which contains only public fields, corresponding to the RecordComponents.
The dynamic class is then filled with values from the source Record, and used as an intermediary between the source and the target.
- MappingException, to serve as a common super-class for Exceptions thrown while mapping classes, and records.
- Default values for Optional, List, Set and Map in the DefaultValues.
- BeanMapper#map(Object, ParameterizedType), allowing for smarter mapping of collections and optionals.
- BeanMatchStore#detectBeanPropertyFieldShadowing(PropertyAccessor, io.beanmapper.annotations.BeanProperty), which will throw a FieldShadowingException when
appropriate.
- Mapping of Optional-objects to a target class, using BeanMapper#map(Optional, Class).

### Changed

- Methods in OverrideConfiguration that used to perform NOP, now throw a BeanConfigurationOperationNotAllowedException.
- Removed deprecated method BeanMapper#config(), BeanMapper#wrapConfig().
- Removed deprecated class BeanMapperAware.
- @BeanAlias now applicable to RecordComponent.
- Expanded the use of type parameters to various methods throughout the library, including the BeanMapper-class.
- BeanConverters may be offered null-values now. Will default to returning the default value for the relevant type.

### Removed

- slf4j-api dependency, as it is transitive through jcl-over-slf4j.

## [4.0.1] - 2022-09-22

### Fixed

- Issue [#121](https://github.com/42BV/beanmapper/issues/121) **Mapping an Enum field to an Enum field of the same type fails when a custom toString method is
present.**; When an Enum with a custom toString-method was mapped to an Enum, the mapping would fail. Fixed by adding an instanceof check in the
- Issue [#121](https://github.com/42BV/beanmapper/issues/121) **Mapping an Enum field to an Enum field of the same type fails when a custom toString method is
present.**; When an Enum with a custom toString-method was mapped to an Enum, the mapping would fail. Fixed by adding an instanceof check in the
AnyToEnumConverter, making it use Enum#name() to get the name of an Enum, rather than toString.
- Issue [#137](https://github.com/42BV/beanmapper/issues/137) **https://github.com/42BV/beanmapper/issues/137**; Mapping a class with a getter that returns an
- Issue [#137](https://github.com/42BV/beanmapper/issues/137) **https://github.com/42BV/beanmapper/issues/137**; Mapping a class with a getter that returns an
Optional, would fail, as an Optional can typically not be mapped to the target class. Fixed implementing an OptionalToObjectConverter, which handles unpacking
an Optional, and additionally delegates further conversion back to the BeanMapper.
- DynamicClassGeneratorHelper was removed, due to returning null, and replaced with passing the baseclass for a generated class immediately to the constructor
- DynamicClassGeneratorHelper was removed, due to returning null, and replaced with passing the baseclass for a generated class immediately to the constructor
of GeneratedClass.


## [4.0.0] - 2022-09-15

### Changed
Expand Down
2 changes: 1 addition & 1 deletion docs/src/test/java/io/beanmapper/BeanConstructExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public Person(Long id, String firstName, String prefix, String lastName) {
}
}

@BeanConstruct({"firstName", "prefix", "lastName"})
@BeanConstruct({ "firstName", "prefix", "lastName" })
public static class PersonResult {
public String fullName;

Expand Down
45 changes: 25 additions & 20 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" 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">
<project xmlns="http://maven.apache.org/POM/4.0.0" 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">
<modelVersion>4.0.0</modelVersion>

<groupId>io.beanmapper</groupId>
Expand Down Expand Up @@ -52,11 +53,21 @@
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<jackson-databind.version>2.13.4</jackson-databind.version>
<javassist.version>3.29.1-GA</javassist.version>
<slf4j.version>2.0.0</slf4j.version>
<javassist.version>3.29.2-GA</javassist.version>
<slf4j.version>2.0.3</slf4j.version>

<junit.version>5.8.2</junit.version>
<jackson-databind.version>2.13.4.2</jackson-databind.version>
<junit.version>5.9.0</junit.version>

<maven.compiler.plugin.version>3.10.1</maven.compiler.plugin.version>
<maven.surefire.plugin.version>2.22.2</maven.surefire.plugin.version>
<maven.release.plugin.version>2.5.3</maven.release.plugin.version>
<nexus.staging.plugin.version>1.6.13</nexus.staging.plugin.version>
<jacoco.maven.plugin.version>0.8.8</jacoco.maven.plugin.version>
<owasp.dependency.check.version>7.2.1</owasp.dependency.check.version>
<maven.javadoc.plugin.version>3.4.1</maven.javadoc.plugin.version>
<maven.source.plugin.version>3.2.1</maven.source.plugin.version>
<maven.gpg.plugin.version>3.0.1</maven.gpg.plugin.version>
</properties>

<dependencies>
Expand All @@ -83,12 +94,6 @@
</dependency>

<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
Expand All @@ -109,7 +114,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
Expand All @@ -119,12 +124,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<version>${maven.surefire.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<version>${maven.release.plugin.version}</version>
<configuration>
<mavenExecutorId>forked-path</mavenExecutorId>
<useReleaseProfile>false</useReleaseProfile>
Expand All @@ -138,7 +143,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.13</version>
<version>${nexus.staging.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<serverId>sonatype-nexus-staging</serverId>
Expand All @@ -149,7 +154,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<version>${jacoco.maven.plugin.version}</version>
<executions>
<execution>
<goals>
Expand All @@ -168,7 +173,7 @@
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>7.1.2</version>
<version>${owasp.dependency.check.version}</version>
<configuration>
<failBuildOnAnyVulnerability>true</failBuildOnAnyVulnerability>
<skipProvidedScope>true</skipProvidedScope>
Expand All @@ -189,7 +194,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<version>${maven.javadoc.plugin.version}</version>
<configuration>
<source>${java.version}</source>
</configuration>
Expand All @@ -205,7 +210,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<version>${maven.source.plugin.version}</version>
<executions>
<execution>
<id>attach-sources</id>
Expand All @@ -218,7 +223,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<version>${maven.gpg.plugin.version}</version>
<executions>
<execution>
<id>sign-artifacts</id>
Expand Down
Loading

0 comments on commit fde6bd9

Please sign in to comment.