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

functionalj.lens.core.LensUtils 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.lens.core;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.BooleanSupplier;
import java.util.function.Function;

import functionalj.lens.lenses.AnyLens;
import functionalj.lens.lenses.FuncListLens;
import functionalj.lens.lenses.ListLens;
import functionalj.lens.lenses.MapLens;
import functionalj.lens.lenses.NullableLens;
import functionalj.lens.lenses.ObjectLens;
import functionalj.lens.lenses.OptionalLens;
import functionalj.lens.lenses.ResultLens;
import functionalj.list.FuncList;
import functionalj.map.FuncMap;
import functionalj.result.Result;
import lombok.val;
import nullablej.nullable.Nullable;

@SuppressWarnings("javadoc")
public class LensUtils {

    public static  SUBLENS createSubLens(
            ObjectLens                 dataLens,
            Function                    readSub,
            WriteLens                   writeSub,
            Function, SUBLENS> subLensCreator) {
        val lensSpec    = dataLens.lensSpec();
        val hostSubSpec = lensSpec.then(LensSpec.of(readSub, writeSub, lensSpec.isNullSafe()));
        return subLensCreator.apply(hostSubSpec);
    }
    
    public static  Function createSubRead(
            Function readValue,
            Function  readSub, 
            BooleanSupplier      isNullSafe) {
        return host ->{
            val value = readValue.apply(host);
            if (isNullSafe.getAsBoolean() && (value == null))
                return null;
            
            val subValue = readSub.apply(value);
            return subValue;
        };
    }
    
    public static  WriteLens createSubWrite(
            Function         readValue,
            WriteLens        writeValue,
            BiFunction  writeSub,
            BooleanSupplier              isNullSafe) {
        return createSubWrite(readValue, writeValue, WriteLens.of(writeSub), isNullSafe);
    }
    
    public static  WriteLens createSubWrite(
            Function  readValue,
            WriteLens writeValue,
            WriteLens  writeSub,
            BooleanSupplier       isNullSafe) {
        return (host, newSubValue)->{
            return performWrite(readValue, writeValue, writeSub, isNullSafe, host, newSubValue);
        };
    }
    
    private static  HOST performWrite(Function readValue, WriteLens writeValue,
            WriteLens writeSub, BooleanSupplier isNullSafe, HOST host, SUB newSubValue) {
        val oldValue = readValue.apply(host);
        if (isNullSafe.getAsBoolean() && (oldValue == null))
            return host;
        
        val newValue = writeSub.apply(oldValue, newSubValue);
        val newHost  = writeValue.apply(host, newValue);
        return newHost;
    }
    
    //== Parameterized ==
    
    public static > 
        LensSpecParameterized createLensSpecParameterized(
            Function                   read,
            WriteLens                  write,
            Function, SUBLENS> subCreator) {
        val spec = new LensSpecParameterized() {
            @Override
            public LensSpec getSpec() {
                return LensSpec.of(read, write);
            }
            @Override
            public SUBLENS createSubLens(LensSpec subSpec) {
                return subCreator.apply(subSpec);
            }
        };
        return spec;
    }
    
    //== Nullable ==
    
    public static > NullableLens 
        createNullableLens(
            Function>          read,
            WriteLens>         write,
            Function, SUBLENS> subCreator) {
        val spec = createLensSpecParameterized(read, write, subCreator);
        val lens = (NullableLens)()->spec;
        return lens;
    }
    
    public static > NullableLens 
        createNullableLens(
            LensSpec> nullableLensSpec,
            Function, SUBLENS> subCreator) {
        val lens = createNullableLens(nullableLensSpec.getRead(), nullableLensSpec.getWrite(), subCreator);
        return lens;
    }
    
    //== Result ==
    
    public static > ResultLens 
        createResultLens(
            Function>          read,
            WriteLens>         write,
            Function, SUBLENS> subCreator) {
        val spec = createLensSpecParameterized(read, write, subCreator);
        val lens = (ResultLens)()->spec;
        return lens;
    }
    
    public static > ResultLens 
        createResultLens(
            LensSpec> resultLensSpec,
            Function, SUBLENS> subCreator) {
        val lens = createResultLens(resultLensSpec.getRead(), resultLensSpec.getWrite(), subCreator);
        return lens;
    }
    
    //== Optional ==
    
    public static > OptionalLens 
        createOptionalLens(
            Function>          read,
            WriteLens>         write,
            Function, SUBLENS> subCreator) {
        val spec = createLensSpecParameterized(read, write, subCreator);
        val lens = (OptionalLens)()->spec;
        return lens;
    }
    
    public static > OptionalLens 
        createOptionalLens(
            LensSpec> spec,
            Function, SUBLENS> subCreator) {
        val lens = createOptionalLens(spec.getRead(), spec.getWrite(), subCreator);
        return lens;
    }
    
    //== List ==
    
    public static > ListLens 
        createListLens(
            Function>              read,
            WriteLens>             write,
            Function, SUBLENS> subCreator) {
        val spec = createLensSpecParameterized(read, write, subCreator);
        val listLens = ListLens.of(spec);
        return listLens;
    }
    
    public static > ListLens
            createSubListLens(
                LensSpec>                              spec,
                LensSpecParameterized, TYPE, TYPELENS> specParameterized,
                Function>                              read) {
        val newSpec = new LensSpecParameterized, TYPE, TYPELENS>() {
            @Override
            public LensSpec> getSpec() {
                return new LensSpec<>(read, spec.getWrite(), spec.getIsNullSafe());
            }
            @Override
            public TYPELENS createSubLens(LensSpec subSpec) {
                return specParameterized.createSubAccessFromHost(subSpec.getRead());
            }
        };
        return () -> newSpec;
    }
    
    //== Map ==
    
    public static , VALUELENS extends AnyLens>
            MapLens of(
                    Function>           read,
                    WriteLens>           write,
                    Function,   KEYLENS>   keyLensCreator,
                    Function, VALUELENS> valueLensCreator) {
        return MapLens.of(read, write, keyLensCreator, valueLensCreator);
    }
    
    public static , HOST, VALUELENS extends AnyLens, KEY, VALUE>
            LensSpecParameterized2, KEY, VALUE, KEYLENS, VALUELENS> createMapLensSpec(
                    Function>           read,
                    WriteLens>           write,
                    Function,   KEYLENS>   keyLensCreator,
                    Function, VALUELENS> valueLensCreator) {
        return new LensSpecParameterized2, KEY, VALUE, KEYLENS, VALUELENS>() {

            @Override
            public LensSpec> getSpec() {
                return LensSpec.of(read, write);
            }

            @Override
            public KEYLENS createSubLens1(
                    LensSpec subSpec) {
                return keyLensCreator.apply(subSpec);
            }

            @Override
            public VALUELENS createSubLens2(
                    LensSpec subSpec) {
                return valueLensCreator.apply(subSpec);
            }
        };
    }
    
    //== FuncList ==
    
    public static > FuncListLens 
        createFuncListLens(
            Function>   read,
            WriteLens>   write,
            Function, SUBLENS> subCreator) {
        val spec = createLensSpecParameterized(read, write, subCreator);
        val listLens = FuncListLens.of(spec);
        return listLens;
    }
    
    public static > FuncListLens
            createSubFuncListLens(
                LensSpec>                              spec,
                LensSpecParameterized, TYPE, TYPELENS> specParameterized,
                Function>                              read) {
        val newSpec = new LensSpecParameterized, TYPE, TYPELENS>() {
            @Override
            public LensSpec> getSpec() {
                return new LensSpec<>(read, spec.getWrite(), spec.getIsNullSafe());
            }
            @Override
            public TYPELENS createSubLens(LensSpec subSpec) {
                return specParameterized.createSubLens(subSpec);
            }
        };
        return () -> newSpec;
    }
    
    // == FuncMap ==
    
    public static , HOST, VALUELENS extends AnyLens, KEY, VALUE>
            LensSpecParameterized2, KEY, VALUE, KEYLENS, VALUELENS> createFuncMapLensSpec(
                    Function>       read,
                    WriteLens>       write,
                    Function,   KEYLENS>   keyLensCreator,
                    Function, VALUELENS> valueLensCreator) {
        return new LensSpecParameterized2, KEY, VALUE, KEYLENS, VALUELENS>() {
            
            @Override
            public LensSpec> getSpec() {
                return LensSpec.of(read, write);
            }
            
            @Override
            public KEYLENS createSubLens1(
                    LensSpec subSpec) {
                return keyLensCreator.apply(subSpec);
            }
            
            @Override
            public VALUELENS createSubLens2(
                    LensSpec subSpec) {
                return valueLensCreator.apply(subSpec);
            }
        };
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy