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

org.hibernate.query.sqm.tree.expression.SqmEnumLiteral Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta1
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 http://www.gnu.org/licenses/lgpl-2.1.html
 */
package org.hibernate.query.sqm.tree.expression;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import javax.persistence.criteria.Expression;

import org.hibernate.query.SemanticException;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;

/**
 * Specialized SQM literal defined by an enum reference.  E.g.
 * {@code ".. where p.sex = Sex.MALE"}
 *
 * @author Steve Ebersole
 */
public class SqmEnumLiteral implements SqmExpression, SqmExpressable, SemanticPathPart {
	private final Enum enumValue;
	private final EnumJavaTypeDescriptor referencedEnumTypeDescriptor;
	private final String enumValueName;
	private final NodeBuilder nodeBuilder;

	private SqmExpressable expressable;

	public SqmEnumLiteral(
			Enum enumValue,
			EnumJavaTypeDescriptor referencedEnumTypeDescriptor,
			String enumValueName,
			NodeBuilder nodeBuilder) {
		this.enumValue = enumValue;
		this.referencedEnumTypeDescriptor = referencedEnumTypeDescriptor;
		this.enumValueName = enumValueName;
		this.nodeBuilder = nodeBuilder;

		this.expressable = this;
	}

	public Enum getEnumValue() {
		return enumValue;
	}

	public String getEnumValueName() {
		return enumValueName;
	}

	@Override
	public EnumJavaTypeDescriptor getExpressableJavaTypeDescriptor() {
		return referencedEnumTypeDescriptor;
	}


	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// SemanticPathPart

	@Override
	public SemanticPathPart resolvePathPart(
			String name,
			boolean isTerminal,
			SqmCreationState creationState) {
		throw new SemanticException(
				String.format(
						Locale.ROOT,
						"Static enum reference [%s#%s] cannot be de-referenced",
						referencedEnumTypeDescriptor.getJavaType().getName(),
						enumValueName
				)
		);
	}

	@Override
	public SqmPath resolveIndexedAccess(
			SqmExpression selector,
			boolean isTerminal,
			SqmCreationState creationState) {
		throw new SemanticException(
				String.format(
						Locale.ROOT,
						"Static enum reference [%s#%s] cannot be de-referenced",
						referencedEnumTypeDescriptor.getJavaType().getName(),
						enumValueName
				)
		);
	}

	@Override
	public SqmExpressable getNodeType() {
		return expressable;
	}

	@Override
	public void applyInferableType(SqmExpressable type) {
		//noinspection unchecked
//		this.expressable = (SqmExpressable) type;
	}

	@Override
	public SqmExpression asLong() {
		return nodeBuilder().literal( getExpressableJavaTypeDescriptor().toOrdinal( enumValue ).longValue() );
	}

	@Override
	public SqmExpression asInteger() {
		return nodeBuilder().literal( getExpressableJavaTypeDescriptor().toOrdinal( enumValue ) );
	}

	@Override
	public SqmExpression asFloat() {
		return nodeBuilder().literal( getExpressableJavaTypeDescriptor().toOrdinal( enumValue ).floatValue() );
	}

	@Override
	public SqmExpression asDouble() {
		return nodeBuilder().literal( getExpressableJavaTypeDescriptor().toOrdinal( enumValue ).doubleValue() );
	}

	@Override
	public SqmExpression asBigDecimal() {
		throw new UnsupportedOperationException( "Enum literal cannot be cast to BigDecimal" );
	}

	@Override
	public SqmExpression asBigInteger() {
		throw new UnsupportedOperationException( "Enum literal cannot be cast to BigInteger" );
	}

	@Override
	public SqmExpression asString() {
		return nodeBuilder().literal( getExpressableJavaTypeDescriptor().toName( enumValue ) );
	}

	@Override
	public  SqmExpression as(Class type) {
		return nodeBuilder().cast( this, type );
	}

	@Override
	public SqmPredicate isNull() {
		return nodeBuilder().isNull( this );
	}

	@Override
	public SqmPredicate isNotNull() {
		return nodeBuilder().isNotNull( this );
	}

	@Override
	public SqmPredicate in(Object... values) {
		return nodeBuilder().in( this, values );
	}

	@Override
	public SqmPredicate in(Expression... values) {
		return nodeBuilder().in( this, values );
	}

	@Override
	public SqmPredicate in(Collection values) {
		return nodeBuilder().in( this, values );
	}

	@Override
	public SqmPredicate in(Expression> values) {
		return nodeBuilder().in( this, values );
	}

	@Override
	public  X accept(SemanticQueryWalker walker) {
		return walker.visitEnumLiteral( this );
	}

	@Override
	public JavaTypeDescriptor getJavaTypeDescriptor() {
		return getExpressableJavaTypeDescriptor();
	}

	@Override
	public NodeBuilder nodeBuilder() {
		return nodeBuilder;
	}

	@Override
	public List> getSelectionItems() {
		// per-JPA
		throw new IllegalStateException( "Not a compound selection" );
	}

	@Override
	public boolean isCompoundSelection() {
		return false;
	}

	@Override
	public JpaSelection alias(String name) {
		return null;
	}

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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy