dollar.api.DollarStatic.java Source code

Java tutorial

Introduction

Here is the source code for dollar.api.DollarStatic.java

Source

/*
 *    Copyright (c) 2014-2017 Neil Ellis
 *
 *    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.
 */

package dollar.api;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import dollar.api.execution.DollarExecutor;
import dollar.api.json.JsonArray;
import dollar.api.json.JsonObject;
import dollar.api.monitor.DollarMonitor;
import dollar.api.monitor.SimpleLogStateTracer;
import dollar.api.plugin.Plugins;
import dollar.api.script.Source;
import dollar.api.types.DollarFactory;
import dollar.api.uri.URI;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.Function;

public class DollarStatic {

    /**
     * The thread context that all Dollar classes have access to.
     */
    @NotNull
    public static final ThreadLocal<DollarThreadContext> threadContext = ThreadLocal
            .withInitial(DollarThreadContext::new);
    @NotNull
    static final DollarExecutor executor = Objects.requireNonNull(Plugins.sharedInstance(DollarExecutor.class));
    @NotNull
    private static final Logger log = LoggerFactory.getLogger(DollarStatic.class);
    @NotNull
    private static final ExecutorService threadPoolExecutor = Executors.newCachedThreadPool();
    @NotNull
    private static Configuration config = new SystemPropertyConfiguration();

    /**
     * $ Value.
     *
     * @param o the o
     * @return the Value
     */
    @NotNull
    public static Value $(@Nullable Object o) {
        return $(o, false);
    }

    @NotNull
    private static Value $(@Nullable Object o, boolean parallel) {
        return DollarFactory.fromValue(o);
    }

    /**
     * $ Value.
     *
     * @param values the values
     * @return the Value
     */
    @NotNull
    public static Value $(@NotNull Value... values) {
        return $map(values);
    }

    /**
     * $ Value.
     *
     * @return the Value
     */
    @NotNull
    public static Value $() {
        return DollarFactory.fromValue();
    }

    /**
     * $ Value.
     *
     * @param name   the name
     * @param values the values
     * @return the Value
     */
    @NotNull
    public static Value $(@NotNull String name, @NotNull Value... values) {
        Value v = $();
        for (Value value : values) {
            v = v.$plus(value);
        }
        return $(name, v);
    }

    /**
     * $ Value.
     *
     * @param name the name
     * @param o    the o
     * @return the Value
     */
    @NotNull
    public static Value $(@NotNull Object name, @NotNull Object o) {
        if ((name instanceof Value) && (o instanceof Value)) {
            if (((Value) name).map()) {
                return ((Value) name).$plus((Value) o);

            }
        }
        return DollarFactory.fromPair(name, o);
    }

    /**
     * $ Value.
     *
     * @param json the json
     * @return the Value
     */
    @NotNull
    public static Value $(@NotNull JsonObject json) {
        return DollarFactory.fromValue(json);
    }

    /**
     * $ Value.
     *
     * @param lambda the lambda
     * @return the Value
     */
    @NotNull
    public static Value $(@NotNull Pipeable lambda) {
        return DollarFactory.fromValue(lambda);
    }

    @NotNull
    public static Value $and(@NotNull Value lhs, @NotNull Value rhs) {
        return $(lhs.isTrue() && rhs.isTrue());
    }

    public static Value $blockingQueue() {
        return DollarFactory.fromQueue(new LinkedBlockingDeque<>());
    }

    /**
     * The beginning of any Dollar Code should start with a DollarStatic.run/call method. This creates an identifier
     * used to link context's together.
     *
     * @param context the current thread context
     * @param call    the lambda to run.
     * @return the Value
     */
    @NotNull
    public static Value $call(@NotNull DollarThreadContext context, @NotNull Callable<Value> call) {
        threadContext.set(context.child());
        try {
            return call.call();
        } catch (Exception e) {
            return handleError(e, null);
        } finally {
            threadContext.remove();
        }
    }

    /**
     * $ date.
     *
     * @param date the date
     * @return the Value
     */
    @NotNull
    public static Value $date(@NotNull Date date) {
        return DollarFactory.fromValue(date);
    }

    /**
     * $ date.
     *
     * @param date the date
     * @return the Value
     */
    @NotNull
    public static Value $date(@NotNull LocalDateTime date) {
        return DollarFactory.fromValue(date);
    }

    @NotNull
    public static Value $debug(@NotNull Value v) {
        v.debug();
        return $void();
    }

    /**
     * $ dump.
     */
    public static void $dump() {
        threadContext.get().monitor().dump();
    }

    /**
     * $ dump thread.
     */
    public static void $dumpThread() {
        threadContext.get().monitor().dumpThread();
    }

    /**
     * $ end.
     *
     * @param value the value
     */
    public static void $end(@NotNull String value) {
        threadContext.get().popLabel(value);
    }

    @NotNull
    public static Value $err(@NotNull Value v) {
        v.err();
        return $void();
    }

    /**
     * $ fork.
     *
     * @param source the source
     * @param in     the in
     * @param call   the call
     * @return the Value
     */
    @NotNull
    public static Value $fork(@NotNull Source source, @NotNull Value in, @NotNull Function<Value, Value> call) {
        return executor.fork(source, in, call);
    }

    @NotNull
    public static Value $gt(@NotNull Value lhs, @NotNull Value rhs) {
        return $(lhs.compareTo(rhs) > 0);
    }

    @NotNull
    public static Value $gte(@NotNull Value lhs, @NotNull Value rhs) {
        return $(lhs.compareTo(rhs) >= 0);
    }

    @NotNull
    public static Value $json(@NotNull String json) {
        if (json.matches("^\\s*\\{.*")) {
            return $(new JsonObject(json));
        } else if (json.matches("^\\s*\\[.*")) {
            return $(new JsonArray(json));
        } else if (json.matches("^\\s*\".*\"")) {
            return $string(json.substring(1, json.length() - 1));
        } else if (json.matches("^\\s*[0-9+-]+\\s*$")) {
            return $(Integer.parseInt(json));
        } else if (json.matches("^\\s*[0-9+-.eE]+\\s*$")) {
            return $(Double.parseDouble(json));
        } else {
            throw new DollarException("Could not parse as json: " + json);
        }
    }

    /**
     * $ json array.
     *
     * @param values the values
     * @return the json array
     */
    @NotNull
    public static JsonArray $jsonArray(@NotNull Object... values) {
        return new JsonArray(values);
    }

    /**
     * $ list.
     *
     * @param values the values
     * @return the Value
     */
    @NotNull

    public static Value $list(@NotNull Object... values) {
        return DollarFactory.fromValue(values);
    }

    @NotNull
    public static Value $lt(@NotNull Value lhs, @NotNull Value rhs) {
        return $(lhs.compareTo(rhs) < 0);
    }

    @NotNull
    public static Value $lte(@NotNull Value lhs, @NotNull Value rhs) {
        return $(lhs.compareTo(rhs) <= 0);
    }

    @NotNull
    public static Value $map(@NotNull Value... values) {
        Value v = $();
        for (Value value : values) {
            v = v.$plus(value);
        }
        return v;
    }

    @NotNull
    public static Value $not(@NotNull Value v) {
        return $(!v.isTrue());
    }

    @NotNull
    public static Value $null(@NotNull Type type) {
        return DollarFactory.newNull(type);
    }

    @NotNull
    public static Value $or(@NotNull Value lhs, @NotNull Value rhs) {
        return $(lhs.isTrue() || rhs.isTrue());
    }

    @NotNull
    public static Value $out(@NotNull Value v) {
        v.out();
        return $void();
    }

    /**
     * $ range.
     *
     * @param from the from
     * @param to   the to
     * @return the Value
     */
    @NotNull
    public static Value $range(@NotNull Value from, @NotNull Value to) {
        return DollarFactory.fromRange(from, to);
    }

    /**
     * $ range.
     *
     * @param from the from
     * @param to   the to
     * @return the Value
     */
    @NotNull
    public static Value $range(long from, long to) {
        return DollarFactory.fromRange(DollarStatic.$(from), DollarStatic.$(to));
    }

    /**
     * $ range.
     *
     * @param from the from
     * @param to   the to
     * @return the Value
     */
    @NotNull
    public static Value $range(double from, double to) {
        return DollarFactory.fromRange($(from), $(to));
    }

    /**
     * $ range.
     *
     * @param from the from
     * @param to   the to
     * @return the Value
     */
    @NotNull
    public static Value $range(@NotNull String from, @NotNull String to) {
        return DollarFactory.fromRange($(from), $(to));
    }

    /**
     * $ range.
     *
     * @param from the from
     * @param to   the to
     * @return the Value
     */
    @NotNull
    public static Value $range(@NotNull Date from, @NotNull Date to) {
        return DollarFactory.fromRange($(from), $(to));
    }

