package org.finra.datagenerator.scaffolding.transformer.service.transformations; import com.google.common.collect.Lists; import org.finra.datagenerator.scaffolding.transformer.function.FunctionTransformation; import org.finra.datagenerator.scaffolding.transformer.limitation.Limitation; import org.finra.datagenerator.scaffolding.transformer.support.Transformation; import org.finra.datagenerator.scaffolding.utils.ClassUtils; import org.springframework.util.Assert; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Created by dkopel on 11/29/16. */ public class TransformationsImpl { public static class MultiBuilder { Set<TransformationsImpl> ts = new HashSet(); public Builder withField(Field field) { return new Builder(this, field); } public Set<TransformationsImpl> build() { return ts; } } public static class Builder { private final MultiBuilder multiBuilder; private Field field; private Set<OrderImpl> orders = new HashSet(); private Set<TransformationImpl> value = new HashSet(); private Builder(MultiBuilder multiBuilder, Field field) { this.multiBuilder = multiBuilder; this.field = field; } public Builder withOrder(long order, String condition) { this.orders.add(new OrderImpl(order, condition)); return this; } public Builder withOrder(OrderImpl order) { this.orders.add(order); return this; } public TransformationsBuilder withTransformations() { return new TransformationsBuilder(this); } public Builder withTransformations(Transformation... ts) { for(Transformation t : ts) { this.value.add(new TransformationImpl(t)); } return this; } public TransformationsImpl get() { return new TransformationsImpl(field, orders, value); } public MultiBuilder build() { if(orders.size() == 0) { orders.add(new OrderImpl(Long.MAX_VALUE)); } multiBuilder.ts.add(new TransformationsImpl(field, orders, value)); return multiBuilder; } public static class TransformationsBuilder { private final Builder builder; private List<TransformationImpl> transformations = new ArrayList(); private TransformationsBuilder(Builder builder) { this.builder = builder; } public TransformationBuilder withTransformation() { return new TransformationBuilder(this); } public Builder withTransformation(Transformation... ts) { for(Transformation t : ts) { transformations.add(new TransformationImpl(t)); } return builder; } public Builder build() { builder.value.addAll(transformations); return builder; } } public static class TransformationBuilder { private final TransformationsBuilder builder; private TransformationBuilder(TransformationsBuilder builder) { this.builder = builder; } private long order = Long.MAX_VALUE; private boolean emptyString = false; private boolean isNull = false; private String value = ""; private FunctionTransformationImpl function = null; private String condition = ""; private List<Limitation> limits = new ArrayList(); public TransformationBuilder withValue(String value) { Assert.notNull(value); this.emptyString = false; this.isNull = false; this.value = value; this.function = null; return this; } public TransformationBuilder withOrder(long order) { this.order = order; return this; } public TransformationBuilder withEmptyString() { this.emptyString = true; this.isNull = false; this.value = ""; this.function = null; return this; } public TransformationBuilder withNull() { this.isNull = true; this.emptyString = false; this.value = ""; this.function = null; return this; } public TransformationBuilder withFunctionTransformation(String key, Class<? extends FunctionTransformation> clazz) { Assert.notNull(key); Assert.notNull(clazz); this.function = new FunctionTransformationImpl(key, clazz); return this; } public TransformationBuilder withCondition(String condition) { this.condition = condition; return this; } public TransformationBuilder withLimitation(Class<? extends Limitation> value, String[] args, Class[] classes) throws InstantiationException { LimitationImpl li = new LimitationImpl(value, args, classes); Limitation limit = ClassUtils.createNewInstance(li.getValue(), li.getArgs(), li.getClasses()); limits.add(limit); return this; } public TransformationBuilder withLimitions(Limitation... limitions) { limits.addAll(Lists.newArrayList(limitions)); return this; } public TransformationsBuilder build() { TransformationImpl ti = new TransformationImpl( emptyString, isNull, value, function, condition, limits.toArray(new Limitation[limits.size()]), order ); builder.transformations.add(ti); return builder; } } } public static Builder singleBuilder(Field field) { MultiBuilder m = new MultiBuilder(); return m.withField(field); } public static MultiBuilder multiBuilder() { return new MultiBuilder(); } public TransformationsImpl(Field field, Set<OrderImpl> orders, Set<TransformationImpl> value) { this.field = field; this.orders = orders; this.value = value; } private final Field field; private final Set<OrderImpl> orders; private final Set<TransformationImpl> value; public Field getField() { return field; } public Set<OrderImpl> getOrders() { return orders; } public Set<TransformationImpl> getValue() { return value; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof TransformationsImpl)) return false; TransformationsImpl that = (TransformationsImpl) o; if (field != null ? !field.equals(that.field) : that.field != null) return false; if (orders != null ? !orders.equals(that.orders) : that.orders != null) return false; return value != null ? value.equals(that.value) : that.value == null; } @Override public int hashCode() { int result = field != null ? field.hashCode() : 0; result = 31 * result + (orders != null ? orders.hashCode() : 0); result = 31 * result + (value != null ? value.hashCode() : 0); return result; } }