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

org.hibernate.query.internal.ParameterMetadataImpl 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.query.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

import javax.persistence.Parameter;

import org.hibernate.QueryException;
import org.hibernate.QueryParameterException;
import org.hibernate.engine.query.spi.NamedParameterDescriptor;
import org.hibernate.engine.query.spi.OrdinalParameterDescriptor;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.query.ParameterMetadata;
import org.hibernate.query.QueryParameter;
import org.hibernate.type.Type;

/**
 * Encapsulates metadata about parameters encountered within a query.
 *
 * @author Steve Ebersole
 */
public class ParameterMetadataImpl implements ParameterMetadata {
	private final Map ordinalDescriptorMap;
	private final Map namedDescriptorMap;

	public ParameterMetadataImpl(
			Map ordinalDescriptorMap,
			Map namedDescriptorMap) {
		this.ordinalDescriptorMap = ordinalDescriptorMap == null
				? Collections.emptyMap()
				: Collections.unmodifiableMap( ordinalDescriptorMap );
		this.namedDescriptorMap = namedDescriptorMap == null
				? Collections.emptyMap()
				: Collections.unmodifiableMap( namedDescriptorMap );

		if (ordinalDescriptorMap != null &&  ! ordinalDescriptorMap.isEmpty() ) {
			final List sortedPositions = new ArrayList<>( ordinalDescriptorMap.keySet() );
			sortedPositions.sort( ComparableComparator.INSTANCE );

			int lastPosition = -1;
			for ( Integer sortedPosition : sortedPositions ) {
				if ( lastPosition == -1 ) {
					lastPosition = sortedPosition;
					continue;
				}

				if ( sortedPosition != lastPosition + 1 ) {
					throw new QueryException(
							String.format(
									Locale.ROOT,
									"Unexpected gap in ordinal parameter labels [%s -> %s] : [%s]",
									lastPosition,
									sortedPosition,
									StringHelper.join( ",", sortedPositions.iterator() )
							)
					);
				}

				lastPosition = sortedPosition;
			}

		}
	}

	@Override
	public Collection getPositionalParameters() {
		return Collections.unmodifiableCollection( ordinalDescriptorMap.values() );
	}

	@Override
	public Collection getNamedParameters() {
		return Collections.unmodifiableCollection( namedDescriptorMap.values() );
	}


	@Override
	public int getParameterCount() {
		return ordinalDescriptorMap.size() + namedDescriptorMap.size();
	}

	@Override
	@SuppressWarnings("SuspiciousMethodCalls")
	public boolean containsReference(QueryParameter parameter) {
		return ordinalDescriptorMap.containsValue( parameter )
				|| namedDescriptorMap.containsValue( parameter );
	}

	@Override
	public boolean hasNamedParameters() {
		return !namedDescriptorMap.isEmpty();
	}

	@Override
	public boolean hasPositionalParameters() {
		return getOrdinalParameterCount() > 0;
	}

	@Override
	public int getPositionalParameterCount() {
		return getOrdinalParameterCount();
	}

	public int getOrdinalParameterCount() {
		return ordinalDescriptorMap.size();
	}

	@Override
	public Set getNamedParameterNames() {
		return  namedDescriptorMap.keySet();
	}

	public Set getOrdinalParameterLabels() {
		return ordinalDescriptorMap.keySet();
	}

	/**
	 * Get the descriptor for an ordinal parameter given its position
	 *
	 * @param position The position (0 based)
	 *
	 * @return The ordinal parameter descriptor
	 *
	 * @throws QueryParameterException If the position is out of range
	 */
	public OrdinalParameterDescriptor getOrdinalParameterDescriptor(int position) {
		final OrdinalParameterDescriptor descriptor = ordinalDescriptorMap.get( position );
		if ( descriptor == null ) {
			throw new IllegalArgumentException(
					String.format(
							Locale.ROOT,
							"Could not locate ordinal parameter [%s], expecting one of [%s]",
							position,
							StringHelper.join( ", ", ordinalDescriptorMap.keySet().iterator())
					)
			);
		}
		return descriptor;
	}

