Skip to content

Commit

Permalink
feat(PropertyMappingStrategy): property mapping strategy that support…
Browse files Browse the repository at this point in the history
…s concatenating collections with bit strings (GitHub #307)
  • Loading branch information
Createsequence committed Jun 17, 2024
1 parent c6a7c76 commit 19bb167
Show file tree
Hide file tree
Showing 17 changed files with 143 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ protected void completeMapping(Object source, Target target) {
.collect(Collectors.toList());
Object origin = target.getOrigin();
propertyMappingStrategy.doMapping(
origin, source, sourceValues, mapping,
operation, origin, source, sourceValues, mapping,
sv -> propertyOperator.writeProperty(origin.getClass(), origin, mapping.getReference(), sourceValues)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ protected void completeMapping(Object source, Target target) {
.collect(Collectors.toList()) : sources;
Object origin = target.getOrigin();
propertyMappingStrategy.doMapping(
target.getExecution().getOperation(),
origin, source, sourceValues, mapping,
sv -> propertyOperator.writeProperty(origin.getClass(), origin, mapping.getReference(), sourceValues)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,18 @@ protected void completeMapping(Object source, Target target) {
AssembleOperation operation = execution.getOperation();
PropertyMappingStrategy propertyMappingStrategy = operation.getPropertyMappingStrategy();
Set<PropertyMapping> mappings = operation.getPropertyMappings();
doCompleteMapping(source, target.getOrigin(), mappings, propertyMappingStrategy);
doCompleteMapping(operation, source, target.getOrigin(), mappings, propertyMappingStrategy);
}

private void doCompleteMapping(
Object source, Object target, Set<PropertyMapping> mappings, PropertyMappingStrategy propertyMappingStrategy) {
AssembleOperation operation, Object source, Object target, Set<PropertyMapping> mappings, PropertyMappingStrategy propertyMappingStrategy) {
PropDesc sourceDesc = propertyOperator.getPropertyDescriptor(source.getClass());
PropDesc targetDesc = propertyOperator.getPropertyDescriptor(target.getClass());
for (PropertyMapping mapping : mappings) {
Object sourceValue = mapping.hasSource() ?
sourceDesc.readProperty(source, mapping.getSource()) : source;
propertyMappingStrategy.doMapping(
target, source, sourceValue, mapping,
operation, target, source, sourceValue, mapping,
sv -> targetDesc.writeProperty(target, mapping.getReference(), sourceValue)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cn.crane4j.core.parser.handler.strategy;

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.operation.AssembleOperation;
import cn.crane4j.core.util.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.Collection;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
* Join as string mapping strategy.
*
* @author huangchengxing
* @see AssembleOperation#getKeyDescription()
* @since 2.9.0
*/
public class CollJoinAsStringMappingStrategy implements PropertyMappingStrategy {

public static final CollJoinAsStringMappingStrategy INSTANCE = new CollJoinAsStringMappingStrategy();
private static final String DEFAULT_DELIMITER = ",";

/**
* Map {@code sourceValue} to reference fields in target.
*
* @param operation assemble operation
* @param target target object
* @param source source object
* @param sourceValue source value
* @param propertyMapping property mapping
* @param mapping mapping action
*/
@Override
public void doMapping(
AssembleOperation operation,
Object target, Object source, @Nullable Object sourceValue,
PropertyMapping propertyMapping, Consumer<Object> mapping) {
if (sourceValue instanceof Collection) {
String delimiter = StringUtils.emptyToDefault(operation.getKeyDescription(), DEFAULT_DELIMITER);
sourceValue = ((Collection<?>)sourceValue).stream()
.map(String::valueOf)
.collect(Collectors.joining(delimiter));
}
mapping.accept(sourceValue);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.crane4j.core.parser.handler.strategy;

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.operation.AssembleOperation;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.function.Consumer;
Expand All @@ -13,22 +14,12 @@
*/
public class OverwriteMappingStrategy implements PropertyMappingStrategy {

public static final String NAME = OverwriteMappingStrategy.class.getSimpleName();
public static final OverwriteMappingStrategy INSTANCE = new OverwriteMappingStrategy();

/**
* Get strategy name.
*
* @return name
*/
@Override
public String getName() {
return NAME;
}

/**
* Map {@code sourceValue} to reference fields in target.
*
* @param operation assemble operation
* @param target target object
* @param source source object
* @param sourceValue source value
Expand All @@ -37,6 +28,7 @@ public String getName() {
*/
@Override
public void doMapping(
AssembleOperation operation,
Object target, Object source, @Nullable Object sourceValue,
PropertyMapping propertyMapping, Consumer<Object> mapping) {
mapping.accept(sourceValue);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.crane4j.core.parser.handler.strategy;

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.operation.AssembleOperation;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.Objects;
Expand All @@ -14,22 +15,12 @@
*/
public class OverwriteNotNullMappingStrategy implements PropertyMappingStrategy {

public static final String NAME = OverwriteNotNullMappingStrategy.class.getSimpleName();
public static final OverwriteNotNullMappingStrategy INSTANCE = new OverwriteNotNullMappingStrategy();

/**
* Get strategy name.
*
* @return name
*/
@Override
public String getName() {
return NAME;
}

/**
* Map {@code sourceValue} to reference fields in target.
*
* @param operation assemble operation
* @param target target object
* @param source source object
* @param sourceValue source value
Expand All @@ -38,6 +29,7 @@ public String getName() {
*/
@Override
public void doMapping(
AssembleOperation operation,
Object target, Object source, @Nullable Object sourceValue,
PropertyMapping propertyMapping, Consumer<Object> mapping) {
if (Objects.nonNull(sourceValue)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.crane4j.core.parser.handler.strategy;

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.operation.AssembleOperation;
import cn.crane4j.core.support.NamedComponent;
import org.checkerframework.checker.nullness.qual.Nullable;

Expand All @@ -18,16 +19,23 @@
*/
public interface PropertyMappingStrategy extends NamedComponent {

String Coll_JOIN_AS_STRING = CollJoinAsStringMappingStrategy.class.getSimpleName();
String OVERWRITE = OverwriteMappingStrategy.class.getSimpleName();
String OVERWRITE_NOT_NULL = OverwriteNotNullMappingStrategy.class.getSimpleName();
String REFERENCE = ReferenceMappingStrategy.class.getSimpleName();

/**
* Map {@code sourceValue} to reference fields in target.
*
* @param operation assemble operation
* @param target target object
* @param source source object
* @param sourceValue source value
* @param propertyMapping property mapping
* @param mapping mapping action
*/
void doMapping(
AssembleOperation operation,
Object target, Object source, @Nullable Object sourceValue,
PropertyMapping propertyMapping, Consumer<Object> mapping);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.crane4j.core.parser.handler.strategy;

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.operation.AssembleOperation;
import cn.crane4j.core.support.reflect.PropertyOperator;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.nullness.qual.Nullable;
Expand All @@ -18,22 +19,12 @@
@RequiredArgsConstructor
public class ReferenceMappingStrategy implements PropertyMappingStrategy {

public static final String NAME = ReferenceMappingStrategy.class.getSimpleName();
private final PropertyOperator propertyOperator;

/**
* Get strategy name.
*
* @return name
*/
@Override
public String getName() {
return NAME;
}

/**
* Map {@code sourceValue} to reference fields in target.
*
* @param operation assemble operation
* @param target target object
* @param source source object
* @param sourceValue source value
Expand All @@ -42,6 +33,7 @@ public String getName() {
*/
@Override
public void doMapping(
AssembleOperation operation,
Object target, Object source, @Nullable Object sourceValue,
PropertyMapping propertyMapping, Consumer<Object> mapping) {
Object referencePropertyValue = propertyOperator.readProperty(target.getClass(), target, propertyMapping.getReference());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cn.crane4j.core.parser.handler.strategy;

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.SimplePropertyMapping;
import cn.crane4j.core.parser.operation.SimpleAssembleOperation;
import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;

/**
* test for {@link CollJoinAsStringMappingStrategy}
*
* @author huangchengxing
*/
public class CollJoinAsStringMappingStrategyTest {

@Test
public void test() {
CollJoinAsStringMappingStrategy strategy = CollJoinAsStringMappingStrategy.INSTANCE;
PropertyMapping mapping = new SimplePropertyMapping("src", "ref");
strategy.doMapping(
SimpleAssembleOperation.builder().keyDescription(" | ").build(),
new Object(), new Object(), Arrays.asList(1, 2, 3),
mapping,
values -> Assert.assertEquals(values, "1 | 2 | 3")
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.SimplePropertyMapping;
import cn.crane4j.core.parser.operation.SimpleAssembleOperation;
import org.junit.Assert;
import org.junit.Test;

Expand All @@ -17,6 +18,7 @@ public void test() {
OverwriteMappingStrategy overwriteMappingStrategy = OverwriteMappingStrategy.INSTANCE;
PropertyMapping mapping = new SimplePropertyMapping("src", "ref");
overwriteMappingStrategy.doMapping(
SimpleAssembleOperation.builder().build(),
new Object(), new Object(), new Object(), mapping, Assert::assertNotNull
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.SimplePropertyMapping;
import cn.crane4j.core.parser.operation.SimpleAssembleOperation;
import org.junit.Assert;
import org.junit.Test;

Expand All @@ -17,9 +18,11 @@ public void test() {
OverwriteNotNullMappingStrategy strategy = OverwriteNotNullMappingStrategy.INSTANCE;
PropertyMapping mapping = new SimplePropertyMapping("src", "ref");
strategy.doMapping(
SimpleAssembleOperation.builder().build(),
new Object(), new Object(), new Object(), mapping, Assert::assertNotNull
);
strategy.doMapping(
SimpleAssembleOperation.builder().build(),
new Object(), new Object(), null, mapping, t -> Assert.fail()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cn.crane4j.core.parser.PropertyMapping;
import cn.crane4j.core.parser.SimplePropertyMapping;
import cn.crane4j.core.parser.operation.SimpleAssembleOperation;
import cn.crane4j.core.support.reflect.PropertyOperator;
import cn.crane4j.core.support.reflect.ReflectivePropertyOperator;
import lombok.AllArgsConstructor;
Expand All @@ -25,12 +26,14 @@ public void test() {
Foo target = new Foo();
PropertyMapping mapping = new SimplePropertyMapping("name", "name");
strategy.doMapping(
SimpleAssembleOperation.builder().build(),
target, source, source.getName(), mapping, t -> target.setName((String)t)
);
Assert.assertEquals(source.getName(), target.getName());

source.setName("test2");
strategy.doMapping(
SimpleAssembleOperation.builder().build(),
target, source, source.getName(), mapping, t -> target.setName((String)t)
);
Assert.assertNotEquals(source.getName(), target.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public List<Container<Object>> get(@Nullable Object source, Method method, Colle

Assert.assertSame(ops, ops.registerContainerLifecycleProcessor(new ContainerLifecycleProcessor() { }));
Assert.assertSame(ops, ops.registerOperationAnnotationHandler((parser, beanOperations) -> { }));
Assert.assertSame(ops, ops.registerPropertyMappingStrategy((target, source, sourceValue, propertyMapping, mapping) -> { }));
Assert.assertSame(ops, ops.registerPropertyMappingStrategy((operation, target, source, sourceValue, propertyMapping, mapping) -> { }));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import cn.crane4j.core.parser.handler.AssembleKeyAnnotationHandler;
import cn.crane4j.core.parser.handler.DisassembleAnnotationHandler;
import cn.crane4j.core.parser.handler.OperationAnnotationHandler;
import cn.crane4j.core.parser.handler.strategy.CollJoinAsStringMappingStrategy;
import cn.crane4j.core.parser.handler.strategy.OverwriteMappingStrategy;
import cn.crane4j.core.parser.handler.strategy.OverwriteNotNullMappingStrategy;
import cn.crane4j.core.parser.handler.strategy.PropertyMappingStrategy;
Expand Down Expand Up @@ -230,6 +231,11 @@ public SimplePropertyMappingStrategyManager simplePropertyMappingStrategyManager
return manager;
}

@Bean
public CollJoinAsStringMappingStrategy joinAsStringMappingStrategy() {
return CollJoinAsStringMappingStrategy.INSTANCE;
}

@Bean
public OverwriteNotNullMappingStrategy overwriteNotNullMappingStrategy() {
return OverwriteNotNullMappingStrategy.INSTANCE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import cn.crane4j.core.parser.handler.AssembleMethodAnnotationHandler;
import cn.crane4j.core.parser.handler.DisassembleAnnotationHandler;
import cn.crane4j.core.parser.handler.OperationAnnotationHandler;
import cn.crane4j.core.parser.handler.strategy.CollJoinAsStringMappingStrategy;
import cn.crane4j.core.parser.handler.strategy.OverwriteMappingStrategy;
import cn.crane4j.core.parser.handler.strategy.OverwriteNotNullMappingStrategy;
import cn.crane4j.core.parser.handler.strategy.PropertyMappingStrategy;
Expand Down Expand Up @@ -382,6 +383,11 @@ public SimplePropertyMappingStrategyManager simplePropertyMappingStrategyManager
return manager;
}

@Bean
public CollJoinAsStringMappingStrategy joinAsStringMappingStrategy() {
return CollJoinAsStringMappingStrategy.INSTANCE;
}

@Bean
public OverwriteNotNullMappingStrategy overwriteNotNullMappingStrategy() {
return OverwriteNotNullMappingStrategy.INSTANCE;
Expand Down
Loading

0 comments on commit 19bb167

Please sign in to comment.