
net.sf.mmm.util.value.api.ComposedValueConverter Maven / Gradle / Ivy
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.value.api;
import net.sf.mmm.util.component.api.ComponentSpecification;
/**
* This is the interface for a {@link ValueConverter} that is composed out of individual
* {@link ValueConverter}s. The idea of this component is the idiom separations of concerns.
* Therefore you can write an individual {@link ValueConverter} for each type of value you want to deal with.
* These individual {@link ValueConverter}s are combined to one generic converter following the
* composition-pattern. Therefore this generic converter needs to choose the individual {@link ValueConverter}
* that is appropriate for a specific {@link #convert(Object, Object, net.sf.mmm.util.reflect.api.GenericType)
* conversion}.
*
* The meaning of appropriate here can depend on the implementation. However it needs to guarantee
* that the {@link #getSourceType() source-type} of the chosen {@link ValueConverter}
* {@link Class#isAssignableFrom(Class) is assignable from} the actual {@link Object#getClass() type} of the
* object to convert. Additionally the {@link ValueConverter#getTargetType() target-type} of the chosen
* {@link ValueConverter} needs to be {@link Class#isAssignableFrom(Class) assignable from} the actual type to
* convert to or vice versa. The following table illustrates this with some examples:
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* sourceType targetType {@link ValueConverter} applicable String Date <String,Date> yes String Date <Object,Date> yes String Date <String,Calendar> no String Number <String,Integer> yes String Integer <String,Number> yes String Integer <String,Integer> yes Double Integer <String,Integer> no String Double <String,Integer> no * * <Object,Object> yes X * <? super X,Object> yes * Y <Object,? super Y> yes * Y <Object,? extends Y> yes
*
* However the chosen converter may {@link #convert(Object, Object, net.sf.mmm.util.reflect.api.GenericType)
* return} {@code null} to indicate that conversion is NOT possible. This {@link ComposedValueConverter}
* should therefore try all applicable converters starting from most to least specific until conversion
* succeeds. If all applicable converters fail it will also fail and return {@code null}.
*
* @see net.sf.mmm.util.value.impl.DefaultComposedValueConverter#getInstance()
*
* @author Joerg Hohwiller (hohwille at users.sourceforge.net)
* @since 1.0.1
*/
@ComponentSpecification
public interface ComposedValueConverter extends ValueConverter