com.tinspx.util.base.Base.java Source code

Java tutorial

Introduction

Here is the source code for com.tinspx.util.base.Base.java

Source

/* 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;
    }
}