package restx.factory;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* User: xavierhanin
* Date: 3/17/13
* Time: 5:56 PM
*/
public class FactoryMachineWrapper implements FactoryMachine {
public static Builder from(FactoryMachine factoryMachine) {
return new Builder().from(factoryMachine);
}
public static class Builder {
private FactoryMachine factoryMachine;
private Integer priority;
private Function transform;
private List<Factory.Query<?>> deps = Lists.newArrayList();
public Builder from(final FactoryMachine factoryMachine) {
this.factoryMachine = factoryMachine;
return this;
}
public Builder withPriority(final int priority) {
this.priority = priority;
return this;
}
public Builder withDependencies(Factory.Query<?>... q) {
deps.addAll(Lists.newArrayList(q));
return this;
}
public Builder transformComponents(final Function<Map.Entry<SatisfiedBOM, NamedComponent>, NamedComponent> transform) {
this.transform = transform;
return this;
}
public FactoryMachine build() {
if (transform == null) {
return new FactoryMachineWrapper(factoryMachine) {
@Override
public int priority() {
return priority == null ? super.priority() : priority;
}
};
}
return new FactoryMachineWrapper(factoryMachine) {
@Override
public int priority() {
return priority == null ? super.priority() : priority;
}
@Override
public <T> MachineEngine<T> getEngine(Name<T> name) {
return new MachineEngineWrapper<T>(super.getEngine(name)) {
@Override
public BillOfMaterials getBillOfMaterial() {
return super.getBillOfMaterial().addQueries(deps);
}
@Override
public ComponentBox<T> newComponent(final SatisfiedBOM satisfiedBOM) {
return new ComponentBoxWrapper<T>(super.newComponent(satisfiedBOM)) {
@Override
@SuppressWarnings("unchecked")
public Optional<NamedComponent<T>> pick() {
Optional<NamedComponent<T>> pick = super.pick();
if (!pick.isPresent()) {
return pick;
}
return Optional.of((NamedComponent<T>) transform.apply(
Maps.immutableEntry(satisfiedBOM, pick.get())));
}
};
}
};
}
};
}
}
private final FactoryMachine original;
public FactoryMachineWrapper(FactoryMachine original) {
this.original = original;
}
public boolean canBuild(Name<?> name) {
return original.canBuild(name);
}
public int priority() {
return original.priority();
}
public <T> MachineEngine<T> getEngine(Name<T> name) {
return original.getEngine(name);
}
public <T> Set<Name<T>> nameBuildableComponents(Class<T> componentClass) {
return original.nameBuildableComponents(componentClass);
}
@Override
public String toString() {
return "FactoryMachineWrapper{" +
"original=" + original +
'}';
}
}