/******************************************************************************* | |
* Copyright (c) 2006, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* 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(); | |
} | |
} |