/*
* Copyright 2008-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;
import org.springframework.lang.Nullable;
Interface to access property types and resolving generics on the way. Starting with a ClassTypeInformation
you can traverse properties using getProperty(String)
to access type information. Author: Oliver Gierke, Mark Paluch
/**
* Interface to access property types and resolving generics on the way. Starting with a {@link ClassTypeInformation}
* you can traverse properties using {@link #getProperty(String)} to access type information.
*
* @author Oliver Gierke
* @author Mark Paluch
*/
public interface TypeInformation<S> {
Returns the TypeInformation
s for the parameters of the given Constructor
. Params: - constructor – must not be null.
Returns:
/**
* Returns the {@link TypeInformation}s for the parameters of the given {@link Constructor}.
*
* @param constructor must not be {@literal null}.
* @return
*/
List<TypeInformation<?>> getParameterTypes(Constructor<?> constructor);
Returns the property information for the property with the given name. Supports property traversal through dot
notation.
Params: - property –
Returns:
/**
* Returns the property information for the property with the given name. Supports property traversal through dot
* notation.
*
* @param property
* @return
*/
@Nullable
TypeInformation<?> getProperty(String property);
Returns the property information for the property with the given name or throw IllegalArgumentException
if the type information cannot be resolved. Supports property traversal through dot notation. Params: - property –
Throws: - IllegalArgumentException – if the type information cannot be resolved.
Returns: Since: 2.0
/**
* Returns the property information for the property with the given name or throw {@link IllegalArgumentException} if
* the type information cannot be resolved. Supports property traversal through dot notation.
*
* @param property
* @return
* @throws IllegalArgumentException if the type information cannot be resolved.
* @since 2.0
*/
default TypeInformation<?> getRequiredProperty(String property) {
TypeInformation<?> typeInformation = getProperty(property);
if (typeInformation != null) {
return typeInformation;
}
throw new IllegalArgumentException(
String.format("Could not find required property %s on %s!", property, getType()));
}
Returns whether the type can be considered a collection, which means it's a container of elements, e.g. a Collection
and Array
or anything implementing Iterable
. If this returns true you can expect getComponentType()
to return a non-null value. Returns:
/**
* Returns whether the type can be considered a collection, which means it's a container of elements, e.g. a
* {@link java.util.Collection} and {@link java.lang.reflect.Array} or anything implementing {@link Iterable}. If this
* returns {@literal true} you can expect {@link #getComponentType()} to return a non-{@literal null} value.
*
* @return
*/
boolean isCollectionLike();
Returns the component type for Collection
s or the key type for Map
s. Returns:
/**
* Returns the component type for {@link java.util.Collection}s or the key type for {@link java.util.Map}s.
*
* @return
*/
@Nullable
TypeInformation<?> getComponentType();
Returns the component type for Collection
s, the key type for Map
s or the single generic type if available. Throws IllegalStateException
if the component value type cannot be resolved. Throws: - IllegalStateException – if the component type cannot be resolved, e.g. if a raw type is used or the type is
not generic in the first place.
Returns: Since: 2.0
/**
* Returns the component type for {@link java.util.Collection}s, the key type for {@link java.util.Map}s or the single
* generic type if available. Throws {@link IllegalStateException} if the component value type cannot be resolved.
*
* @return
* @throws IllegalStateException if the component type cannot be resolved, e.g. if a raw type is used or the type is
* not generic in the first place.
* @since 2.0
*/
default TypeInformation<?> getRequiredComponentType() {
TypeInformation<?> componentType = getComponentType();
if (componentType != null) {
return componentType;
}
throw new IllegalStateException(String.format("Can't resolve required component type for %s!", getType()));
}
Returns whether the property is a Map
. If this returns true you can expect getComponentType()
as well as getMapValueType()
to return something not null. Returns:
/**
* Returns whether the property is a {@link java.util.Map}. If this returns {@literal true} you can expect
* {@link #getComponentType()} as well as {@link #getMapValueType()} to return something not {@literal null}.
*
* @return
*/
boolean isMap();
Will return the type of the value in case the underlying type is a Map
. Returns:
/**
* Will return the type of the value in case the underlying type is a {@link java.util.Map}.
*
* @return
*/
@Nullable
TypeInformation<?> getMapValueType();
Will return the type of the value in case the underlying type is a Map
or throw IllegalStateException
if the map value type cannot be resolved. Throws: - IllegalStateException – if the map value type cannot be resolved, usually due to the current
Map
type being a raw one.
Returns: Since: 2.0
/**
* Will return the type of the value in case the underlying type is a {@link java.util.Map} or throw
* {@link IllegalStateException} if the map value type cannot be resolved.
*
* @return
* @throws IllegalStateException if the map value type cannot be resolved, usually due to the current
* {@link java.util.Map} type being a raw one.
* @since 2.0
*/
default TypeInformation<?> getRequiredMapValueType() {
TypeInformation<?> mapValueType = getMapValueType();
if (mapValueType != null) {
return mapValueType;
}
throw new IllegalStateException(String.format("Can't resolve required map value type for %s!", getType()));
}
Returns the type of the property. Will resolve generics and the generic context of
Returns:
/**
* Returns the type of the property. Will resolve generics and the generic context of
*
* @return
*/
Class<S> getType();
Returns a ClassTypeInformation
to represent the TypeInformation
of the raw type of the current instance. Returns:
/**
* Returns a {@link ClassTypeInformation} to represent the {@link TypeInformation} of the raw type of the current
* instance.
*
* @return
*/
ClassTypeInformation<?> getRawTypeInformation();
Transparently returns the Map
value type if the type is a Map
, returns the component type if the type isCollectionLike()
or the simple type if none of this applies. Returns: the map value, collection component type or the current type, null it the current type is a raw Map
or Collection
.
/**
* Transparently returns the {@link java.util.Map} value type if the type is a {@link java.util.Map}, returns the
* component type if the type {@link #isCollectionLike()} or the simple type if none of this applies.
*
* @return the map value, collection component type or the current type, {@literal null} it the current type is a raw
* {@link java.util.Map} or {@link java.util.Collection}.
*/
@Nullable
TypeInformation<?> getActualType();
Transparently returns the Map
value type if the type is a Map
, returns the component type if the type isCollectionLike()
or the simple type if none of this applies. Throws: - IllegalArgumentException – if the current type is a raw
Map
or Collection
and no value or component type is available.
Returns: Since: 2.0
/**
* Transparently returns the {@link java.util.Map} value type if the type is a {@link java.util.Map}, returns the
* component type if the type {@link #isCollectionLike()} or the simple type if none of this applies.
*
* @return
* @throws IllegalArgumentException if the current type is a raw {@link java.util.Map} or {@link java.util.Collection}
* and no value or component type is available.
* @since 2.0
*/
default TypeInformation<?> getRequiredActualType() {
TypeInformation<?> result = getActualType();
if (result == null) {
throw new IllegalStateException(
"Expected to be able to resolve a type but got null! This usually stems from types implementing raw Map or Collection interfaces!");
}
return result;
}
Returns a TypeInformation
for the return type of the given Method
. Will potentially resolve generics information against the current types type parameter bindings. Params: - method – must not be null.
Returns:
/**
* Returns a {@link TypeInformation} for the return type of the given {@link Method}. Will potentially resolve
* generics information against the current types type parameter bindings.
*
* @param method must not be {@literal null}.
* @return
*/
TypeInformation<?> getReturnType(Method method);
Returns the TypeInformation
s for the parameters of the given Method
. Params: - method – must not be null.
Returns:
/**
* Returns the {@link TypeInformation}s for the parameters of the given {@link Method}.
*
* @param method must not be {@literal null}.
* @return
*/
List<TypeInformation<?>> getParameterTypes(Method method);
Returns the TypeInformation
for the given raw super type. Params: - superType – must not be null.
Returns: the TypeInformation
for the given raw super type or null in case the current TypeInformation
does not implement the given type.
/**
* Returns the {@link TypeInformation} for the given raw super type.
*
* @param superType must not be {@literal null}.
* @return the {@link TypeInformation} for the given raw super type or {@literal null} in case the current
* {@link TypeInformation} does not implement the given type.
*/
@Nullable
TypeInformation<?> getSuperTypeInformation(Class<?> superType);
Returns the TypeInformation
for the given raw super type. Params: - superType – must not be null.
Throws: - IllegalArgumentException – in case the current
TypeInformation
does not implement the given type.
Returns: the TypeInformation
for the given raw super type. Since: 2.0
/**
* Returns the {@link TypeInformation} for the given raw super type.
*
* @param superType must not be {@literal null}.
* @return the {@link TypeInformation} for the given raw super type.
* @throws IllegalArgumentException in case the current {@link TypeInformation} does not implement the given type.
* @since 2.0
*/
default TypeInformation<?> getRequiredSuperTypeInformation(Class<?> superType) {
TypeInformation<?> result = getSuperTypeInformation(superType);
if (result == null) {
throw new IllegalArgumentException(String.format(
"Can't retrieve super type information for %s! Does current type really implement the given one?",
superType));
}
return result;
}
Returns if the current TypeInformation
can be safely assigned to the given one. Mimics semantics of Class.isAssignableFrom(Class)
but takes generics into account. Thus it will allow to detect that a List<Long>
is assignable to List<? extends Number>
. Params: - target –
Returns:
/**
* Returns if the current {@link TypeInformation} can be safely assigned to the given one. Mimics semantics of
* {@link Class#isAssignableFrom(Class)} but takes generics into account. Thus it will allow to detect that a
* {@code List<Long>} is assignable to {@code List<? extends Number>}.
*
* @param target
* @return
*/
boolean isAssignableFrom(TypeInformation<?> target);
Returns the TypeInformation
for the type arguments of the current TypeInformation
. Returns:
/**
* Returns the {@link TypeInformation} for the type arguments of the current {@link TypeInformation}.
*
* @return
*/
List<TypeInformation<?>> getTypeArguments();
Specializes the given (raw) ClassTypeInformation
using the context of the current potentially parameterized type, basically turning the given raw type into a parameterized one. Will return the given type as is if no generics are involved. Params: - type – must not be null.
Returns: will never be null.
/**
* Specializes the given (raw) {@link ClassTypeInformation} using the context of the current potentially parameterized
* type, basically turning the given raw type into a parameterized one. Will return the given type as is if no
* generics are involved.
*
* @param type must not be {@literal null}.
* @return will never be {@literal null}.
*/
TypeInformation<? extends S> specialize(ClassTypeInformation<?> type);
Returns whether the current type is a sub type of the given one, i.e. whether it's assignable but not the same one.
Params: - type – must not be null.
Returns: Since: 2.2
/**
* Returns whether the current type is a sub type of the given one, i.e. whether it's assignable but not the same one.
*
* @param type must not be {@literal null}.
* @return
* @since 2.2
*/
default boolean isSubTypeOf(Class<?> type) {
return !type.equals(getType()) && type.isAssignableFrom(getType());
}
}