Last active
August 29, 2015 14:02
-
-
Save mikaelhg/1c167d36bd97cdedf83e to your computer and use it in GitHub Desktop.
Playing around with ideas for easily readable bean or even JSON converters using Java 8 lambdas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mikael.convert; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.function.*; | |
public class LambdaConverter { | |
public static class Foo { | |
public String getA() { return "A"; } | |
public void invalid(final String in) { System.err.println("INVALID"); } | |
} | |
public static class Bar { | |
public void setB(final String b) { System.out.println("b: " + b); } | |
public String invalid() { System.err.println("INVALID"); return "INVALID"; } | |
} | |
public static abstract class AbstractFieldTransfer<SOURCE, TARGET> { | |
protected final Converter<SOURCE, TARGET> converter; | |
public AbstractFieldTransfer(final Converter<SOURCE, TARGET> converter) { | |
this.converter = converter; | |
} | |
public boolean isActive(final SOURCE source) { | |
return true; | |
} | |
public abstract void convert(final SOURCE source, final TARGET target); | |
} | |
public static class FieldGroup<SOURCE, TARGET> extends AbstractFieldTransfer<SOURCE, TARGET> { | |
private final List<AbstractFieldTransfer<SOURCE, TARGET>> transfers = new ArrayList<>(); | |
private final Predicate<SOURCE> predicate; | |
private FieldGroup() { | |
this(null); | |
} | |
public FieldGroup(final Converter<SOURCE, TARGET> converter) { | |
this(converter, null); | |
} | |
public FieldGroup(final Converter<SOURCE, TARGET> converter, final Predicate<SOURCE> predicate) { | |
super(converter); | |
this.predicate = predicate; | |
} | |
public Converter<SOURCE, TARGET> end() { | |
return converter; | |
} | |
public <D> FieldGroup<SOURCE, TARGET> field( | |
final Function<SOURCE, D> in, final BiConsumer<TARGET, D> out) | |
{ | |
transfers.add(new Field<>(converter, in, out)); | |
return this; | |
} | |
public void convert(final SOURCE source, final TARGET target) { | |
transfers.stream() | |
.filter(t -> t.isActive(source)) | |
.forEach(t -> t.convert(source, target)); | |
} | |
@Override | |
public boolean isActive(final SOURCE source) { | |
return predicate == null || predicate.test(source); | |
} | |
} | |
public static class Field<SOURCE, TARGET, D> extends AbstractFieldTransfer<SOURCE, TARGET> { | |
private final Function<SOURCE, D> in; | |
private final BiConsumer<TARGET, D> out; | |
private Field() { | |
this(null, null, null); | |
} | |
public Field(final Converter<SOURCE, TARGET> converter, | |
final Function<SOURCE, D> in, final BiConsumer<TARGET, D> out) | |
{ | |
super(converter); | |
this.in = in; | |
this.out = out; | |
} | |
public void convert(final SOURCE source, final TARGET target) { | |
out.accept(target, in.apply(source)); | |
} | |
} | |
public static class Converter<SOURCE, TARGET> { | |
private final List<AbstractFieldTransfer<SOURCE, TARGET>> transfers = new ArrayList<>(); | |
public static <S, T> Converter<S, T> fromTo(final Class<S> cs, final Class<T> ct) { | |
return new Converter<>(); | |
} | |
public static <S, T> Converter<S, T> fromTo() { | |
return new Converter<>(); | |
} | |
public <D> Converter<SOURCE, TARGET> field( | |
final Function<SOURCE, D> in, final BiConsumer<TARGET, D> out) | |
{ | |
transfers.add(new Field<>(this, in, out)); | |
return this; | |
} | |
public FieldGroup<SOURCE, TARGET> fieldGroup() { | |
final FieldGroup<SOURCE, TARGET> ret = new FieldGroup<>(this); | |
transfers.add(ret); | |
return ret; | |
} | |
public FieldGroup<SOURCE, TARGET> fieldGroup(final Predicate<SOURCE> isGroupActive) { | |
final FieldGroup<SOURCE, TARGET> ret = new FieldGroup<>(this, isGroupActive); | |
transfers.add(ret); | |
return ret; | |
} | |
public TARGET convert(final SOURCE source, final TARGET target) { | |
transfers.stream() | |
.filter(t -> t.isActive(source)) | |
.forEach(t -> t.convert(source, target)); | |
return target; | |
} | |
} | |
public static void main(String[] args) { | |
final Converter<Foo, Bar> c1 = Converter.<Foo, Bar>fromTo() | |
.field(Foo::getA, Bar::setB); | |
final Converter<Foo, Bar> c2 = Converter.fromTo(Foo.class, Bar.class) | |
.field(Foo::getA, Bar::setB); | |
final Converter<Foo, Bar> c3 = Converter.fromTo(Foo.class, Bar.class) | |
.fieldGroup() | |
.field(Foo::getA, Bar::setB) | |
.end(); | |
final Converter<Foo, Bar> c4 = Converter.fromTo(Foo.class, Bar.class) | |
.fieldGroup(f -> f.getA().equals("I AM A TEAPOT")) | |
.field(Foo::getA, Bar::setB) | |
.end(); | |
final Bar bar = Converter.fromTo(Foo.class, Bar.class) | |
.fieldGroup(f -> f.getA().equals("I AM A TEAPOT")) | |
.field(Foo::getA, Bar::setB) | |
.end() | |
.convert(new Foo(), new Bar()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment