package fr.openwide.core.jpa.more.junit.difference;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.bindgen.Binding;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
import fr.openwide.core.commons.util.fieldpath.FieldPath;
import fr.openwide.core.jpa.more.business.history.model.atomic.HistoryDifferenceEventType;
public final class TestHistoryDifferenceDescription {
private final HistoryDifferenceEventType action;
private final ListMultimap<TestHistoryDifferenceKey, TestHistoryDifferenceDescription> differences;
public static Builder builder() {
return new Builder();
}
/* package */ TestHistoryDifferenceDescription(HistoryDifferenceEventType action) {
super();
this.action = action;
this.differences = ImmutableListMultimap.of();
}
/* package */ TestHistoryDifferenceDescription(HistoryDifferenceEventType action, Multimap<TestHistoryDifferenceKey, TestHistoryDifferenceDescription> differences) {
super();
this.action = action;
this.differences = ImmutableListMultimap.copyOf(differences);
}
public HistoryDifferenceEventType getAction() {
return action;
}
public ListMultimap<TestHistoryDifferenceKey, TestHistoryDifferenceDescription> getDifferences() {
return differences;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TestHistoryDifferenceDescription) {
TestHistoryDifferenceDescription other = (TestHistoryDifferenceDescription) obj;
return new EqualsBuilder()
.append(action, other.action)
.append(differences, other.differences)
.build();
} else {
return false;
}
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(action)
.append(differences)
.build();
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SIMPLE_STYLE)
.append("action", action)
.append("differences", differences)
.build();
}
public static abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
protected final ImmutableListMultimap.Builder<TestHistoryDifferenceKey, TestHistoryDifferenceDescription> delegate = ImmutableListMultimap.builder();
private AbstractBuilder() {
}
protected T put(FieldPath path, Object key, TestHistoryDifferenceDescription differenceDescription) {
delegate.put(new TestHistoryDifferenceKey(path, key), differenceDescription);
return thisAsT();
}
public T put(FieldPath path, HistoryDifferenceEventType action) {
return put(path, null, new TestHistoryDifferenceDescription(action));
}
public T putItem(FieldPath path, Object key, HistoryDifferenceEventType action) {
return put(toItem(path), key, new TestHistoryDifferenceDescription(action));
}
public T put(Binding<?> binding, HistoryDifferenceEventType action) {
return put(FieldPath.fromBinding(binding), null, new TestHistoryDifferenceDescription(action));
}
public T putItem(Binding<?> binding, Object key, HistoryDifferenceEventType action) {
return putItem(FieldPath.fromBinding(binding), key, action);
}
public ContainedBuilder<T> putComposite(FieldPath path, HistoryDifferenceEventType action) {
return new ContainedBuilder<T>(thisAsT(), path, null, action);
}
public ContainedBuilder<T> putItemComposite(FieldPath path, Object key, HistoryDifferenceEventType action) {
return new ContainedBuilder<T>(thisAsT(), toItem(path), key, action);
}
public ContainedBuilder<T> putComposite(Binding<?> binding, HistoryDifferenceEventType action) {
return new ContainedBuilder<T>(thisAsT(), FieldPath.fromBinding(binding), null, action);
}
public ContainedBuilder<T> putItemComposite(Binding<?> binding, Object key, HistoryDifferenceEventType action) {
return putItemComposite(FieldPath.fromBinding(binding), key, action);
}
private static FieldPath toItem(FieldPath path) {
return path.isItem() ? path : path.item();
}
protected abstract T thisAsT();
}
public static class Builder extends AbstractBuilder<Builder> {
private Builder() {
}
@Override
protected Builder thisAsT() {
return this;
}
public ListMultimap<TestHistoryDifferenceKey, TestHistoryDifferenceDescription> build() {
return delegate.build();
}
}
public static class ContainedBuilder<T extends AbstractBuilder<T>> extends AbstractBuilder<ContainedBuilder<T>> {
private final T caller;
private final FieldPath path;
private final Object key;
private final HistoryDifferenceEventType action;
private ContainedBuilder(T caller, FieldPath path, Object key, HistoryDifferenceEventType action) {
this.caller = caller;
this.path = path;
this.key = key;
this.action = action;
}
public T and() {
return caller.put(path, key, new TestHistoryDifferenceDescription(action, delegate.build()));
}
@Override
protected ContainedBuilder<T> thisAsT() {
return this;
}
}
}