package com.yoursway.utils.gemstones;
import static com.google.common.collect.Lists.newArrayList;
import static com.yoursway.utils.JavaStackFrameUtils.callerPackageOutside;
import static com.yoursway.utils.JavaStackFrameUtils.packageName;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.yoursway.utils.JavaStackFrameUtils;
public class GemstoneDefinitionBuilder<G extends Gemstone<G>> {
static class FaceletDefinition<F extends Facelet<G>, G extends Gemstone<G>> {
private final Class<? super F>[] faceletInterfaces;
private final FaceletFactory<F, G> factory;
public FaceletDefinition(Class<? super F>[] faceletInterfaces, FaceletFactory<F, G> factory) {
this.faceletInterfaces = faceletInterfaces;
this.factory = factory;
}
@SuppressWarnings("unchecked")
public void create(G gemstone, Map<Class<? extends Facelet<G>>, Facelet<G>> facelets,
Collection<Facelet<G>> allCreatedFacelets) {
F facelet = factory.create(gemstone);
allCreatedFacelets.add(facelet);
for (Class<? super F> klass : faceletInterfaces)
facelets.put((Class<? extends Facelet<G>>) klass, facelet);
}
}
private final List<SlotImpl<? extends Facelet<G>, G>> slots = newArrayList();
public <F extends Facelet<G>> Slot<F> addFacelet(FaceletFactory<F, G> factory, Class<F> interfaceToken) {
String interfaceClassName = interfaceToken.getName();
String interfacePackageName = packageName(interfaceClassName);
String implementationPackageName = callerPackageOutside(getClass());
String description = JavaStackFrameUtils.isTrivialExtention(interfacePackageName,
implementationPackageName) ? interfaceClassName : interfaceClassName + " implemented in "
+ implementationPackageName;
SlotImpl<F, G> slot = new SlotImpl<F, G>(slots.size(), description, factory);
slots.add(slot);
return slot;
}
public GemstoneDefinition<G> build() {
return new GemstoneDefinition<G>(slots);
}
public static <G extends Gemstone<G>> GemstoneDefinitionBuilder<G> create() {
return new GemstoneDefinitionBuilder<G>();
}
}