/* * 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.sqm.test.domain; import java.math.BigDecimal; import java.math.BigInteger; import org.hibernate.query.sqm.domain.SqmDomainMetamodel; import org.hibernate.query.sqm.domain.SqmExpressableTypeBasic; /** * Helper for making the determination of an expression's "type" as sovered by the rules * defined in section 6.5.7.1 (Result Types of Expressions) of the JPA 2.1 spec * * @author Steve Ebersole */ public class ExpressionTypeHelper { private ExpressionTypeHelper() { } /** * Determine the result type of an arithmetic operation as defined by the * rules in section 6.5.7.1. * * @return The operation result type */ public static SqmExpressableTypeBasic resolveArithmeticType( SqmExpressableTypeBasic firstType, SqmExpressableTypeBasic secondType, boolean isDivision, SqmDomainMetamodel domainMetamodel) { if ( isDivision ) { // covered under the note in 6.5.7.1 discussing the unportable // "semantics of the SQL division operation".. return domainMetamodel.resolveBasicType( Number.class ); } else if ( matchesJavaType( firstType, Double.class ) ) { return firstType; } else if ( matchesJavaType( secondType, Double.class ) ) { return secondType; } else if ( matchesJavaType( firstType, Float.class ) ) { return firstType; } else if ( matchesJavaType( secondType, Float.class ) ) { return secondType; } else if ( matchesJavaType( firstType, BigDecimal.class ) ) { return firstType; } else if ( matchesJavaType( secondType, BigDecimal.class ) ) { return secondType; } else if ( matchesJavaType( firstType, BigInteger.class ) ) { return firstType; } else if ( matchesJavaType( secondType, BigInteger.class ) ) { return secondType; } else if ( matchesJavaType( firstType, Long.class ) ) { return firstType; } else if ( matchesJavaType( secondType, Long.class ) ) { return secondType; } else if ( matchesJavaType( firstType, Integer.class ) ) { return firstType; } else if ( matchesJavaType( secondType, Integer.class ) ) { return secondType; } else if ( matchesJavaType( firstType, Short.class ) ) { return domainMetamodel.resolveBasicType( Integer.class ); } else if ( matchesJavaType( secondType, Short.class ) ) { return domainMetamodel.resolveBasicType( Integer.class ); } else { return domainMetamodel.resolveBasicType( Number.class ); } } @SuppressWarnings("unchecked") private static boolean matchesJavaType(SqmExpressableTypeBasic type, Class javaType) { return type != null && javaType.isAssignableFrom( type.getExportedDomainType().getJavaType() ); } public static SqmExpressableTypeBasic resolveSingleNumericType( SqmExpressableTypeBasic typeDescriptor, SqmDomainMetamodel domainMetamodel) { if ( matchesJavaType( typeDescriptor, Double.class ) ) { return typeDescriptor; } else if ( matchesJavaType( typeDescriptor, Float.class ) ) { return typeDescriptor; } else if ( matchesJavaType( typeDescriptor, BigDecimal.class ) ) { return typeDescriptor; } else if ( matchesJavaType( typeDescriptor, BigInteger.class ) ) { return typeDescriptor; } else if ( matchesJavaType( typeDescriptor, Long.class ) ) { return typeDescriptor; } else if ( matchesJavaType( typeDescriptor, Integer.class ) ) { return typeDescriptor; } else if ( matchesJavaType( typeDescriptor, Short.class ) ) { return domainMetamodel.resolveBasicType( Integer.class ); } else { return domainMetamodel.resolveBasicType( Number.class ); } } }