package xapi.model.api; import xapi.collect.X_Collect; import xapi.collect.api.StringDictionary; import xapi.util.api.ReceivesValue; import java.util.function.Supplier; /** * Created by james on 03/10/15. */ public class ModelBuilder <M extends Model> { private KeyBuilder key = new KeyBuilder(); private StringDictionary<Object> properties = X_Collect.newDictionary(); private Supplier<M> creator; public static <M extends Model> ModelBuilder<M> build(Supplier<M> creator) { ModelBuilder builder = new ModelBuilder(); builder.creator = creator; return builder; } public static <M extends Model> ModelBuilder<M> build(ModelKey withKey, Supplier<M> creator) { ModelBuilder builder = new ModelBuilder(); builder.key.fromKey(withKey); builder.creator = creator; return builder; } public static <M extends Model> ModelBuilder<M> build(KeyBuilder withBuilder, Supplier<M> creator) { ModelBuilder builder = new ModelBuilder(); builder.key.fromBuilder(withBuilder); builder.creator = creator; return builder; } public KeyBuilder key() { return key; } public ModelBuilder<M> withId(String id) { key.withId(id); return this; } public ModelBuilder<M> withCreator(Supplier<M> creator) { this.creator = creator; return this; } public ModelBuilder<M> withKind(String kind) { key.withKind(kind); return this; } public ModelBuilder<M> withNamespace(String namespace) { key.withNamespace(namespace); return this; } public ModelBuilder withProperty(String propName, Object value) { properties.setValue(propName, value); return this; } public ModelBuilder withParent(String propName, ModelKey parent) { key.withParent(parent); return this; } public ModelBuilder withParent(String propName, KeyBuilder parent) { key.withParent(parent); return this; } public M buildModel() { final M model = newModel(); model.setKey(key.buildKey()); copyProperties(model); return model; } private void copyProperties(final M model) { properties.forKeys(new ReceivesValue<String>() { @Override public void set(String id) { model.setProperty(id, properties.getValue(id)); } }); } private M newModel() { assert creator != null : "You MUST supply a creator to ModelBuilder"; final M model = creator.get(); return model; } public M buildModel(Supplier<M> creator) { Supplier<M> oldCreator = creator; this.creator = creator; M model = buildModel(); this.creator = oldCreator; oldCreator = null; return model; } public M buildModel(String id) { ModelKey newKey = key.buildKey(id); return buildModel(newKey); } public M buildModel(ModelKey key) { final M model = newModel(); model.setKey(key); copyProperties(model); return model; } }