functionalj.lens.core.LensUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionalj-core Show documentation
Show all versions of functionalj-core Show documentation
The module for FunctionalJ Core.
// ============================================================================
// 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);
}
};
}
}