Java tutorial
/* Copyright (C) 2013-2014 Ian Teune <ian.teune@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.tinspx.util.base; import static com.google.common.base.Preconditions.*; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.MoreObjects; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.primitives.Ints; import java.util.List; import java.util.regex.Pattern; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; import lombok.NonNull; /** * * @author Ian */ public class Base { public static final Integer ZERO_INT = 0; private Base() { } public static Integer parseIntOrZero(@Nullable Object o) { return parseInt(o).or(ZERO_INT); } /** * Attempts to parse the integer if is an Integer, Number, or CharSequence */ public static Optional<Integer> parseInt(@Nullable Object o) { if (o instanceof Integer) { return Optional.of((Integer) o); } else if (o instanceof Number) { return Optional.of(((Number) o).intValue()); } else if (o instanceof CharSequence) { return Optional.fromNullable(Ints.tryParse(o.toString())); } else { return Optional.absent(); } } /** * Returns the first nonnull object, or null if all are null. * Differs from guava {@link MoreObjects#firstNonNull(Object, Object)} * in that it does not throw a NPE if both args are null. */ public static <T> T firstNonNull(@Nullable T first, @Nullable T second) { return first != null ? first : second; } /** * * Returns the first nonnull object, or null if all are null. */ public static <T> T firstNonNull(@Nullable T first, @Nullable T second, @Nullable T third) { return first != null ? first : (second != null ? second : third); } static final Function<Object, Object> NOT_NULL_IDENTITY = new Function<Object, Object>() { @Override public Object apply(Object input) { return checkNotNull(input); } }; @SuppressWarnings("unchecked") public static <E> Function<E, E> notNullIdentity() { return (Function<E, E>) NOT_NULL_IDENTITY; } public static <T> FunctionBuilder<T> functionBuilder() { return new FunctionBuilder<T>(); } @NotThreadSafe public static class FunctionBuilder<T> implements Function<T, T>, Supplier<Function<T, T>> { final List<Function<? super T, ? extends T>> functions; Function<T, T> cache; final boolean stopWhenNull; protected FunctionBuilder() { functions = Lists.newArrayList(); cache = Functions.identity(); stopWhenNull = false; } @SuppressWarnings("LeakingThisInConstructor") private FunctionBuilder(FunctionBuilder<T> fb) { functions = ImmutableList.copyOf(fb.functions); cache = this; stopWhenNull = fb.stopWhenNull(); } @Override public T apply(T input) { if (input == null && stopWhenNull()) { return null; } for (Function<? super T, ? extends T> function : functions) { input = function.apply(input); if (input == null && stopWhenNull()) { return null; } } return input; } /** * If true, the Function returned from {@link #get()} will stop applying * the Functions and return null when the {@code input} becomes null. * This can be useful when there is a large number of Functions and the * Functions have no effect on null input. Defaults to {@code false}. */ protected boolean stopWhenNull() { return stopWhenNull; } public FunctionBuilder<T> append(@NonNull Function<? super T, ? extends T> function) { functions.add(function); cache = null; return this; } public FunctionBuilder<T> prepend(@NonNull Function<? super T, ? extends T> function) { functions.add(0, function); cache = null; return this; } /** * Throws a {@code NullPointerException} on null input. */ public FunctionBuilder<T> notNull() { return append(Base.<T>notNullIdentity()); } /** * Same as {@link #get()}. */ public final Function<T, T> build() { return get(); } @Override public Function<T, T> get() { if (cache == null) { cache = new FunctionBuilder<T>(this); } return cache; } } static final Function<Object, Class<?>> CLASS_FUNCTION = new Function<Object, Class<?>>() { @Override public Class<?> apply(Object input) { return input != null ? input.getClass() : null; } }; @SuppressWarnings("unchecked") public static Function<Object, Class<?>> getClassFunction() { return CLASS_FUNCTION; } public static <T> Predicate<Object> iofAnd(@NonNull final Class<T> cls, @NonNull final Predicate<? super T> predicate) { return new Predicate<Object>() { @Override public boolean apply(Object input) { return cls.isInstance(input) && predicate.apply(cls.cast(input)); } }; } /** * returns a function that computes {@code h(g(f(x)))}. * @see Functions#compose(Function, Function) */ public static <A, B, C, D> Function<A, D> compose(final @NonNull Function<C, D> h, final @NonNull Function<B, ? extends C> g, final @NonNull Function<A, ? extends B> f) { return new Function<A, D>() { @Override public D apply(A input) { return h.apply(g.apply(f.apply(input))); } }; } public static Optional<String> asString(@Nullable Object value) { return value instanceof String ? Optional.of((String) value) : Optional.<String>absent(); } public static Optional<Number> asNumber(@Nullable Object value) { return value instanceof Number ? Optional.of((Number) value) : Optional.<Number>absent(); } public static Optional<Boolean> asBoolean(@Nullable Object value) { return value instanceof Boolean ? Optional.of((Boolean) value) : Optional.<Boolean>absent(); } private static final Function<CharSequence, Pattern> TO_PATTERN = new Function<CharSequence, Pattern>() { @Override public Pattern apply(CharSequence input) { return input != null ? Pattern.compile(input.toString()) : null; } }; public static Function<CharSequence, Pattern> toPattern() { return TO_PATTERN; } }