All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.boot.internal.AttributeConverterManager Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha1
Show newest version
/*
 * 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 .
 */
package org.hibernate.boot.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.AssertionFailure;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.boot.spi.AttributeConverterAutoApplyHandler;
import org.hibernate.boot.spi.AttributeConverterDescriptor;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.util.StringHelper;

import org.jboss.logging.Logger;

/**
 * @author Steve Ebersole
 */
public class AttributeConverterManager implements AttributeConverterAutoApplyHandler {
	private static final Logger log = Logger.getLogger( AttributeConverterManager.class );

	private Map attributeConverterDescriptorsByClass;

	void addConverter(AttributeConverterDescriptor descriptor) {
		if ( attributeConverterDescriptorsByClass == null ) {
			attributeConverterDescriptorsByClass = new ConcurrentHashMap();
		}

		final Object old = attributeConverterDescriptorsByClass.put(
				descriptor.getAttributeConverter().getClass(),
				descriptor
		);

		if ( old != null ) {
			throw new AssertionFailure(
					String.format(
							Locale.ENGLISH,
							"AttributeConverter class [%s] registered multiple times",
							descriptor.getAttributeConverter().getClass()
					)
			);
		}
	}

	private Collection converterDescriptors() {
		if ( attributeConverterDescriptorsByClass == null ) {
			return Collections.emptyList();
		}
		return attributeConverterDescriptorsByClass.values();
	}

	@Override
	public AttributeConverterDescriptor findAutoApplyConverterForAttribute(
			XProperty xProperty,
			MetadataBuildingContext context) {
		List matched = new ArrayList();

		for ( AttributeConverterDescriptor descriptor : converterDescriptors() ) {
			log.debugf(
					"Checking auto-apply AttributeConverter [%s] (type=%s) for match against attribute : %s.%s (type=%s)",
					descriptor.toString(),
					descriptor.getDomainType().getSimpleName(),
					xProperty.getDeclaringClass().getName(),
					xProperty.getName(),
					xProperty.getType().getName()
			);

			if ( descriptor.shouldAutoApplyToAttribute( xProperty, context ) ) {
				matched.add( descriptor );
			}
		}

		if ( matched.isEmpty() ) {
			return null;
		}

		if ( matched.size() == 1 ) {
			return matched.get( 0 );
		}

		// otherwise, we had multiple matches
		throw new RuntimeException(
				String.format(
						Locale.ROOT,
						"Multiple auto-apply converters matched attribute [%s.%s] : %s",
						xProperty.getDeclaringClass().getName(),
						xProperty.getName(),
						StringHelper.join( matched, RENDERER )
				)
		);
	}

	@Override
	public AttributeConverterDescriptor findAutoApplyConverterForCollectionElement(
			XProperty xProperty,
			MetadataBuildingContext context) {
		List matched = new ArrayList();

		for ( AttributeConverterDescriptor descriptor : converterDescriptors() ) {
			log.debugf(
					"Checking auto-apply AttributeConverter [%s] (type=%s) for match against collection attribute's element : %s.%s (type=%s)",
					descriptor.toString(),
					descriptor.getDomainType().getSimpleName(),
					xProperty.getDeclaringClass().getName(),
					xProperty.getName(),
					xProperty.getElementClass().getName()
			);
			if ( descriptor.shouldAutoApplyToCollectionElement( xProperty, context ) ) {
				matched.add( descriptor );
			}
		}

		if ( matched.isEmpty() ) {
			return null;
		}

		if ( matched.size() == 1 ) {
			return matched.get( 0 );
		}

		// otherwise, we had multiple matches
		throw new RuntimeException(
				String.format(
						Locale.ROOT,
						"Multiple auto-apply converters matched attribute [%s.%s] : %s",
						xProperty.getDeclaringClass().getName(),
						xProperty.getName(),
						StringHelper.join( matched, RENDERER )
				)
		);
	}

	@Override
	public AttributeConverterDescriptor findAutoApplyConverterForMapKey(
			XProperty xProperty,
			MetadataBuildingContext context) {
		List matched = new ArrayList();

		for ( AttributeConverterDescriptor descriptor : converterDescriptors() ) {
			log.debugf(
					"Checking auto-apply AttributeConverter [%s] (type=%s) for match against map attribute's key : %s.%s (type=%s)",
					descriptor.toString(),
					descriptor.getDomainType().getSimpleName(),
					xProperty.getDeclaringClass().getName(),
					xProperty.getName(),
					xProperty.getMapKey().getName()
			);
			if ( descriptor.shouldAutoApplyToMapKey( xProperty, context ) ) {
				matched.add( descriptor );
			}
		}

		if ( matched.isEmpty() ) {
			return null;
		}

		if ( matched.size() == 1 ) {
			return matched.get( 0 );
		}

		// otherwise, we had multiple matches
		throw new RuntimeException(
				String.format(
						Locale.ROOT,
						"Multiple auto-apply converters matched attribute [%s.%s] : %s",
						xProperty.getDeclaringClass().getName(),
						xProperty.getName(),
						StringHelper.join( matched, RENDERER )
				)
		);
	}

	private static StringHelper.Renderer RENDERER = new StringHelper.Renderer() {
		@Override
		public String render(AttributeConverterDescriptor value) {
			return value.getAttributeConverter().getClass().getName();
		}
	};

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy