All Downloads are FREE. Search and download functionalities are using the official Maven repository.

functionalj.pipeable.PipeLine Maven / Gradle / Ivy

// ============================================================================
// Copyright (c) 2017-2019 Nawapunth Manusitthipol (NawaMan - http://nawaman.net).
// ----------------------------------------------------------------------------
// MIT License
// 
// 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 functionalj.pipeable;

import static functionalj.pipeable.Catch.toResult;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

import functionalj.function.Func1;
import functionalj.list.ImmutableList;
import lombok.val;

@SuppressWarnings("javadoc")
public class PipeLine implements Func1 {
    
    private static final boolean NULL_SAFE   = true;
    private static final boolean NULL_UNSAFE = false;
    
    @SuppressWarnings("rawtypes")
    private final ImmutableList functions;
    
    @SuppressWarnings("rawtypes")
    private final Catch catchHandler;
    
    @SuppressWarnings("rawtypes")
    private PipeLine(List functions, Catch catchHandler) {
        this.functions    = ImmutableList.from(functions);
        this.catchHandler = catchHandler;
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public OUTPUT applyUnsafe(INPUT input) throws Exception {
        try {
            Object data = input;
            for (int i = 0; i < functions.size(); i++) {
                @SuppressWarnings("rawtypes")
                val func1 = functions.get(i);
                data = __internal.apply(func1, data);
            }
            if (catchHandler == null)
                return (OUTPUT)data;
            
            return (OUTPUT)catchHandler.doCatch(data, null);
            
        } catch (Exception e) {
            
            if (catchHandler == null)
                return (OUTPUT)null;
            return (OUTPUT)catchHandler.doCatch(null, e);
        }
    }
    
    public static  Builder of(Class inputType) {
        val builder = new Builder(NULL_UNSAFE);
        return builder;
    }
    public static  Builder ofNullable(Class inputType) {
        val builder = new Builder(NULL_SAFE);
        return builder;
    }
    
    public static  Builder from(Func1 func1) {
        val builder = new Builder(NULL_UNSAFE);
        builder.functions.add(func1);
        return builder;
    }
    
    
    static class NullSafe extends PipeLine implements NullSafeOperator {
        @SuppressWarnings("rawtypes")
        private NullSafe(List functions, Catch catchHandler) {
            super(functions, catchHandler);
        }
    }
    
    public static class Builder {
        
        private final boolean isNullSafe;
        
        @SuppressWarnings("rawtypes")
        private final List functions = new ArrayList();
        
        private Builder(boolean isNullSafe) {
            this.isNullSafe = isNullSafe;
        }
        
        @SuppressWarnings("rawtypes")
        private Builder(boolean isNullSafe, List functions, Func1 func1) {
            this.isNullSafe = isNullSafe;
            this.functions.addAll(functions);
            this.functions.add(func1);
        }
        
        public  Builder then(Func1 func) {
            return new Builder(isNullSafe, functions, func);
        }
        
        public PipeLine thenReturn() {
            return isNullSafe
                ? new PipeLine.NullSafe<>(functions, null)
                : new PipeLine<>         (functions, null);
        }
        
        public PipeLine thenReturnAsResult() {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, toResult())
                    : new PipeLine<>         (functions, toResult());
        }
        public PipeLine thenReturnOrElse(OUTPUT elseValue) {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, Catch.thenReturn(elseValue))
                    : new PipeLine<>         (functions, Catch.thenReturn(elseValue));
        }
        public PipeLine thenReturnOrElseGet(Supplier elseSupplier) {
            return thenReturnOrGet(elseSupplier);
        }
        public PipeLine thenReturnOrGet(Supplier elseSupplier) {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, Catch.thenGet(elseSupplier))
                    : new PipeLine<>         (functions, Catch.thenGet(elseSupplier));
        }
        public PipeLine thenReturnOrThrow() {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, Catch.thenThrow())
                    : new PipeLine<>         (functions, Catch.thenThrow());
        }
        public PipeLine thenReturnOrThrowRuntimeException() {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, Catch.thenThrowRuntimeException())
                    : new PipeLine<>         (functions, Catch.thenThrowRuntimeException());
        }
        public  PipeLine thenHandleValue(Function mapper) {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, Catch.thenHandleValue(mapper))
                    : new PipeLine<>         (functions, Catch.thenHandleValue(mapper));
        }
        public  PipeLine thenHandleException(Function mapper) {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, Catch.thenHandleException(mapper))
                    : new PipeLine<>         (functions, Catch.thenHandleException(mapper));
        }
        public  PipeLine thenHandle(BiFunction mapper) {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, Catch.thenHandle(mapper))
                    : new PipeLine<>         (functions, Catch.thenHandle(mapper));
        }
        
        public  PipeLine thenCatch(Catch handler) {
            return isNullSafe
                    ? new PipeLine.NullSafe<>(functions, handler)
                    : new PipeLine<>         (functions, handler);
        }
    }
    
}