package restx.factory;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
import java.util.Iterator;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* User: xavierhanin
* Date: 2/9/13
* Time: 2:14 PM
*/
public class SatisfiedBOM {
private final BillOfMaterials bom;
private final ImmutableMultimap<Factory.Query<?>, NamedComponent<?>> materials;
public SatisfiedBOM(BillOfMaterials bom, ImmutableMultimap<Factory.Query<?>, NamedComponent<?>> materials) {
this.bom = bom;
this.materials = materials;
}
public BillOfMaterials getBom() {
return bom;
}
@SuppressWarnings("unchecked")
public <T> Iterable<NamedComponent<T>> get(Factory.Query<T> key) {
ImmutableCollection namedComponents = checkNotNull(materials.get(key),
"key not found: %s. Check your bill of materials. Available keys: %s", key, materials.keySet());
return (Iterable<NamedComponent<T>>) namedComponents;
}
public <T> Iterable<T> getAsComponents(Factory.Query<T> key) {
return Iterables.transform(get(key), NamedComponent.<T>toComponent());
}
public <T> Optional<NamedComponent<T>> getOne(Factory.Query<T> key) {
Iterator<NamedComponent<T>> components = get(key).iterator();
if (!components.hasNext()) {
return Optional.absent();
}
NamedComponent<T> component = components.next();
if (components.hasNext()) {
throw new IllegalStateException(String.format(
"more than one component is available for %s." +
" Please select which one you want with a more specific query." +
" Available components are: %s",
key, materials.get(key)));
}
return Optional.of(component);
}
public <T> Optional<T> getOneAsComponent(Factory.Query<T> key) {
Optional<NamedComponent<T>> namedComponent = getOne(key);
if(namedComponent.isPresent()) {
return Optional.of(namedComponent.get().getComponent());
} else {
return Optional.absent();
}
}
@Override
public String toString() {
return "SatisfiedBOM{" +
"bom=" + bom +
", materials=" + materials +
'}';
}
public Iterable<NamedComponent<? extends Object>> getAllComponents() {
return materials.values();
}
}