package org.hibernate.type.descriptor.java;
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.HibernateException;
import org.hibernate.type.descriptor.WrapperOptions;
import org.jboss.logging.Logger;
public class JavaTypeDescriptorRegistry {
private static final Logger log = Logger.getLogger( JavaTypeDescriptorRegistry.class );
public static final JavaTypeDescriptorRegistry INSTANCE = new JavaTypeDescriptorRegistry();
private ConcurrentHashMap<Class,JavaTypeDescriptor> descriptorsByClass = new ConcurrentHashMap<Class, JavaTypeDescriptor>();
public void addDescriptor(JavaTypeDescriptor descriptor) {
descriptorsByClass.put( descriptor.getJavaTypeClass(), descriptor );
}
@SuppressWarnings("unchecked")
public <T> JavaTypeDescriptor<T> getDescriptor(Class<T> cls) {
if ( cls == null ) {
throw new IllegalArgumentException( "Class passed to locate Java type descriptor cannot be null" );
}
JavaTypeDescriptor<T> descriptor = descriptorsByClass.get( cls );
if ( descriptor != null ) {
return descriptor;
}
if ( cls.isEnum() ) {
descriptor = new EnumJavaTypeDescriptor( cls );
descriptorsByClass.put( cls, descriptor );
return descriptor;
}
if ( Serializable.class.isAssignableFrom( cls ) ) {
return new SerializableTypeDescriptor( cls );
}
for ( Map.Entry<Class,JavaTypeDescriptor> entry : descriptorsByClass.entrySet() ) {
if ( entry.getKey().isAssignableFrom( cls ) ) {
log.debugf( "Using cached JavaTypeDescriptor instance for Java class [%s]", cls.getName() );
return entry.getValue();
}
}
log.warnf( "Could not find matching type descriptor for requested Java class [%s]; using fallback", cls.getName() );
return new FallbackJavaTypeDescriptor<T>( cls );
}
public static class FallbackJavaTypeDescriptor<T> extends AbstractTypeDescriptor<T> {
@SuppressWarnings("unchecked")
protected FallbackJavaTypeDescriptor(Class<T> type) {
super( type, ImmutableMutabilityPlan.INSTANCE );
}
@Override
public String toString(T value) {
return value == null ? "<null>" : value.toString();
}
@Override
public T fromString(String string) {
throw new HibernateException(
"Not known how to convert String to given type [" + getJavaTypeClass().getName() + "]"
);
}
@Override
@SuppressWarnings("unchecked")
public <X> X unwrap(T value, Class<X> type, WrapperOptions options) {
return (X) value;
}
@Override
@SuppressWarnings("unchecked")
public <X> T wrap(X value, WrapperOptions options) {
return (T) value;
}
}
}