Class FallbackConverter<S,T>
- Type Parameters:
S
- the base type of source objects.T
- the base type of converted objects.
- All Implemented Interfaces:
Serializable
,Function<S,
,T> ObjectConverter<S,
T>
The primary converter is expected more generic than the fallback converter. We try the generic converter first because we expect that if the user wanted the specific subclass, he would have asked explicitly for it. Trying the generic converter first is both closer to what the user asked and less likely to throw many exceptions before we found a successful conversion.
All converters in a FallbackConverter
tree have the same source class <S>
,
and different target classes <? extends T>
not equal to <T>
.
The tree should never have two classes <T1>
and <T2>
such as one is assignable
from the other.
Instances are created by the merge(ObjectConverter, ObjectConverter)
method.
It is invoked when a new converter is registered for the same source and target class than an existing converter.
Immutability and thread safety
This class is immutable, and thus inherently thread-safe, if the converters given to the static factory method are also immutable.- Since:
- 0.3
- Version:
- 0.3
-
Field Summary
FieldsModifier and TypeFieldDescription(package private) final ObjectConverter<S,
? extends T> The fallback converter.(package private) final ObjectConverter<S,
? extends T> The primary converter, to be tried first.private static final long
For cross-version compatibility.Fields inherited from class org.apache.sis.internal.converter.ClassPair
sourceClass, targetClass
-
Constructor Summary
ConstructorsModifierConstructorDescriptionprivate
FallbackConverter
(Class<S> sourceClass, Class<T> targetClass, ObjectConverter<S, ? extends T> primary, ObjectConverter<S, ? extends T> fallback) Creates a converter using the given primary and fallback converters. -
Method Summary
Modifier and TypeMethodDescriptionConverts the given object, using the fallback if needed.private ObjectConverter<S,
? extends T> Mergethis
with another converter whose target class is a subtype of thisClassPair.targetClass
.static <S,
T> ObjectConverter<S, ? extends T> merge
(ObjectConverter<S, ? extends T> primary, ObjectConverter<S, ? extends T> fallback) Appends the givenconverter
in the given tree of fallback converters.private static <S,
T> ObjectConverter<S, ? extends T> mergeIfSubtype
(ObjectConverter<S, T> branch, ObjectConverter<S, ?> converter, Class<? super T> parentTarget) Merges if theconverter
target class of is a subtype of thebranch
target class.private static <S> boolean
needSwap
(ObjectConverter<S, ?> primary, Class<?> fallbackClass) Returnstrue
if the given primary and fallback converters should be interchanged.final Set<FunctionProperty>
Returns the manner in which source values (S) are mapped to target values.toString()
Returns a tree representation of this converter.(package private) final void
toTree
(TreeTable.Node addTo, boolean isNew) Adds a simplified tree representation of thisFallbackConverter
to the given node.private void
toTree
(ObjectConverter<?, ?> converter, TreeTable.Node addTo) Creates a node for the given converter and adds it to the given tree.Methods inherited from class org.apache.sis.internal.converter.SystemConverter
bijective, equals, formatErrorMessage, getSourceClass, getTargetClass, inverse, readResolve, unique
Methods inherited from class org.apache.sis.internal.converter.ClassPair
cast, hashCode, parentSource
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDFor cross-version compatibility.- See Also:
-
The primary converter, to be tried first.
-
fallback
The fallback converter. Its target type should not be assignable from the primary target type, except if both converters have the same target type. We intend primary to be the most generic converter, because we assume that if the user wanted a more specific type he would have asked explicitly for it. In addition this layout reduces the amount of exceptions to be thrown and caught before we found a successful conversion.
-
-
Constructor Details
-
FallbackConverter
private FallbackConverter(Class<S> sourceClass, Class<T> targetClass, ObjectConverter<S, ? extends T> primary, ObjectConverter<S, ? extends T> fallback) Creates a converter using the given primary and fallback converters. This method may interchange the two converters in order to met the fallback contract.- Parameters:
sourceClass
- the source class.targetClass
- the target class.primary
- a first converter.fallback
- a second converter.- See Also:
-
-
Method Details
-
needSwap
Returnstrue
if the given primary and fallback converters should be interchanged. This method may invoke itself recursively.- Parameters:
primary
- the primary converter to test.fallbackClass
- the target class of the fallback converter to test.- Returns:
true
if the given primary and fallback converters should be interchanged.
-
merge
public static <S,T> ObjectConverter<S,? extends T> merge(ObjectConverter<S, ? extends T> primary, ObjectConverter<S, ? extends T> fallback) Appends the givenconverter
in the given tree of fallback converters. This method may create a newFallbackConverter
if the given converter cannot be inserted in the given tree.This method has no information about
In the current implementation, the<T>
type because of parameterized types erasure, and should not need that information if we didn't made a mistake in this class. Nevertheless for safety, callers are encouraged to verify themselves as below:primary
converter can be either an arbitraryObjectConverter
, or a previously createdFallbackConverter
. However, thefallback
converter shall not be aFallbackConverter
. This restriction exists because the tree built in such case would probably not be the desired one. It should be okay if only SIS code deal withFallbackConverter
.- Type Parameters:
S
- the base type of source objects.T
- the base type of converted objects.- Parameters:
primary
- the first converter, which may be aFallback
tree.fallback
- a new fallback to insert in the converters tree.- Returns:
- a tree of converters which contains the given
converter
. May be eitherexisting
,converter
or a newFallbackConverter
instance.
-
mergeIfSubtype
private static <S,T> ObjectConverter<S,? extends T> mergeIfSubtype(ObjectConverter<S, T> branch, ObjectConverter<S, ?> converter, Class<? super T> parentTarget) Merges if theconverter
target class of is a subtype of thebranch
target class. Otherwise returnsnull
.The
branch
can be either an arbitraryObjectConverter
, or a previously createdFallbackConverter
. However, theconverter
shall be a new instance, not aFallbackConverter
instance. Seemerge(ObjectConverter, ObjectConverter)
javadoc for more information.- Type Parameters:
S
- the source class of thebranch
converter.T
- the target class of thebranch
converter- Parameters:
branch
- the converter to eventually merge withconverter
.converter
- the converter to eventually merge withbranch
.parentTarget
- to be given verbatim tomerge(ObjectConverter, Class)
.- Returns:
- the merged converter, or
null
if theconverter
target class is not a subtype of thebranch
target class.
-
merge
private ObjectConverter<S,? extends T> merge(ObjectConverter<S, ? extends T> converter, Class<? super T> parentTarget) Mergethis
with another converter whose target class is a subtype of thisClassPair.targetClass
. If eitherfallback
orprimary
are otherFallbackConverter
instances, then this method will follow those branches.- Parameters:
converter
- the converter to merge withthis
.parentTarget
- if this method is invoked recursively, the target class of the parentFallbackConverter
. Otherwisenull
.- Returns:
- the merged converter.
-
properties
Returns the manner in which source values (S) are mapped to target values. This is the intersection of the properties of the primary and fallback converters.- Returns:
- the manners in which source values are mapped to target values. May be an empty set, but never null.
-
apply
Converts the given object, using the fallback if needed.- Parameters:
source
- the object to convert, ornull
.- Returns:
- the converted object, or
null
. - Throws:
UnconvertibleObjectException
- if the given object is not an element of the function domain.
-
toTree
Creates a node for the given converter and adds it to the given tree. This method invokes itself recursively for scanning through fallbacks.- Parameters:
converter
- the converter for which to create a tree.addTo
- the node in which to add the converter.
-
toTree
Adds a simplified tree representation of thisFallbackConverter
to the given node.- Parameters:
addTo
- the node in which to add the converter.isNew
-true
ifaddTo
is a newly created node.
-
toString
Returns a tree representation of this converter. The tree leaves represent the backing converters.
-