    /**
     * $ range.
     *
     * @param from the from
     * @param to   the to
     * @return the Value
     */
    @NotNull
    public static Value $range(@NotNull LocalDateTime from, @NotNull LocalDateTime to) {
        return DollarFactory.fromRange($(from), $(to));
    }

    /**
     * $ range.
     *
     * @param from the from
     * @param to   the to
     * @return the Value
     */
    @NotNull
    public static Value $range(@NotNull Instant from, @NotNull Instant to) {
        return DollarFactory.fromRange($(from), $(to));
    }

    /**
     * The beginning of any Dollar Code should start with a DollarStatic.run method.
     *
     * @param context this is an identifier used to link context's together, it should be unique to the request being
     *                processed.
     * @param run     the lambda to run.
     */
    public static void $run(@NotNull DollarThreadContext context, @NotNull Runnable run) {
        threadContext.set(context.child());
        try {
            run.run();
        } finally {
            threadContext.remove();
        }
    }

    /**
     * The beginning of any new Dollar Code should start with a DollarStatic.run/call method. This creates an object
     * used to link context's together.
     *
     * @param run the lambda to run.
     */
    static void $run(@NotNull Runnable run) {
        try {
            run.run();
        } finally {
            threadContext.remove();
        }
    }

    public static Value $string(@NotNull String s) {
        return DollarFactory.fromStringValue(s);
    }

    @NotNull
    public static Value $truthy(@NotNull Value v) {
        return $(v.truthy());
    }

    /**
     * $ uri.
     *
     * @param uri the uri
     * @return the Value
     */
    @NotNull
    public static Value $uri(@NotNull URI uri) {
        return DollarFactory.fromValue(uri);
    }

    /**
     * $ uri.
     *
     * @param uri the uri
     * @return the Value
     */
    @NotNull
    public static Value $uri(@NotNull String uri) {
        return DollarFactory.fromValue(URI.parse(uri));
    }

    /**
     * $ void.
     *
     * @return the Value
     */
    @NotNull
    public static Value $void() {
        return DollarFactory.newVoid();
    }

    /**
     * Creates a Value from a YAML formatted string as a Value
     *
     * @param yaml the YAML
     * @return a Value
     */
    @NotNull
    public static Value $yaml(@NotNull Value yaml) {
        return DollarFactory.fromYaml(yaml.toString());
    }

    /**
     * Creates a Value from a YAML file
     *
     * @param yamlFile the YAML as a file
     * @return a Value
     */
    @NotNull
    public static Value $yaml(@NotNull File yamlFile) {
        return DollarFactory.fromYaml(yamlFile);
    }

    /**
     * Creates a Value from YAML
     *
     * @param yaml the YAML
     * @return a Value
     */
    @NotNull
    public static Value $yaml(@NotNull String yaml) {
        return DollarFactory.fromYaml(yaml);
    }

    /**
     * Child context.
     *
     * @return the dollar thread context
     */
    @NotNull
    public static DollarThreadContext childContext() {
        return threadContext.get().child();
    }

    /**
     * Child context.
     *
     * @param s the s
     * @return the dollar thread context
     */
    @NotNull
    public static DollarThreadContext childContext(@NotNull String s) {
        return threadContext.get().child(s);
    }

    /**
     * Context dollar thread context.
     *
     * @return the dollar thread context
     */
    @NotNull
    public static DollarThreadContext context() {
        return threadContext.get();
    }

    /**
     * Create Value.
     *
     * @return the Value
     */
    @NotNull
    public static Value create() {
        return $();
    }

    /**
     * Create Value.
     *
     * @param value the value
     * @return the Value
     */
    @NotNull
    public static Value create(@NotNull Object value) {
        return $(value);
    }

    /**
     * Fix Value.
     *
     * @param v        the v
     * @param parallel the parallel
     * @return the Value
     */
    @NotNull
    public static Value fix(@Nullable Value v, boolean parallel) {
        return (v != null) ? DollarFactory.wrap(v.$fix(parallel)) : $void();
    }

