/** * Copyright 2010 CosmoCode GmbH * * 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 * * http://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 de.cosmocode.palava.ipc.xml.rpc.adapters; import com.google.common.base.Function; import com.google.common.base.Preconditions; /** * Utility class for {@link Adapter}s. * * @since 1.0 * @author Willi Schoenborn */ public final class Adapters { private Adapters() { } /** * Adapts the specified adapter to the {@link Function} interface using {@link Adapter#decode(Object)}. * * @since 1.0 * @param <F> source type * @param <T> target type * @param adapter the backing adapter * @return a function using the decode method of the given adapter * @throws NullPointerException if adapter is null */ public static <F, T> Function<F, T> asDecoder(final Adapter<? super F, ? extends T> adapter) { Preconditions.checkNotNull(adapter, "Adapter"); return new Function<F, T>() { @Override public T apply(F from) { return adapter.decode(from); } @Override public String toString() { return String.format("Adapters.asDecoder(%s)", adapter); } }; } /** * Adapts the specified adapter to the {@link Function} interface using {@link Adapter#encode(Object)}. * * @since 1.0 * @param <F> target type * @param <T> source type * @param adapter the backing adapter * @return a function using the encode method of the given adapter * @throws NullPointerException if adapter is null */ public static <F, T> Function<T, F> asEncoder(final Adapter<? extends F, ? super T> adapter) { Preconditions.checkNotNull(adapter, "Adapter"); return new Function<T, F>() { @Override public F apply(T from) { return adapter.encode(from); } @Override public String toString() { return String.format("Adapters.asEncoder(%s)", adapter); } }; } /** * Creates an inverse version of the specified {@link Adapter} which uses * {@link Adapter#decode(Object)} when asked to encode and vice versa. * * @since 1.0 * @param <F> target type * @param <T> source type * @param adapter the backing adapter * @return an adapter which is a flipped version of the given one * @throws NullPointerException if adapter is null */ public static <F, T> Adapter<T, F> flip(final Adapter<F, T> adapter) { Preconditions.checkNotNull(adapter, "Adapter"); return new Adapter<T, F>() { @Override public F decode(T input) { return adapter.encode(input); } @Override public T encode(F input) { return adapter.decode(input); } @Override public String toString() { return String.format("Adapters.flip(%s)", adapter); } }; } /** * Composes two {@link Adapter}s into one. * * @since 1.0 * @param <F> source type * @param <T> intermediate type * @param <S> target type * @param left left adapter * @param right right adapter * @return an adapter chaining left and right * @throws NullPointerException if left or right is null */ public static <F, T, S> Adapter<F, S> compose(final Adapter<F, T> left, final Adapter<T, S> right) { Preconditions.checkNotNull(left, "Left"); Preconditions.checkNotNull(right, "Right"); return new Adapter<F, S>() { @Override public S decode(F input) { return right.decode(left.decode(input)); } @Override public F encode(S input) { return left.encode(right.encode(input)); } @Override public String toString() { return String.format("Adapters.compose(%s, %s)", left, right); } }; } /** * Composes an {@link Adapter} and a {@link Function} into a one-way encoder, an adapter which * supports {@link Adapter#encode(Object)} but not {@link Adapter#decode(Object)}. * * @since 1.0 * @param <F> the source type * @param <T> the intermediate type * @param <S> the target type * @param adapter the backing adapter * @param function the encoding function * @return a composed adapter using the specified adapter and function for encoding */ public static <F, T, S> Adapter<F, S> composeEncoder(final Adapter<F, T> adapter, final Function<? super S, ? extends T> function) { Preconditions.checkNotNull(adapter, "Adapter"); Preconditions.checkNotNull(function, "Function"); return new Adapter<F, S>() { @Override public S decode(F input) { throw new UnsupportedOperationException(); } @Override public F encode(S input) { return adapter.encode(function.apply(input)); } @Override public String toString() { return String.format("Adapters.compose(%s, %s)", adapter, function); } }; } }