001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2020 microBean™.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
014 * implied.  See the License for the specific language governing
015 * permissions and limitations under the License.
016 */
017package org.microbean.settings;
018
019import java.lang.reflect.Type;
020
021import javax.enterprise.util.TypeLiteral;
022
023/**
024 * A provider of appropriately-typed {@link Converter} instances,
025 * given {@link Class}, {@link Type} or {@link TypeLiteral} instances.
026 *
027 * @author <a href="https://about.me/lairdnelson"
028 * target="_parent">Laird Nelson</a>
029 *
030 * @see #getConverter(Class)
031 *
032 * @see #getConverter(TypeLiteral)
033 *
034 * @see #getConverter(Type)
035 */
036@FunctionalInterface
037public interface ConverterProvider {
038
039  /**
040   * Returns a {@link Converter} capable of {@linkplain
041   * Converter#convert(Value) converting} {@link Value}s into objects
042   * of the supplied {@code type}.
043   *
044   * @param <T> the conversion type
045   *
046   * @param type a {@link Class} describing the conversion type; must
047   * not be {@code null}
048   *
049   * @return a non-{@code null} {@link Converter} capable of
050   * {@linkplain Converter#convert(Value) converting} {@link Value}s
051   * into objects of the proper type
052   *
053   * @exception NullPointerException if {@code type} is {@code null}
054   *
055   * @exception IllegalArgumentException if no {@link Converter} is
056   * available for the supplied {@code type}
057   *
058   * @idempotency Implementations of this method may return different
059   * {@link Converter} instances over time given the same {@code
060   * type}.
061   *
062   * @nullability Implementations of this method must never return
063   * {@code null}.
064   *
065   * @threadsafety Implementations of this method must be safe for
066   * concurrent use by multiple threads.
067   *
068   * @see #getConverter(Type)
069   */
070  default public <T> Converter<? extends T> getConverter(final Class<T> type) {
071    @SuppressWarnings("unchecked")
072    final Converter<? extends T> returnValue = (Converter<? extends T>)this.getConverter((Type)type);
073    return returnValue;
074  }
075
076  /**
077   * Returns a {@link Converter} capable of {@linkplain
078   * Converter#convert(Value) converting} {@link Value}s into objects
079   * of the supplied {@code type}.
080   *
081   * @param <T> the conversion type
082   *
083   * @param type a {@link TypeLiteral} describing the conversion type;
084   * must not be {@code null}
085   *
086   * @return a non-{@code null} {@link Converter} capable of
087   * {@linkplain Converter#convert(Value) converting} {@link Value}s
088   * into objects of the proper type
089   *
090   * @exception NullPointerException if {@code type} is {@code null}
091   *
092   * @exception IllegalArgumentException if no {@link Converter} is
093   * available for the supplied {@code type}
094   *
095   * @idempotency Implementations of this method may return different
096   * {@link Converter} instances over time given the same {@code
097   * type}.
098   *
099   * @nullability Implementations of this method must never return
100   * {@code null}.
101   *
102   * @threadsafety Implementations of this method must be safe for
103   * concurrent use by multiple threads.
104   *
105   * @see #getConverter(Type)
106   */
107  default public <T> Converter<? extends T> getConverter(final TypeLiteral<T> type) {
108    @SuppressWarnings("unchecked")
109    final Converter<? extends T> returnValue = (Converter<? extends T>)this.getConverter(type.getType());
110    return returnValue;
111  }
112
113  /**
114   * Returns a {@link Converter} capable of {@linkplain
115   * Converter#convert(Value) converting} {@link Value}s into objects
116   * of the supplied {@code type}.
117   *
118   * <p>Implementations of this method must not call either {@link
119   * #getConverter(Class)} or {@link #getConverter(TypeLiteral)} or
120   * undefined behavior may result.</p>
121   *
122   * @param type a {@link Type} describing the conversion type; must
123   * not be {@code null}
124   *
125   * @return a non-{@code null} {@link Converter} capable of
126   * {@linkplain Converter#convert(Value) converting} {@link Value}s
127   * into objects of the proper type
128   *
129   * @exception NullPointerException if {@code type} is {@code null}
130   *
131   * @exception IllegalArgumentException if no {@link Converter} is
132   * available for the supplied {@code type}
133   *
134   * @idempotency Implementations of this method may return different
135   * {@link Converter} instances over time given the same {@code
136   * type}.
137   *
138   * @nullability Implementations of this method must never return
139   * {@code null}.
140   *
141   * @threadsafety Implementations of this method must be safe for
142   * concurrent use by multiple threads.
143   */
144  public Converter<?> getConverter(final Type type);
145  
146}