    /**
     * Fix, i.e. evaluate lambdas to the depth supplied, optionally hinting that parallel behaviour is fine
     *
     * @param v        the object to be fixed
     * @param depth    the depth at which to stop evaluation, 1 means do not penetrate any layers of maps/blocks, 2
     *                 means penetrate one layer of maps.
     * @param parallel if true parallel evaluation if fine
     * @return the 'fixed' Value
     */
    @NotNull
    public static Value fix(@Nullable Value v, int depth, boolean parallel) {
        return (v != null) ? DollarFactory.wrap(v.$fix(depth, parallel)) : $void();
    }

    /**
     * Fix Value.
     *
     * @param v the v
     * @return the Value
     */
    @NotNull
    public static Value fix(@Nullable Value v) {
        return (v != null) ? DollarFactory.wrap(v.$fix(false)) : $void();
    }

    /**
     * Fix deep.
     *
     * @param v the v
     * @return the Value
     */
    @NotNull
    public static Value fixDeep(@Nullable Value v) {
        return (v != null) ? DollarFactory.wrap(v.$fixDeep(false)) : $void();
    }

    /**
     * Fix deep.
     *
     * @param v        the v
     * @param parallel the parallel
     * @return the Value
     */
    @NotNull
    public static Value fixDeep(@Nullable Value v, boolean parallel) {
        return (v != null) ? DollarFactory.wrap(v.$fixDeep(parallel)) : $void();
    }

    /**
     * The shared configuration for Dollar.
     *
     * @return the Configuration
     */
    @NotNull
    public static Configuration getConfig() {
        return config;
    }

    public static void setConfig(@NotNull Configuration config) {
        DollarStatic.config = config;
    }

    /**
     * Handle error.
     *
     * @param throwable the throwable
     * @param failee    the failee
     * @return the Value
     */
    @NotNull
    public static Value handleError(@NotNull Exception throwable, @Nullable Value failee) {
        if (failee == null) {
            return DollarFactory.failure(throwable);
        }
        return failee.$copy(ImmutableList.of(throwable));

    }

    /**
     * Handle interrupt.
     *
     * @param <R> the type parameter
     * @param ie  the ie
     * @return the r
     */
    @NotNull
    public static <R> R handleInterrupt(@NotNull InterruptedException ie) {
        if (Thread.interrupted()) {
            log("Interrupted");
        }
        throw new Error("Interrupted");
    }

    /**
     * Label void.
     *
     * @param label the label
     */
    public static void label(@NotNull String label) {
        context().pushLabel(label);
    }

    /**
     * Log void.
     *
     * @param message the message
     */
    public static void log(@NotNull Object message) {
        log.info("{}:{}", threadContext.get().labels(), message);
    }

    /**
     * Log void.
     *
     * @param message the message
     */
    public static void log(@NotNull String message) {
        log.info("{}:{}", threadContext.get().labels(), message);
    }

    /**
     * Log and rethrow.
     *
     * @param <R>       the type parameter
     * @param throwable the throwable
     * @return the r
     */
    @NotNull
    @Deprecated
    public static <R> R logAndRethrow(@NotNull Exception throwable) {
        if (throwable instanceof DollarException) {
            throw (DollarException) throwable;
        } else {
            throw new DollarException(throwable);
        }

    }

    /**
     * Map to json.
     *
     * @param map the map
     * @return the json object
     */
    @NotNull
    public static JsonObject mapToJson(@NotNull Multimap<String, String> map) {
        JsonObject jsonObject = new JsonObject();
        for (Map.Entry<String, Collection<String>> entry : map.asMap().entrySet()) {
            jsonObject.putString(entry.getKey(), entry.getValue().iterator().next());
        }
        return jsonObject;
    }

    /**
     * Monitor dollar monitor.
     *
     * @return the dollar monitor
     */
    @NotNull
    public static DollarMonitor monitor() {
        return threadContext.get().monitor();
    }

    /**
     * Param map to json.
     *
     * @param map the map
     * @return the json object
     */
    @NotNull
    public static JsonObject paramMapToJson(@NotNull Map<String, String[]> map) {
        JsonObject jsonObject = new JsonObject();
        for (Map.Entry<String, String[]> entry : map.entrySet()) {
            if (entry.getValue().length == 1) {
                jsonObject.putString(entry.getKey(), entry.getValue()[0]);
            } else {
                jsonObject.putArray(entry.getKey(), new JsonArray(entry.getValue()));
            }
        }
        return jsonObject;
    }

    /**
     * Tracer state tracer.
     *
     * @return the state tracer
     */
    @NotNull
    public static StateTracer tracer() {
        return new SimpleLogStateTracer();
    }
}