package fr.openwide.core.basicapp.web.application.common.typedescriptor;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;
import org.javatuples.Pair;
import com.google.common.collect.Maps;
import fr.openwide.core.basicapp.web.application.common.util.ResourceKeyGenerator;
import fr.openwide.core.jpa.business.generic.model.GenericEntity;
import fr.openwide.core.jpa.util.HibernateUtils;
public abstract class AbstractGenericEntityTypeDescriptor<T extends AbstractGenericEntityTypeDescriptor<?, E>, E extends GenericEntity<?, ?>> implements Serializable {
private static final long serialVersionUID = 4551490933539106231L;
private static final Map<Pair<Class<?>, Class<?>>, AbstractGenericEntityTypeDescriptor<?, ?>> ALL = Maps.newHashMap();
private final Class<E> clazz;
private final ResourceKeyGenerator resourceKeyGenerator;
protected AbstractGenericEntityTypeDescriptor(Class<?> typeDescriptorClass, Class<E> clazz, String name) {
ALL.put(Pair.<Class<?>, Class<?>>with(typeDescriptorClass, clazz), this);
this.clazz = checkNotNull(clazz);
this.resourceKeyGenerator = ResourceKeyGenerator.of(checkNotNull(name));
}
@SuppressWarnings("unchecked")
protected static final <T extends AbstractGenericEntityTypeDescriptor<?, E>, E extends GenericEntity<?, ?>> T get(Class<?> typeDescriptorClass, E entity) {
if (entity == null) {
return null;
}
AbstractGenericEntityTypeDescriptor<?, ?> specificTypeDescriptor = ALL.get(Pair.<Class<?>, Class<?>>with(typeDescriptorClass, HibernateUtils.getClass(entity)));
if (specificTypeDescriptor != null) {
return (T) specificTypeDescriptor;
}
// fallback
for (Entry<Pair<Class<?>, Class<?>>, AbstractGenericEntityTypeDescriptor<?, ?>> entry : ALL.entrySet()) {
if (entry.getKey().getValue0().equals(typeDescriptorClass) && entry.getKey().getValue1().isInstance(entity)) {
return (T) entry.getValue();
}
}
throw new IllegalStateException("Unknown type for entity " + entity);
}
public Class<E> getEntityClass() {
return clazz;
}
public ResourceKeyGenerator business() {
return resourceKeyGenerator.withPrefix("business");
}
public ResourceKeyGenerator resourceKeyGenerator() {
return resourceKeyGenerator;
}
protected abstract Object readResolve();
}