| /* |
| * Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation |
| // |
| package org.eclipse.persistence.jpa.jpql.tools; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.sql.Timestamp; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.Map; |
| import org.eclipse.persistence.jpa.jpql.tools.spi.IType; |
| import org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration; |
| import org.eclipse.persistence.jpa.jpql.tools.spi.ITypeRepository; |
| |
| /** |
| * This helper contains methods related to {@link IType} and can perform equivalency checks. |
| * |
| * @version 2.4 |
| * @since 2.3 |
| * @author Pascal Filion |
| */ |
| public final class TypeHelper { |
| |
| /** |
| * The {@link IType} for the <code>Object</code> class. |
| */ |
| private IType objectType; |
| |
| /** |
| * The {@link IType} for the <code>String</code> class. |
| */ |
| private IType stringType; |
| |
| /** |
| * The external form of the provider of {@link IType ITypes}. |
| */ |
| private final ITypeRepository typeRepository; |
| |
| /** |
| * The {@link IType} representing an unknown type. |
| */ |
| private IType unknownType; |
| |
| /** |
| * Creates a new <code>TypeHelper</code>. |
| * |
| * @param typeRepository The repository used to retrieve the types |
| */ |
| public TypeHelper(ITypeRepository typeRepository) { |
| super(); |
| this.typeRepository = typeRepository; |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link BigDecimal}. |
| * |
| * @return The external form of the <code>BigDecimal</code> class |
| */ |
| public IType bigDecimal() { |
| return getType(BigDecimal.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link BigInteger}. |
| * |
| * @return The external form of the <code>BigInteger</code> class |
| */ |
| public IType bigInteger() { |
| return getType(BigInteger.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Boolean}. |
| * |
| * @return The external form of the <code>Boolean</code> class |
| */ |
| public IType booleanType() { |
| return getType(Boolean.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Byte}. |
| * |
| * @return The external form of the <code>Byte</code> class |
| */ |
| public IType byteType() { |
| return getType(Byte.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Character}. |
| * |
| * @return The external form of the <code>Character</code> class |
| */ |
| public IType characterType() { |
| return getType(Character.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Collection}. |
| * |
| * @return The external form of the <code>Collection</code> class |
| */ |
| public IType collectionType() { |
| return getType(Collection.class); |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's representing a primitive type, into the class of the |
| * same type. |
| * |
| * @param type Type to possibly convert from the primitive into the class |
| * @return The given {@link IType} if it's not a primitive type otherwise the primitive type will |
| * have been converted into the class of that primitive |
| */ |
| public IType convertPrimitive(IType type) { |
| |
| // byte |
| IType newType = toByteType(type); |
| if (newType != type) { |
| return newType; |
| } |
| |
| // short |
| newType = toShortType(type); |
| if (newType != type) { |
| return newType; |
| } |
| |
| // int |
| newType = toIntegerType(type); |
| if (newType != type) { |
| return newType; |
| } |
| |
| // long |
| newType = longType(type); |
| if (newType != type) { |
| return newType; |
| } |
| |
| // float |
| newType = toFloatType(type); |
| if (newType != type) { |
| return newType; |
| } |
| |
| // double |
| newType = toDoubleType(type); |
| if (newType != type) { |
| return newType; |
| } |
| |
| // boolean |
| newType = toBooleanType(type); |
| if (newType != type) { |
| return newType; |
| } |
| |
| return type; |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Date}. |
| * |
| * @return The external form of the <code>Date</code> class |
| */ |
| public IType dateType() { |
| return getType(Date.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Double}. |
| * |
| * @return The external form of the <code>Double</code> class |
| */ |
| public IType doubleType() { |
| return getType(Double.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Enum}. |
| * |
| * @return The external form of the <code>Enum</code> class |
| */ |
| public IType enumType() { |
| return getType(Enum.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Float}. |
| * |
| * @return The external form of the <code>Float</code> class |
| */ |
| public IType floatType() { |
| return getType(Float.class); |
| } |
| |
| /** |
| * Returns the {@link IType} of the given Java type. |
| * |
| * @param type The Java type for which its external form will be returned |
| * @return The {@link IType} representing the given Java type |
| */ |
| public IType getType(Class<?> type) { |
| return typeRepository.getType(type); |
| } |
| |
| /** |
| * Retrieves the external class for the given fully qualified class name. |
| * |
| * @param typeName The fully qualified class name of the class to retrieve |
| * @return The external form of the class to retrieve |
| */ |
| public IType getType(String typeName) { |
| return typeRepository.getType(typeName); |
| } |
| |
| /** |
| * Returns the {@link ITypeRepository} used by this helper |
| * |
| * @return The external form of the provider of {@link IType ITypes}. |
| */ |
| public ITypeRepository getTypeRepository() { |
| return typeRepository; |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Integer}. |
| * |
| * @return The external form of the <code>Integer</code> class |
| */ |
| public IType integerType() { |
| return getType(Integer.class); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is a {@link Boolean}. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is a {@link Boolean}; <code>false</code> |
| * otherwise |
| */ |
| public boolean isBooleanType(IType type) { |
| return type.equals(booleanType()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is an instance of {@link Collection}. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is an instance of {@link Collection}; |
| * <code>false</code> otherwise |
| */ |
| public boolean isCollectionType(IType type) { |
| return type.isAssignableTo(collectionType()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is a {@link Date}, {@link Timestamp} or |
| * {@link Calendar}. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is a {@link Date}, {@link Timestamp} or |
| * {@link Calendar} |
| */ |
| public boolean isDateType(IType type) { |
| return type.equals(dateType()) || |
| type.equals(timestampType()) || |
| type.equals(getType(Calendar.class)); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is an instance of {@link Enum}. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is an instance of {@link Enum}; |
| * <code>false</code> otherwise |
| */ |
| public boolean isEnumType(IType type) { |
| return type.isAssignableTo(enumType()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is an instance of a floating type, which is either |
| * <code>Float</code>, <code>Double</code>, float or double. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is a floating type; <code>false</code> |
| * otherwise |
| */ |
| public boolean isFloatingType(IType type) { |
| return type.equals(floatType()) || |
| type.equals(doubleType()) || |
| type.equals(primitiveFloat()) || |
| type.equals(primitiveDouble()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is an instance of a floating type, which is either |
| * <code>Integer</code>, <code>Long</code>, int or float. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is a integral type; <code>false</code> |
| * otherwise |
| */ |
| public boolean isIntegralType(IType type) { |
| return type.equals(integerType()) || |
| type.equals(longType()) || |
| type.equals(shortType()) || |
| type.equals(characterType()) || |
| type.equals(primitiveInteger()) || |
| type.equals(primitiveLong()) || |
| type.equals(primitiveShort()) || |
| type.equals(primitiveChar()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is an instance of {@link Map}. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is an instance of {@link Map}; |
| * <code>false</code> otherwise |
| */ |
| public boolean isMapType(IType type) { |
| return type.isAssignableTo(mapType()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is an instance of {@link Number}. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is an instance of {@link Number}; |
| * <code>false</code> otherwise |
| */ |
| public boolean isNumericType(IType type) { |
| return type.isAssignableTo(numberType()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} is the external form of {@link Object}. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} is the external form of {@link Object} |
| */ |
| public boolean isObjectType(IType type) { |
| return type.equals(objectType()); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} represents a primitive type. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} represents a primitive; <code>false</code> |
| * otherwise |
| */ |
| public boolean isPrimitiveType(IType type) { |
| return type == primitiveBoolean() || |
| type == primitiveByte() || |
| type == primitiveDouble() || |
| type == primitiveFloat() || |
| type == primitiveInteger() || |
| type == primitiveLong() || |
| type == primitiveShort(); |
| } |
| |
| /** |
| * Determines whether the given {@link IType} represents the <code>String</code> class. |
| * |
| * @param type The type to check it's assignability |
| * @return <code>true</code> if the given {@link IType} represents the <code>String</code> class; |
| * <code>false</code> otherwise |
| */ |
| public boolean isStringType(IType type) { |
| return type.equals(stringType()); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Long}. |
| * |
| * @return The external form of the <code>Long</code> class |
| */ |
| public IType longType() { |
| return getType(Long.class); |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's the primitive long, into the <code>Long</code> type. |
| * |
| * @param type The {@link IType} to possibly convert |
| * @return The given type if it's not the primitive long or the {@link IType} for the class |
| * <code>Long</code> |
| */ |
| public IType longType(IType type) { |
| if (type.equals(primitiveLong())) { |
| return longType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Map}. |
| * |
| * @return The external form of the <code>Map</code> class |
| */ |
| public IType mapType() { |
| return getType(Map.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Number}. |
| * |
| * @return The external form of the <code>Number</code> class |
| */ |
| public IType numberType() { |
| return getType(Number.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Object}. |
| * |
| * @return The external form of the <code>Object</code> class |
| */ |
| public IType objectType() { |
| if (objectType == null) { |
| objectType = getType(Object.class); |
| } |
| return objectType; |
| } |
| |
| /** |
| * Returns the {@link ITypeDeclaration} for the {@link IType} representing the <code>Object</code> |
| * class. |
| * |
| * @return The {@link ITypeDeclaration} of the <code>Object</code> class |
| */ |
| public ITypeDeclaration objectTypeDeclaration() { |
| return objectType().getTypeDeclaration(); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive boolean. |
| * |
| * @return The external form of the primitive boolean |
| */ |
| public IType primitiveBoolean() { |
| return getType(Boolean.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive byte. |
| * |
| * @return The external form of the primitive byte |
| */ |
| public IType primitiveByte() { |
| return getType(Byte.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive char. |
| * |
| * @return The external form of the primitive char |
| */ |
| public IType primitiveChar() { |
| return getType(Character.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive double. |
| * |
| * @return The external form of the primitive double |
| */ |
| public IType primitiveDouble() { |
| return getType(Double.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive float. |
| * |
| * @return The external form of the primitive float |
| */ |
| public IType primitiveFloat() { |
| return getType(Float.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive int. |
| * |
| * @return The external form of the primitive int |
| */ |
| public IType primitiveInteger() { |
| return getType(Integer.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive long. |
| * |
| * @return The external form of the primitive long |
| */ |
| public IType primitiveLong() { |
| return getType(Long.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for the primitive short. |
| * |
| * @return The external form of the primitive short |
| */ |
| public IType primitiveShort() { |
| return getType(Short.TYPE); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Short}. |
| * |
| * @return The external form of the <code>Short</code> class |
| */ |
| public IType shortType() { |
| return getType(Short.class); |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link String}. |
| * |
| * @return The external form of the <code>String</code> class |
| */ |
| public IType stringType() { |
| if (stringType == null) { |
| stringType = getType(String.class); |
| } |
| return stringType; |
| } |
| |
| /** |
| * Retrieves the {@link IType} for {@link Timestamp}. |
| * |
| * @return The external form of the <code>Timestamp</code> class |
| */ |
| public IType timestampType() { |
| return getType(Timestamp.class); |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's the primitive boolean, into the <code>Boolean</code> |
| * type. |
| * |
| * @param type The {@link IType} to possibly convert |
| * @return The given type if it's not the primitive boolean or the {@link IType} for the class |
| * <code>Boolean</code> |
| */ |
| public IType toBooleanType(IType type) { |
| if (type.equals(primitiveBoolean())) { |
| return booleanType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's the primitive byte, into the <code>Byte</code> |
| * type. |
| * |
| * @param type The {@link IType} to possibly convert |
| * @return The given type if it's not the primitive byte or the {@link IType} for the class |
| * <code>Byte</code> |
| */ |
| public IType toByteType(IType type) { |
| if (type.equals(primitiveByte())) { |
| return byteType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's the primitive double, into the <code>Double</code> |
| * type. |
| * |
| * @param type The {@link IType} to possibly convert |
| * @return The given type if it's not the primitive double or the {@link IType} for the class |
| * <code>Double</code> |
| */ |
| public IType toDoubleType(IType type) { |
| if (type.equals(primitiveDouble())) { |
| return doubleType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's the primitive float, into the <code>Float</code> |
| * type. |
| * |
| * @param type The {@link IType} to possibly convert |
| * @return The given type if it's not the primitive float or the {@link IType} for the class |
| * <code>Float</code> |
| */ |
| public IType toFloatType(IType type) { |
| if (type.equals(primitiveFloat())) { |
| return floatType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's the primitive int, into the <code>Integer</code> |
| * type. |
| * |
| * @param type The {@link IType} to possibly convert |
| * @return The given type if it's not the primitive int or the {@link IType} for the class |
| * <code>Integer</code> |
| */ |
| public IType toIntegerType(IType type) { |
| if (type.equals(primitiveInteger())) { |
| return integerType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Converts the given {@link IType}, if it's the primitive short, into the <code>Short</code> |
| * type. |
| * |
| * @param type The {@link IType} to possibly convert |
| * @return The given type if it's not the primitive short or the {@link IType} for the class |
| * <code>Short</code> |
| */ |
| public IType toShortType(IType type) { |
| if (type.equals(primitiveShort())) { |
| return shortType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Retrieves the {@link IType} that represents an unknown type. |
| * |
| * @return The external form of an unknown type |
| */ |
| public IType unknownType() { |
| if (unknownType == null) { |
| unknownType = getType(IType.UNRESOLVABLE_TYPE); |
| } |
| return unknownType; |
| } |
| |
| /** |
| * Returns the {@link ITypeDeclaration} for the {@link IType} representing an unknown type. |
| * |
| * @return The {@link ITypeDeclaration} of the unknown type |
| */ |
| public ITypeDeclaration unknownTypeDeclaration() { |
| return unknownType().getTypeDeclaration(); |
| } |
| } |