package org.rakam.collection; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.rakam.collection.SchemaField; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Sets.newHashSet; public class FieldDependencyBuilder { private final List<SchemaField> constantFields = Lists.newArrayList(); private final Map<String, List<SchemaField>> dependentFields = Maps.newHashMap(); public void addFields(List<SchemaField> fields) { checkFields(fields); constantFields.addAll(fields); } public void addFields(String dependentField, List<SchemaField> fields) { checkFields(fields); dependentFields.put(dependentField, fields); } private void checkFields(List<SchemaField> fields) { SchemaField[] collisions = fields.stream() .filter(newField -> constantFields.stream() .anyMatch(f -> f.getName().equals(newField.getName()) && !f.getType().equals(newField.getType()))) .toArray(SchemaField[]::new); checkState(collisions.length == 0, "Module field collides with existing field that has another type exists: ", Arrays.toString(collisions)); collisions = dependentFields.values().stream() .flatMap(col -> col.stream()) .filter(field -> fields.stream().anyMatch(f -> f.getName().equals(field.getName()) && !f.getType().equals(field.getType()))) .toArray(SchemaField[]::new); checkState(collisions.length == 0, "Fields already exist in dependency table: ", Arrays.toString(collisions)); } public FieldDependency build() { return new FieldDependency(newHashSet(constantFields), dependentFields); } public static class FieldDependency { public final Set<SchemaField> constantFields; public final Map<String, List<SchemaField>> dependentFields; public FieldDependency(Set<SchemaField> constantFields, Map<String, List<SchemaField>> dependentFields) { this.constantFields = Collections.unmodifiableSet(constantFields); this.dependentFields = Collections.unmodifiableMap(dependentFields); } } }