	/**
	 * Deprecated.
	 *
	 * @param position The position
	 *
	 * @return The type
	 *
	 * @deprecated Use {@link OrdinalParameterDescriptor#getExpectedType()} from the
	 * {@link #getOrdinalParameterDescriptor} return instead
	 */
	@Deprecated
	public Type getOrdinalParameterExpectedType(int position) {
		return getOrdinalParameterDescriptor( position ).getExpectedType();
	}

	/**
	 * Deprecated.
	 *
	 * @param position The position
	 *
	 * @return The source location
	 *
	 * @deprecated Use {@link OrdinalParameterDescriptor#getPosition()} from the
	 * {@link #getOrdinalParameterDescriptor} return instead
	 */
	@Deprecated
	public int getOrdinalParameterSourceLocation(int position) {
		return getOrdinalParameterDescriptor( position ).getPosition();
	}

	@Override
	public  QueryParameter getQueryParameter(String name) {
		//noinspection unchecked
		return getNamedParameterDescriptor( name );
	}

	@Override
	@SuppressWarnings("unchecked")
	public  QueryParameter getQueryParameter(Integer position) {
		return getOrdinalParameterDescriptor( position );
	}

	@Override
	public  QueryParameter resolve(Parameter param) {
		if ( param instanceof QueryParameter ) {
			return (QueryParameter) param;
		}

		throw new IllegalArgumentException( "Could not resolve javax.persistence.Parameter to org.hibernate.query.QueryParameter" );
	}

	/**
	 * Get the descriptor for a named parameter given the name
	 *
	 * @param name The name of the parameter to locate
	 *
	 * @return The named parameter descriptor
	 *
	 * @throws QueryParameterException If the name could not be resolved to a named parameter
	 */
	public NamedParameterDescriptor getNamedParameterDescriptor(String name) {
		final NamedParameterDescriptor descriptor = namedDescriptorMap.get( name );
		if ( descriptor == null ) {
			throw new IllegalArgumentException(
					String.format(
							Locale.ROOT,
							"Could not locate named parameter [%s], expecting one of [%s]",
							name,
							String.join( ", ", namedDescriptorMap.keySet() )
					)
			);
		}
		return descriptor;
	}

	@Override
	public void visitRegistrations(Consumer action) {
		if ( hasPositionalParameters() ) {
			for ( OrdinalParameterDescriptor descriptor : ordinalDescriptorMap.values() ) {
				action.accept( descriptor );
			}
		}
		else if ( hasNamedParameters() ) {
			for ( NamedParameterDescriptor descriptor : namedDescriptorMap.values() ) {
				action.accept( descriptor );
			}
		}
	}

	/**
	 * Deprecated.
	 *
	 * @param name The name of the parameter
	 *
	 * @return The type
	 *
	 * @deprecated Use {@link NamedParameterDescriptor#getExpectedType()} from the
	 * {@link #getNamedParameterDescriptor} return instead
	 */
	@Deprecated
	public Type getNamedParameterExpectedType(String name) {
		return getNamedParameterDescriptor( name ).getExpectedType();
	}

	/**
	 * Deprecated.
	 *
	 * @param name The name of the parameter
	 *
	 * @return The type
	 *
	 * @deprecated Use {@link NamedParameterDescriptor#getPosition()} from the
	 * {@link #getNamedParameterDescriptor} return instead
	 */
	@Deprecated
	public int[] getNamedParameterSourceLocations(String name) {
		return getNamedParameterDescriptor( name ).getSourceLocations();
	}

	@Override
	@SuppressWarnings("unchecked")
	public Set> collectAllParameters() {
		if ( hasNamedParameters() || hasPositionalParameters() ) {
			final HashSet allParameters = new HashSet();
			allParameters.addAll( namedDescriptorMap.values() );
			allParameters.addAll( ordinalDescriptorMap.values() );
			return allParameters;
		}

		return Collections.emptySet();
	}

	@Override
	@SuppressWarnings("unchecked")
	public Set> collectAllParametersJpa() {
		if ( hasNamedParameters() || hasPositionalParameters() ) {
			final HashSet allParameters = new HashSet();
			allParameters.addAll( namedDescriptorMap.values() );
			allParameters.addAll( ordinalDescriptorMap.values() );
			return allParameters;
		}

		return Collections.emptySet();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy