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

org.hibernate.jpa.spi.NativeQueryTupleTransformer 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.jpa.spi;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.Tuple;
import javax.persistence.TupleElement;

import org.hibernate.HibernateException;
import org.hibernate.transform.BasicTransformerAdapter;

/**
 * ResultTransformer adapter for handling Tuple results from Native queries
 *
 * @author Arnold Galovics
 */
public class NativeQueryTupleTransformer extends BasicTransformerAdapter {

	@Override
	public Object transformTuple(Object[] tuple, String[] aliases) {
		return new NativeTupleImpl( tuple, aliases );
	}

	private static class NativeTupleElementImpl implements TupleElement {

		private final Class javaType;

		private final String alias;

		public NativeTupleElementImpl(Class javaType, String alias) {
			this.javaType = javaType;
			this.alias = alias;
		}

		@Override
		public Class getJavaType() {
			return javaType;
		}

		@Override
		public String getAlias() {
			return alias;
		}
	}

	private static class NativeTupleImpl implements Tuple {

		private Object[] tuple;

		private Map aliasToValue = new LinkedHashMap<>();
		private Map aliasReferences = new LinkedHashMap<>();

		public NativeTupleImpl(Object[] tuple, String[] aliases) {
			if ( tuple == null ) {
				throw new HibernateException( "Tuple must not be null" );
			}
			if ( aliases == null ) {
				throw new HibernateException( "Aliases must not be null" );
			}
			if ( tuple.length != aliases.length ) {
				throw new HibernateException( "Got different size of tuples and aliases" );
			}
			this.tuple = tuple;
			for ( int i = 0; i < tuple.length; i++ ) {
				aliasToValue.put( aliases[i], tuple[i] );
				aliasReferences.put( aliases[i].toLowerCase(), aliases[i] );
			}
		}

		@Override
		public  X get(String alias, Class type) {
			final Object untyped = get( alias );

			return ( untyped != null ) ? type.cast( untyped ) : null;
		}

		@Override
		public Object get(String alias) {
			final String aliasReference = aliasReferences.get( alias.toLowerCase() );
			if ( aliasReference != null && aliasToValue.containsKey( aliasReference ) ) {
				return aliasToValue.get( aliasReference );
			}
			throw new IllegalArgumentException( "Unknown alias [" + alias + "]" );
		}

		@Override
		public  X get(int i, Class type) {
			final Object untyped = get( i );

			return ( untyped != null ) ? type.cast( untyped ) : null;
		}

		@Override
		public Object get(int i) {
			if ( i < 0 ) {
				throw new IllegalArgumentException( "requested tuple index must be greater than zero" );
			}
			if ( i >= aliasToValue.size() ) {
				throw new IllegalArgumentException( "requested tuple index exceeds actual tuple size" );
			}
			return tuple[i];
		}

		@Override
		public Object[] toArray() {
			// todo : make a copy?
			return tuple;
		}

		@Override
		public List> getElements() {
			List> elements = new ArrayList<>( aliasToValue.size() );

			for ( Map.Entry entry : aliasToValue.entrySet() ) {
				elements.add( new NativeTupleElementImpl<>( getValueClass( entry.getValue() ), entry.getKey() ) );
			}
			return elements;
		}

		private Class getValueClass(Object value) {
			Class valueClass = Object.class;
			if ( value != null ) {
				valueClass = value.getClass();
			}
			return valueClass;
		}

		@Override
		public  X get(TupleElement tupleElement) {
			return get( tupleElement.getAlias(), tupleElement.getJavaType() );
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy