org.hibernate.type.BasicTypeRegistry.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.type.BasicTypeRegistry.java

Source

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.type;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.HibernateException;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.UserType;

/**
 * A registry of {@link BasicType} instances
 *
 * @author Steve Ebersole
 */
public class BasicTypeRegistry implements Serializable {
    private static final CoreMessageLogger LOG = CoreLogging.messageLogger(BasicTypeRegistry.class);

    // TODO : analyze these sizing params; unfortunately this seems to be the only way to give a "concurrencyLevel"
    private Map<String, BasicType> registry = new ConcurrentHashMap<>(100, .75f, 1);
    private boolean locked;
    private TypeConfiguration typeConfiguration;

    public BasicTypeRegistry(TypeConfiguration typeConfiguration) {
        this();
        this.typeConfiguration = typeConfiguration;
    }

    public BasicTypeRegistry() {
        register(BooleanType.INSTANCE);
        register(NumericBooleanType.INSTANCE);
        register(TrueFalseType.INSTANCE);
        register(YesNoType.INSTANCE);

        register(ByteType.INSTANCE);
        register(CharacterType.INSTANCE);
        register(ShortType.INSTANCE);
        register(IntegerType.INSTANCE);
        register(LongType.INSTANCE);
        register(FloatType.INSTANCE);
        register(DoubleType.INSTANCE);
        register(BigDecimalType.INSTANCE);
        register(BigIntegerType.INSTANCE);

        register(StringType.INSTANCE);
        register(StringNVarcharType.INSTANCE);
        register(CharacterNCharType.INSTANCE);
        register(UrlType.INSTANCE);

        register(DurationType.INSTANCE);
        register(InstantType.INSTANCE);
        register(LocalDateTimeType.INSTANCE);
        register(LocalDateType.INSTANCE);
        register(LocalTimeType.INSTANCE);
        register(OffsetDateTimeType.INSTANCE);
        register(OffsetTimeType.INSTANCE);
        register(ZonedDateTimeType.INSTANCE);

        register(DateType.INSTANCE);
        register(TimeType.INSTANCE);
        register(TimestampType.INSTANCE);
        register(DbTimestampType.INSTANCE);
        register(CalendarType.INSTANCE);
        register(CalendarDateType.INSTANCE);

        register(LocaleType.INSTANCE);
        register(CurrencyType.INSTANCE);
        register(TimeZoneType.INSTANCE);
        register(ClassType.INSTANCE);
        register(UUIDBinaryType.INSTANCE);
        register(UUIDCharType.INSTANCE);

        register(BinaryType.INSTANCE);
        register(WrapperBinaryType.INSTANCE);
        register(RowVersionType.INSTANCE);
        register(ImageType.INSTANCE);
        register(CharArrayType.INSTANCE);
        register(CharacterArrayType.INSTANCE);
        register(TextType.INSTANCE);
        register(NTextType.INSTANCE);
        register(BlobType.INSTANCE);
        register(MaterializedBlobType.INSTANCE);
        register(ClobType.INSTANCE);
        register(NClobType.INSTANCE);
        register(MaterializedClobType.INSTANCE);
        register(MaterializedNClobType.INSTANCE);
        register(SerializableType.INSTANCE);

        register(ObjectType.INSTANCE);

        //noinspection unchecked
        register(new AdaptedImmutableType(DateType.INSTANCE));
        //noinspection unchecked
        register(new AdaptedImmutableType(TimeType.INSTANCE));
        //noinspection unchecked
        register(new AdaptedImmutableType(TimestampType.INSTANCE));
        //noinspection unchecked
        register(new AdaptedImmutableType(DbTimestampType.INSTANCE));
        //noinspection unchecked
        register(new AdaptedImmutableType(CalendarType.INSTANCE));
        //noinspection unchecked
        register(new AdaptedImmutableType(CalendarDateType.INSTANCE));
        //noinspection unchecked
        register(new AdaptedImmutableType(BinaryType.INSTANCE));
        //noinspection unchecked
        register(new AdaptedImmutableType(SerializableType.INSTANCE));
    }

    /**
     * Constructor version used during shallow copy
     *
     * @param registeredTypes The type map to copy over
     */
    @SuppressWarnings({ "UnusedDeclaration" })
    private BasicTypeRegistry(Map<String, BasicType> registeredTypes) {
        registry.putAll(registeredTypes);
        locked = true;
    }

    public void register(BasicType type) {
        register(type, type.getRegistrationKeys());
    }

    public void register(BasicType type, String[] keys) {
        if (locked) {
            throw new HibernateException("Can not alter TypeRegistry at this time");
        }

        if (type == null) {
            throw new HibernateException("Type to register cannot be null");
        }

        if (keys == null || keys.length == 0) {
            LOG.typeDefinedNoRegistrationKeys(type);
            return;
        }

        for (String key : keys) {
            // be safe...
            if (key == null) {
                continue;
            }
            //Use String#intern here as there's high chances of duplicates combined with long term usage:
            //just running our testsuite would generate 210,000 instances for the String "java.lang.Class" alone.
            //Incidentally this might help with map lookup efficiency too.
            key = key.intern();
            LOG.debugf("Adding type registration %s -> %s", key, type);
            final Type old = registry.put(key, type);
            if (old != null && old != type) {
                LOG.typeRegistrationOverridesPrevious(key, old);
            }
        }
    }

    public void register(UserType type, String[] keys) {
        register(new CustomType(type, keys));
    }

    public void register(CompositeUserType type, String[] keys) {
        register(new CompositeCustomType(type, keys));
    }

    public void unregister(String... keys) {
        for (String key : keys) {
            registry.remove(key);
        }
    }

    public BasicType getRegisteredType(String key) {
        return registry.get(key);
    }

    public BasicTypeRegistry shallowCopy() {
        return new BasicTypeRegistry(this.registry);
    }
}