org.hibernate.jpa.spi.CriteriaQueryTupleTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
Hibernate's core ORM functionality
/*
* 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.List;
import javax.persistence.Tuple;
import javax.persistence.TupleElement;
import org.hibernate.query.criteria.internal.ValueHandlerFactory;
import org.hibernate.transform.BasicTransformerAdapter;
/**
* ResultTransformer adapter for handling Tuple results from Criteria queries
*
* @author Steve Ebersole
*/
public class CriteriaQueryTupleTransformer extends BasicTransformerAdapter {
private final List valueHandlers;
private final List tupleElements;
public CriteriaQueryTupleTransformer(List valueHandlers, List tupleElements) {
// todo : should these 2 sizes match *always*?
this.valueHandlers = valueHandlers;
this.tupleElements = tupleElements;
}
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
final Object[] valueHandlerResult;
if ( valueHandlers == null ) {
valueHandlerResult = tuple;
}
else {
valueHandlerResult = new Object[tuple.length];
for ( int i = 0; i < tuple.length; i++ ) {
ValueHandlerFactory.ValueHandler valueHandler = valueHandlers.get( i );
valueHandlerResult[i] = valueHandler == null
? tuple[i]
: valueHandler.convert( tuple[i] );
}
}
return tupleElements == null
? valueHandlerResult.length == 1 ? valueHandlerResult[0] : valueHandlerResult
: new TupleImpl( tuple );
}
private class TupleImpl implements Tuple {
private final Object[] tuples;
private TupleImpl(Object[] tuples) {
if ( tuples.length != tupleElements.size() ) {
throw new IllegalArgumentException(
"Size mismatch between tuple result [" + tuples.length
+ "] and expected tuple elements [" + tupleElements.size() + "]"
);
}
this.tuples = tuples;
}
public X get(TupleElement tupleElement) {
int index = tupleElements.indexOf( tupleElement );
if ( index < 0 ) {
throw new IllegalArgumentException(
"Requested tuple element did not correspond to element in the result tuple"
);
}
// index should be "in range" by nature of size check in ctor
return (X) tuples[index];
}
public Object get(String alias) {
int index = -1;
if ( alias != null ) {
alias = alias.trim();
if ( alias.length() > 0 ) {
int i = 0;
for ( TupleElement selection : (List) tupleElements ) {
if ( alias.equals( selection.getAlias() ) ) {
index = i;
break;
}
i++;
}
}
}
if ( index < 0 ) {
throw new IllegalArgumentException(
"Given alias [" + alias + "] did not correspond to an element in the result tuple"
);
}
// index should be "in range" by nature of size check in ctor
return tuples[index];
}
public X get(String alias, Class type) {
final Object untyped = get( alias );
if ( untyped != null ) {
if ( !type.isInstance( untyped ) ) {
throw new IllegalArgumentException(
String.format(
"Requested tuple value [alias=%s, value=%s] cannot be assigned to requested type [%s]",
alias,
untyped,
type.getName()
)
);
}
}
return (X) untyped;
}
public Object get(int i) {
if ( i >= tuples.length ) {
throw new IllegalArgumentException(
"Given index [" + i + "] was outside the range of result tuple size [" + tuples.length + "] "
);
}
return tuples[i];
}
public X get(int i, Class type) {
final Object result = get( i );
if ( result != null && !type.isInstance( result ) ) {
throw new IllegalArgumentException(
String.format(
"Requested tuple value [index=%s, realType=%s] cannot be assigned to requested type [%s]",
i,
result.getClass().getName(),
type.getName()
)
);
}
return (X) result;
}
public Object[] toArray() {
// todo : make a copy?
return tuples;
}
public List> getElements() {
return tupleElements;
}
}
}