Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.osgl.Lang Maven / Gradle / Ivy
package org.osgl;
/*-
* #%L
* Java Tool
* %%
* Copyright (C) 2014 - 2017 OSGL (Open Source General Library)
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import static org.osgl.util.DataMapper.MappingRule.KEYWORD_MATCHING;
import static org.osgl.util.DataMapper.MappingRule.STRICT_MATCHING;
import static org.osgl.util.DataMapper.Semantic.*;
import static org.osgl.util.XML.HINT_PRETTY;
import com.alibaba.fastjson.*;
import org.osgl.cache.CacheService;
import org.osgl.concurrent.ContextLocal;
import org.osgl.exception.*;
import org.osgl.util.*;
import org.osgl.util.TypeReference;
import org.osgl.util.converter.*;
import org.w3c.dom.Document;
import osgl.version.Version;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.sql.ResultSet;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Osgl
is the umbrella namespace aggregates core utilities of OSGL toolkit:
*
* Function interfaces and base implementations
* currying utilities
* Tuple and multi-elements tupbles
* Option
* core utilities like ts()
* predefined functions aggregated in the F
namespace
*
* More about function interface
* Under Osgl
, there are six function interfaces defined, from Func0
* to Func5
, where the last digit means the number of parameters the function
* is applied to. For example, the apply
method of Func0
takes
* no parameter while that of Func2
takes two parameters. All these function
* interfaces are defined with generic type parameters, corresponding to the type of all
* parameters and that of the return value. For procedure (a function that does not return anything),
* the user application could use Void
as the return value type, and return
* null
in the apply
method implementation.
* For each function interface, OSGL provide a base class, from F0
to
* F5
. Within the base class, OSGL implement several utility methods, including
*
* currying methods, returns function takes fewer parameter with given parameter specified
* chain, returns composed function with a function takes the result of this function
* andThen, returns composed function with an array of same signature functions
* breakOut, short cut the function execution sequence by throwing out a {@link Break} instance
*
* Usually user application should define their function implementation by extending the base class in order
* to benefit from the utility methods; however in certain cases, e.g. a function implementation already
* extends another base class, user implementation cannot extends the base function class, OSGL provides
* easy way to convert user's implementation to corresponding base class implementation, here is one
* example of how to do it:
*
* void foo(Func2<Integer, String> f) {
* F2<Integer, String> newF = f2(f);
* newF.chain(...);
* ...
* }
*
* Dumb functions, for certain case where a dumb function is needed, OSGL defines dumb function instances for
* each function interface, say, from F0
to F5
. Note the name of the dumb function
* instance is the same as the name of the base function class. But they belong to different concept, class and
* instance, so there is no conflict in the code. For each dumb function instance, a corresponding type safe
* version is provided, f0()
to f5()
, this is the same case of
* java.util.Collections.EMPTY_LIST
and java.util.Collections.emptyList()
* Utility methods
*
* @author Gelin Luo
* @version 0.8
*/
public class Lang implements Serializable {
public static final Version VERSION = Version.get();
public static final Lang INSTANCE = $.INSTANCE;
protected Lang() {
}
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
@Override
public final boolean equals(Object obj) {
return obj == this || obj instanceof Lang;
}
@Override
public final int hashCode() {
return Lang.class.hashCode();
}
@Override
public final String toString() {
return "OSGL";
}
// --- Functions and their default implementations
/**
* The base for all Fx function class implemention
*/
public static abstract class FuncBase {
/**
* Return a {@link Break} with payload. Here is an example of how to use this method:
*
* myData.accept(new Visitor(){
* public void apply(T e) {
* if (...) {
* throw breakOut(e);
* }
* }
* })
*
*
* @param payload
* the object passed through the Break
* @return a {@link Break} instance
*/
protected final Break breakOut(Object payload) {
return new Break(payload);
}
}
/**
* Define a function that apply to no parameter (strictly this is not a function)
*
* @param
* the generic type of the return value, could be Void
* @see Function
* @see Func2
* @see Func3
* @see Func4
* @see Func5
* @see F0
* @since 0.2
*/
public interface Func0 {
/**
* user application to implement main logic of applying the function
*
* @return the Result instance of type R after appplying the function
* @throws NotAppliedException
* if the function doesn't apply to the current context
* @throws Break
* to short cut collecting operations (fold/reduce) on an {@link org.osgl.util.C.Traversable container}
*/
R apply() throws NotAppliedException, Break;
}
/**
* Default implementation for {@link Func0}. Implementation of {@link Func0} should
* (nearly) always extend to this class instead of implement the interface directly
*
* @since 0.2
*/
public static abstract class F0 extends FuncBase implements Func0 {
/**
* Applies this partial function to the given argument when it is contained in the function domain.
* Applies fallback function where this partial function is not defined, i.e. any
* {@link java.lang.RuntimeException} is captured
*
* @param fallback
* if {@link RuntimeException} captured then apply this fallback function
* @return the result of this function or the fallback function application
*/
public R applyOrElse(F0 extends R> fallback) {
try {
return apply();
} catch (RuntimeException e) {
return fallback.apply();
}
}
/**
* Returns a composed function that applies this function to it's input and
* then applies the {@code after} function to the result. If evaluation of either
* function throws an exception, it is relayed to the caller of the composed
* function.
*
* @param after
* the function applies after this function is applied
* @param
* the type of the output of the {@code before} function
* @return the composed function
* @throws NullPointerException
* if {@code before} is null
*/
public Producer andThen(final Function super R, ? extends T> after) {
E.NPE(after);
final F0 me = this;
return new Producer() {
@Override
public T produce() {
return after.apply(me.apply());
}
};
}
/**
* Returns a composed function that applied, in sequence, this function and
* all functions specified one by one. If applying anyone of the functions
* throws an exception, it is relayed to the caller of the composed function.
* If an exception is thrown out, the following functions will not be applied.
* When apply the composed function, the result of the last function
* is returned
*
* @param fs
* a sequence of function to be applied after this function
* @return a composed function
*/
public F0 andThen(final Func0 extends R>... fs) {
if (fs.length == 0) {
return this;
}
final F0 me = this;
return new F0() {
@Override
public R apply() {
R r = me.apply();
for (Func0 extends R> f : fs) {
r = f.apply();
}
return r;
}
};
}
/**
* Returns a composed function that when applied, try to apply this function first, in case
* a {@link java.lang.RuntimeException} is captured apply to the fallback function specified. This
* method helps to implement partial function
*
* @param fallback
* the function to applied if this function doesn't apply in the current situation
* @return the final result
*/
public F0 orElse(final Func0 extends R> fallback) {
final F0 me = this;
return new F0() {
@Override
public R apply() {
try {
return me.apply();
} catch (RuntimeException e) {
return fallback.apply();
}
}
};
}
/**
* Turns this partial function into a plain function returning an Option result.
*
* @return a function that takes an argument x to Some(this.apply(x)) if this can be applied, and to None otherwise.
*/
public F0> lift() {
final F0 me = this;
return new F0>() {
@Override
public Option apply() {
try {
return some(me.apply());
} catch (RuntimeException e) {
return none();
}
}
};
}
}
/**
* The class adapt traditional Factory to Function
*
* @param
* the type of the instance been created by the factory
*/
public static abstract class Factory extends F0 {
@Override
public T apply() throws NotAppliedException, Break {
return create();
}
/**
* The abstract create method that will be called by
* the {@link #apply()} method
*
* @return an instance the factory create
*/
public abstract T create();
}
@SuppressWarnings("unchecked")
public static Factory factory(final Func0 func) {
if (func instanceof Factory) {
return (Factory) func;
}
return new Factory() {
@Override
public T create() {
return func.apply();
}
};
}
private static class DumbF0 extends F0 implements Serializable {
private static final long serialVersionUID = 2856835860950L;
@Override
public Object apply() throws NotAppliedException, Break {
return null;
}
}
/**
* A dumb function for {@link Func0} that does nothing and return null
*
* @see #f0()
* @since 0.2
*/
public static final F0 F0 = new DumbF0();
/**
* Return a dumb function for {@link Func0}. This is the type-safe version of {@link #F0}
*
* @param
* a generic type that matches whatever type required by the context of applying the function
* @return A dumb function that always return {@code null}
* @since 0.2
*/
@SuppressWarnings("unchecked")
public static F0 f0() {
return (F0) F0;
}
/**
* Convert a general {@link Func0} typed function to {@link F0} type
*
* @param f0
* a function of type {@link Func0} that returns type R value
* @param
* the generic type of the return value when applying function f0
* @return a {@link F0} type that is equaivlent to function f0
* @since 0.2
*/
@SuppressWarnings("unchecked")
public static F0 f0(final Func0 extends R> f0) {
E.NPE(f0);
if (f0 instanceof F0) {
return (F0) f0;
}
return new F0() {
@Override
public R apply() {
return f0.apply();
}
};
}
/**
* Define a function structure that accept one parameter. This interface is created to make it
* easily migrate to Java 8 in the future
*
* @param
* the type of input parameter
* @param
* the type of the return value when this function applied to the parameter(s)
* @see Func0
* @see Function
* @see Func2
* @see Func3
* @see Func4
* @see Func5
* @see F1
* @since 0.2
*/
public interface Function {
/**
* Apply this function to <T> type parameter.
* In case implementing a partial function, it can throw out an
* {@link NotAppliedException} if the function is not defined for
* the given parameter(s)
*
* @param t
* the argument
* @return {@code U} type result
* @throws NotAppliedException
* if the function doesn't apply to the parameter(s)
* @throws Break
* to short cut collecting operations (fold/reduce) on an {@link org.osgl.util.C.Traversable container}
*/
U apply(T t) throws NotAppliedException, Break;
}
/**
* Alias of {@link Function}
*
* @param
* the argument type
* @param
* the return value type
* @since 0.2
*/
public interface Func1 extends Function {
}
/**
* A {@link Function} function that support {@link #times(int)} operation
*
* @param
* the type of parameter the function applied to
* @param
* the type of return value of the function
*/
public interface MultiplicableFunction extends Function {
/**
* Returns a function with {@code n} times factor specified. When the function
* returned applied to a param, the effect is the same as apply this function
* {@code n} times to the same param
*
* @param n
* specify the times factor
* @return the new function
*/
MultiplicableFunction times(int n);
}
/**
* See http://en.wikipedia.org/wiki/Bijection . A
* {@code Bijection} (mapping from {@code X} to {@code Y} is a special {@link Function} that has an
* inverse function by itself also a {@code Bijection} mapping from {@code Y} to {@code X}
*
* @param
* the type of parameter
* @param
* the type of return value
*/
public interface Bijection extends Function {
/**
* Returns the inverse function mapping from {@code Y} back to {@code X}
*
* @return a function that map {@code Y} type element to {@code X} type element
*/
Bijection invert();
}
/**
* Base implementation of {@link Function} function. User application should
* (nearly) always make their implementation extend to this base class
* instead of implement {@link Function} directly
*
* @since 0.2
*/
public static abstract class F1
extends FuncBase
implements Func1, Bijection, MultiplicableFunction {
@Override
public Bijection invert() {
throw new NotAppliedException();
}
@Override
public MultiplicableFunction times(final int n) {
E.illegalArgumentIf(n < 1);
if (n == 1) return this;
final F1 me = this;
return new F1() {
@Override
public R apply(P1 p1) throws NotAppliedException, Break {
R r = null;
for (int i = 0; i < n; ++i) {
r = me.apply(p1);
}
return r;
}
};
}
/**
* Applies this partial function to the given argument when it is contained in the function domain.
* Applies fallback function where this partial function is not defined.
*
* @param p1
* the argument this function to be applied
* @param fallback
* the function to be applied to the argument p1 when this function failed with any runtime exception
* @return the result of this function or the fallback function application
*/
public R applyOrElse(P1 p1, F1 super P1, ? extends R> fallback) {
try {
return apply(p1);
} catch (RuntimeException e) {
return fallback.apply(p1);
}
}
public final F0 curry(final P1 p1) {
final Function me = this;
return new F0() {
@Override
public R apply() {
return me.apply(p1);
}
};
}
/**
* Returns a composed function that applies this function to it's input and
* then applies the {@code after} function to the result. If evaluation of either
* function throws an exception, it is relayed to the caller of the composed
* function.
*
* @param
* the type of return value of the new composed function
* @param after
* the function applies after this function is applied
* @return the composed function
* @throws NullPointerException
* if @{code after} is null
*/
public F1 andThen(final Function super R, ? extends T> after) {
E.NPE(after);
final Function me = this;
return new F1() {
@Override
public T apply(P1 p1) {
return after.apply(me.apply(p1));
}
};
}
/**
* Returns a composed function that applied, in sequence, this function and
* all functions specified one by one. If applying anyone of the functions
* throws an exception, it is relayed to the caller of the composed function.
* If an exception is thrown out, the following functions will not be applied.
* When apply the composed function, the result of the last function
* is returned
*
* @param afters
* a sequence of function to be applied after this function
* @return a composed function
*/
public F1 andThen(final Function super P1, ? extends R>... afters) {
if (0 == afters.length) {
return this;
}
final F1 me = this;
return new F1() {
@Override
public R apply(P1 p1) {
R r = me.apply(p1);
for (Function super P1, ? extends R> f : afters) {
r = f.apply(p1);
}
return r;
}
};
}
/**
* Returns a composed function that when applied, try to apply this function first, in case
* a {@link NotAppliedException} is captured apply to the fallback function specified. This
* method helps to implement partial function
*
* @param fallback
* the function to applied if this function doesn't apply to the parameter(s)
* @return the composed function
*/
public F1 orElse(final Function super P1, ? extends R> fallback) {
final F1 me = this;
return new F1() {
@Override
public R apply(P1 p1) {
try {
return me.apply(p1);
} catch (RuntimeException e) {
return fallback.apply(p1);
}
}
};
}
/**
* Returns an {@code F0<R>>} function by composing the specified {@code Func0<P1>} function
* with this function applied last
*
* @param before
* the function to be applied first when applying the return function
* @return an new function such that f() == apply(f0())
*/
public F0 compose(final Func0 extends P1> before) {
final F1 me = this;
return new F0() {
@Override
public R apply() {
return me.apply(before.apply());
}
};
}
/**
* Returns an {@code F1<X1, R>>} function by composing the specified
* {@code Function<X1, P1>} function with this function applied last
*
* @param before
* the function to be applied first when applying the return function
* @param
* type of argument takes by the {@code before} function
* @return an new function such that f(a) == apply(f1(a))
*/
public F1
compose(final Function super X1, ? extends P1> before) {
final F1 me = this;
return new F1() {
@Override
public R apply(X1 x1) {
return me.apply(before.apply(x1));
}
};
}
/**
* Returns an {@code F2<X1, X2, R>>} function by composing the specified
* {@code Func2<X1, X2, P1>} function with this function applied last
*
* @param
* the type of first param the new function applied to
* @param
* the type of second param the new function applied to
* @param before
* the function to be applied first when applying the return function
* @return an new function such that f(x1, x2) == apply(f1(x1, x2))
*/
public F2
compose(final Func2 super X1, ? super X2, ? extends P1> before) {
final F1 me = this;
return new F2() {
@Override
public R apply(X1 x1, X2 x2) {
return me.apply(before.apply(x1, x2));
}
};
}
/**
* Returns an {@code F3<X1, X2, X3, R>>} function by composing the specified
* {@code Func3<X1, X2, X3, P1>} function with this function applied last
*
* @param
* the type of first param the new function applied to
* @param
* the type of second param the new function applied to
* @param
* the type of third param the new function applied to
* @param before
* the function to be applied first when applying the return function
* @return an new function such that f(x1, x2, x3) == apply(f1(x1, x2, x3))
*/
public F3
compose(final Func3 super X1, ? super X2, ? super X3, ? extends P1> before) {
final F1 me = this;
return new F3() {
@Override
public R apply(X1 x1, X2 x2, X3 x3) {
return me.apply(before.apply(x1, x2, x3));
}
};
}
/**
* Returns an {@code F3<X1, X2, X3, X4, R>>} function by composing the specified
* {@code Func3<X1, X2, X3, X4, P1>} function with this function applied last
*
* @param
* the type of first param the new function applied to
* @param
* the type of second param the new function applied to
* @param
* the type of third param the new function applied to
* @param
* the type of fourth param the new function applied to
* @param before
* the function to be applied first when applying the return function
* @return an new function such that f(x1, x2, x3, x4) == apply(f1(x1, x2, x3, x4))
*/
public F4
compose(final Func4 super X1, ? super X2, ? super X3, ? super X4, ? extends P1> before) {
final F1 me = this;
return new F4() {
@Override
public R apply(X1 x1, X2 x2, X3 x3, X4 x4) {
return me.apply(before.apply(x1, x2, x3, x4));
}
};
}
/**
* Returns an {@code F3<X1, X2, X3, X4, X5, R>>} function by composing the specified
* {@code Func3<X1, X2, X3, X4, X5, P1>} function with this function applied last
*
* @param
* the type of first param the new function applied to
* @param
* the type of second param the new function applied to
* @param
* the type of third param the new function applied to
* @param
* the type of fourth param the new function applied to
* @param
* the type of fifth param the new function applied to
* @param before
* the function to be applied first when applying the return function
* @return an new function such that f(x1, x2, x3, x4, x5) == apply(f1(x1, x2, x3, x4, x5))
*/
public F5
compose(final Func5 super X1, ? super X2, ? super X3, ? super X4, ? super X5, ? extends P1> before) {
final F1 me = this;
return new F5() {
@Override
public R apply(X1 x1, X2 x2, X3 x3, X4 x4, X5 x5) {
return me.apply(before.apply(x1, x2, x3, x4, x5));
}
};
}
/**
* Turns this partial function into a plain function returning an Option result.
*
* @return a function that takes an argument x to Some(this.apply(x)) if this can be applied, and to None otherwise.
*/
public F1> lift() {
final F1 me = this;
return new F1>() {
@Override
public Option apply(P1 p1) {
try {
return some(me.apply(p1));
} catch (RuntimeException e) {
return none();
}
}
};
}
}
private static class DumbF1 extends F1 implements Serializable {
private static final long serialVersionUID = 2856835860951L;
@Override
public Object apply(Object o) throws NotAppliedException, Break {
return null;
}
}
/**
* A dumb {@link Function} implementation that does nothing and return null
*
* @see #f1()
* @since 0.2
*/
public static final F1 F1 = new DumbF1();
/**
* The type-safe version of {@link #F1}
*
* @param
* the argument type
* @param
* the return value type
* @return a dumb function {@link #F1}
* @since 0.2
*/
@SuppressWarnings("unchecked")
public static F1 f1() {
return (F1) F1;
}
/**
* Convert a general {@link Function} function into a {@link F1} typed
* function
*
* @param f1
* the function that consumes {@code P1} and produce {@code R}
* @param
* the argument type
* @param
* the return value type
* @return whatever of type {@code R}
* @since 0.2
*/
@SuppressWarnings("unchecked")
public static F1 f1(final Function super P1, ? extends R> f1) {
E.NPE(f1);
if (f1 instanceof F1) {
return (F1) f1;
}
return new F1() {
@Override
public R apply(P1 p1) {
return f1.apply(p1);
}
@Override
public MultiplicableFunction times(int n) {
if (f1 instanceof MultiplicableFunction) {
return ((MultiplicableFunction) f1).times(n);
}
return super.times(n);
}
};
}
public static F1 f1(final Bijection f1) {
E.NPE(f1);
if (f1 instanceof F1) {
return (F1) f1;
}
return new F1() {
@Override
public Y apply(X p1) {
return f1.apply(p1);
}
@Override
public F1 invert() {
return f1(f1.invert());
}
@Override
@SuppressWarnings("unchecked")
public MultiplicableFunction times(int n) {
if (f1 instanceof MultiplicableFunction) {
return ((MultiplicableFunction) f1).times(n);
}
return super.times(n);
}
};
}
/**
* Define a function structure that accept two parameter
*
* @param
* the type of first parameter this function applied to
* @param
* the type of second parameter this function applied to
* @param
* the type of the return value when this function applied to the parameter(s)
* @see Func0
* @see Function
* @see Func3
* @see Func4
* @see Func5
* @see F2
* @since 0.2
*/
public interface Func2 {
/**
* Apply the two params to the function
* In case implementing a partial function, it can throw out an
* {@link NotAppliedException} if the function is not defined for
* the given parameter(s)
*
* @param p1
* the first argument of type P1
* @param p2
* the second argument of type P2
* @return the result of type R
* @throws NotAppliedException
* if the function doesn't apply to the parameter(s)
* @throws Break
* to short cut collecting operations (fold/reduce) on an {@link org.osgl.util.C.Traversable container}
*/
R apply(P1 p1, P2 p2) throws NotAppliedException, Break;
}
/**
* Base implementation of {@link Func2} function. User application should
* (nearly) always make their implementation extend to this base class
* instead of implement {@link Func2} directly
*
* @since 0.2
*/
public static abstract class F2
extends FuncBase
implements Func2 {
/**
* Applies this partial function to the given argument when it is contained in the function domain.
* Applies fallback function where this partial function is not defined.
*
* @param p1
* the first param with type P1
* @param p2
* the second param with type P2
* @param fallback
* the function to be called when an {@link RuntimeException} caught
* @return the result of this function or the fallback function application
*/
public R applyOrElse(P1 p1, P2 p2, F2 super P1, ? super P2, ? extends R> fallback) {
try {
return apply(p1, p2);
} catch (RuntimeException e) {
return fallback.apply(p1, p2);
}
}
public final F0 curry(final P1 p1, final P2 p2) {
final F2 me = this;
return new F0() {
@Override
public R apply() {
return me.apply(p1, p2);
}
};
}
public final F1 curry(final P2 p2) {
final F2 me = this;
return new F1() {
@Override
public R apply(P1 p1) {
return me.apply(p1, p2);
}
};
}
/**
* Returns a composed function from this function and the specified function that takes the
* result of this function. When applying the composed function, this function is applied
* first to given parameter and then the specified function is applied to the result of
* this function.
*
* @param f
* the function takes the R
type parameter and return T
* type result
* @param
* the return type of function {@code f}
* @return the composed function
* @throws NullPointerException
* if f
is null
*/
public F2 andThen(final Function super R, ? extends T> f) {
E.NPE(f);
final Func2 me = this;
return new F2() {
@Override
public T apply(P1 p1, P2 p2) {
R r = me.apply(p1, p2);
return f.apply(r);
}
};
}
/**
* Returns a composed function that applied, in sequence, this function and
* all functions specified one by one. If applying anyone of the functions
* throws an exception, it is relayed to the caller of the composed function.
* If an exception is thrown out, the following functions will not be applied.
* When apply the composed function, the result of the last function
* is returned
*
* @param fs
* a sequence of function to be applied after this function
* @return a composed function
*/
public F2 andThen(final Func2 super P1, ? super P2, ? extends R>... fs) {
if (0 == fs.length) {
return this;
}
final Func2 me = this;
return new F2() {
@Override
public R apply(P1 p1, P2 p2) {
R r = me.apply(p1, p2);
for (Func2 super P1, ? super P2, ? extends R> f : fs) {
r = f.apply(p1, p2);
}
return r;
}
};
}
/**
* Returns a composed function that when applied, try to apply this function first, in case
* a {@link NotAppliedException} is captured apply to the fallback function specified. This
* method helps to implement partial function
*
* @param fallback
* the function to applied if this function doesn't apply to the parameter(s)
* @return the composed function
*/
public F2 orElse(final Func2 super P1, ? super P2, ? extends R> fallback) {
final F2 me = this;
return new F2() {
@Override
public R apply(P1 p1, P2 p2) {
try {
return me.apply(p1, p2);
} catch (RuntimeException e) {
return fallback.apply(p1, p2);
}
}
};
}
/**
* Turns this partial function into a plain function returning an Option result.
*
* @return a function that takes an argument x to Some(this.apply(x)) if this can be applied, and to None otherwise.
*/
public F2> lift() {
final F2 me = this;
return new F2>() {
@Override
public Option apply(P1 p1, P2 p2) {
try {
return some(me.apply(p1, p2));
} catch (RuntimeException e) {
return none();
}
}
};
}
}
private static class DumbF2 extends F2 implements Serializable {
private static final long serialVersionUID = 2856835860952L;
@Override
public Object apply(Object o, Object o2) throws NotAppliedException, Break {
return null;
}
}
/**
* A dumb {@link Func2} implementation that does nothing and return null
*
* @see #f2()
* @since 0.2
*/
public static final F2 F2 = new DumbF2();
/**
* The type-safe version of {@link #F2}
*
* @param
* the type of the first param the new function applied to
* @param
* the type of the second param the new function applied to
* @param
* the type of new function application result
* @return the dumb function {@link #F2}
* @since 0.2
*/
@SuppressWarnings("unchecked")
public static F2 f2() {
return (F2) F2;
}
/**
* Convert a general {@link Func2} function into a {@link F2} typed
* function
*
* @param f2
* the function that takes two arguments and return type {@code R}
* @param
* the type of the first param the new function applied to
* @param
* the type of the second param the new function applied to
* @param
* the type of new function application result
* @return a {@code F2} instance corresponding to the specified {@code Func2} instance
* @since 0.2
*/
@SuppressWarnings("unchecked")
public static F2 f2(final Func2 super P1, ? super P2, ? extends R> f2) {
E.NPE(f2);
if (f2 instanceof F2) {
return (F2) f2;
}
return new F2() {
@Override
public R apply(P1 p1, P2 p2) {
return f2.apply(p1, p2);
}
};
}
/**
* Define a function structure that accept three parameter
*
* @param
* the type of first parameter this function applied to
* @param
* the type of second parameter this function applied to
* @param
* the type of thrid parameter this function applied to
* @param
* the type of the return value when this function applied to the parameter(s)
* @see Func0
* @see Function
* @see Func2
* @see Func4
* @see Func5
* @since 0.2
*/
public interface Func3 {
/**
* Run the function with parameters specified.
* In case implementing a partial function, it can throw out an
* {@link NotAppliedException} if the function is not defined for
* the given parameter(s)
*
* @param p1
* argument 1
* @param p2
* argument 2
* @param p3
* argument 3
* @return the result of function applied
* @throws NotAppliedException
* if the function doesn't apply to the parameter(s)
* @throws Break
* to short cut collecting operations (fold/reduce) on an {@link org.osgl.util.C.Traversable container}
*/
R apply(P1 p1, P2 p2, P3 p3) throws NotAppliedException, Break;
}
/**
* Base implementation of {@link Func3} function. User application should
* (nearly) always make their implementation extend to this base class
* instead of implement {@link Func3} directly
*
* @since 0.2
*/
public static abstract class F3
extends FuncBase
implements Func3 {
/**
* Applies this partial function to the given argument when it is contained in the function domain.
* Applies fallback function where this partial function is not defined.
*
* @param p1
* the first argument
* @param p2
* the second argument
* @param p3
* the third argument
* @param fallback
* the function to be called of application of this function failed with any runtime exception
* @return the result of this function or the fallback function application
*/
public R applyOrElse(P1 p1, P2 p2, P3 p3, F3 super P1, ? super P2, ? super P3, ? extends R> fallback) {
try {
return apply(p1, p2, p3);
} catch (RuntimeException e) {
return fallback.apply(p1, p2, p3);
}
}
public final F0 curry(final P1 p1, final P2 p2, final P3 p3) {
final F3 me = this;
return new F0() {
@Override
public R apply() {
return me.apply(p1, p2, p3);
}
};
}
public final F1 curry(final P2 p2, final P3 p3) {
final F3 me = this;
return new F1() {
@Override
public R apply(P1 p1) {
return me.apply(p1, p2, p3);
}
};
}
public final F2 curry(final P3 p3) {
final F3 me = this;
return new F2() {
@Override
public R apply(P1 p1, P2 p2) {
return me.apply(p1, p2, p3);
}
};
}
/**
* Returns a composed function from this function and the specified function that takes the
* result of this function. When applying the composed function, this function is applied
* first to given parameter and then the specified function is applied to the result of
* this function.
*
* @param f
* the function takes the R
type parameter and return T
* type result
* @param
* the return type of function {@code f}
* @return the composed function
* @throws NullPointerException
* if f
is null
*/
public Func3 andThen(final Function super R, ? extends T> f) {
E.NPE(f);
final Func3 me = this;
return new F3() {
@Override
public T apply(P1 p1, P2 p2, P3 p3) {
R r = me.apply(p1, p2, p3);
return f.apply(r);
}
};
}
/**
* Returns a composed function that applied, in sequence, this function and
* all functions specified one by one. If applying anyone of the functions
* throws an exception, it is relayed to the caller of the composed function.
* If an exception is thrown out, the following functions will not be applied.
* When apply the composed function, the result of the last function
* is returned
*
* @param fs
* a sequence of function to be applied after this function
* @return a composed function
*/
public Func3 andThen(
final Func3 super P1, ? super P2, ? super P3, ? extends R>... fs
) {
if (0 == fs.length) {
return this;
}
final Func3 me = this;
return new F3() {
@Override
public R apply(P1 p1, P2 p2, P3 p3) {
R r = me.apply(p1, p2, p3);
for (Func3 super P1, ? super P2, ? super P3, ? extends R> f : fs) {
r = f.apply(p1, p2, p3);
}
return r;
}
};
}
/**
* Returns a composed function that when applied, try to apply this function first, in case
* a {@link NotAppliedException} is captured apply to the fallback function specified. This
* method helps to implement partial function
*
* @param fallback
* the function to applied if this function doesn't apply to the parameter(s)
* @return the composed function
*/
public F3 orElse(final Func3 super P1, ? super P2, ? super P3, ? extends R> fallback) {
final F3 me = this;
return new F3() {
@Override
public R apply(P1 p1, P2 p2, P3 p3) {
try {
return me.apply(p1, p2, p3);
} catch (RuntimeException e) {
return fallback.apply(p1, p2, p3);
}
}
};
}
/**
* Turns this partial function into a plain function returning an Option result.
*
* @return a function that takes an argument x to Some(this.apply(x)) if this can be applied, and to None otherwise.
*/
public F3> lift() {
final F3 me = this;
return new F3>() {
@Override
public Option apply(P1 p1, P2 p2, P3 p3) {
try {
return some(me.apply(p1, p2, p3));
} catch (RuntimeException e) {
return none();
}
}
};
}
}
private static class DumbF3 extends F3 implements Serializable {
private static final long serialVersionUID = 2856835860953L;
@Override
public Object apply(Object o, Object o2, Object o3) throws NotAppliedException, Break {
return null;
}
}
/**
* A dumb {@link Func3} implementation that does nothing and return null
*
* @see #f3()
* @since 0.2
*/
public static final F3 F3 = new DumbF3();
/**
* The type-safe version of {@link #F3}
*
* @param
* the type of first parameter this function applied to
* @param
* the type of second parameter this function applied to
* @param
* the type of thrid parameter this function applied to
* @param
* the type of the return value when this function applied to the parameter(s)
* @return the dumb function {@link #F3}
* @since 0.2
*/
@SuppressWarnings({"unchecked", "unused"})
public static F3 f3() {
return F3;
}
/**
* Convert a general {@link Func3} function into a {@link F3} typed
* function
*
* @param f3
* the general function with three params
* @param
* type of argument 1
* @param
* type of argument 2
* @param
* type of argument 3
* @param
* return type
* @return the {@link #F3} typed instance which is equivalent to f3
* @since 0.2
*/
@SuppressWarnings("unchecked")
public static F3 f3(final Func3 super P1, ? super P2, ? super P3, ? extends R> f3
) {
E.NPE(f3);
if (f3 instanceof F3) {
return (F3) f3;
}
return new F3() {
@Override
public R apply(P1 p1, P2 p2, P3 p3) {
return f3.apply(p1, p2, p3);
}
};
}
/**
* Define a function structure that accept four parameter
*
* @param
* the type of first parameter this function applied to
* @param
* the type of second parameter this function applied to
* @param
* the type of thrid parameter this function applied to
* @param
* the type of fourth parameter this function applied to
* @param
* the type of the return value when this function applied to the parameter(s)
* @see Func0
* @see Function
* @see Func2
* @see Func4
* @see Func5
* @since 0.2
*/
public interface Func4 {
/**
* Run the function with parameters specified.
* In case implementing a partial function, it can throw out an
* {@link NotAppliedException} if the function is not defined for
* the given parameter(s)
*
* @param p1
* the first argument
* @param p2
* the second argument
* @param p3
* the third argument
* @param p4
* the fourth argument
* @return whatever value of type {@code R}
* @throws NotAppliedException
* if the function doesn't apply to the parameter(s)
* @throws Break
* to short cut collecting operations (fold/reduce) on an {@link org.osgl.util.C.Traversable container}
*/
R apply(P1 p1, P2 p2, P3 p3, P4 p4) throws NotAppliedException, Break;
}
/**
* Base implementation of {@link Func4} function. User application should
* (nearly) always make their implementation extend to this base class
* instead of implement {@link Func4} directly
*
* @since 0.2
*/
public static abstract class F4
extends FuncBase
implements Func4 {
/**
* Applies this partial function to the given argument when it is contained in the function domain.
* Applies fallback function where this partial function is not defined.
*
* @param p1
* the first argument
* @param p2
* the second argument
* @param p3
* the third argument
* @param p4
* the fourth argument
* @param fallback
* the failover function to be called if application of this function failed with any
* runtime exception
* @return a composite function that apply to this function first and if failed apply to the callback function
*/
public R applyOrElse(P1 p1, P2 p2, P3 p3, P4 p4,
F4 super P1, ? super P2, ? super P3, ? super P4, ? extends R> fallback
) {
try {
return apply(p1, p2, p3, p4);
} catch (RuntimeException e) {
return fallback.apply(p1, p2, p3, p4);
}
}
public final F0 curry(final P1 p1, final P2 p2, final P3 p3, final P4 p4) {
final F4 me = this;
return new F0() {
@Override
public R apply() {
return me.apply(p1, p2, p3, p4);
}
};
}
public final F1 curry(final P2 p2, final P3 p3, final P4 p4) {
final F4 me = this;
return new F1() {
@Override
public R apply(P1 p1) {
return me.apply(p1, p2, p3, p4);
}
};
}
public final F2 curry(final P3 p3, final P4 p4) {
final F4 me = this;
return new F2() {
@Override
public R apply(P1 p1, P2 p2) {
return me.apply(p1, p2, p3, p4);
}
};
}
public final F3 curry(final P4 p4) {
final F4 me = this;
return new F3() {
@Override
public R apply(P1 p1, P2 p2, P3 p3) {
return me.apply(p1, p2, p3, p4);
}
};
}
/**
* Returns a composed function from this function and the specified function that takes the
* result of this function. When applying the composed function, this function is applied
* first to given parameter and then the specified function is applied to the result of
* this function.
*
* @param f
* the function takes the R
type parameter and return T
* type result
* @param
* the return type of function {@code f}
* @return the composed function
* @throws NullPointerException
* if f
is null
*/
public F4 andThen(final Function super R, ? extends T> f) {
E.NPE(f);
final Func4