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

com.radiance.tonclient.TONContext Maven / Gradle / Ivy

The newest version!
package com.radiance.tonclient;

import java.io.*;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.function.BiConsumer;
import java.util.logging.Logger;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.radiance.tonclient.*;

public class TONContext {
    private static Logger log = Logger.getLogger(TONContext.class.getName());
    private class Callback {
        BiConsumer consumer;
        Class clazz;

        Callback(BiConsumer consumer, Class clazz) {
            this.consumer = consumer;
            this.clazz = clazz;
        }

        void invoke(String value, int type) {
            try {
                consumer.accept(jsonMapper.readValue(value, clazz), type);
            } catch (JsonProcessingException e) {
                e.printStackTrace(System.out);
            }
        }
    }

    // natives
    private static native String loadLibrary(String path);
    private static native String createContext(String config);
    private static native void destroyContext(int context);
    private static native void request(int context, String functionName, String params, int requestId);
    private static native String requestSync(int context, String functionName, String params);

    static {
        try {
            String osName = System.getProperty("os.name");
            log.info("OS name: '" + osName + "'");
            osName = osName.toLowerCase();
            String libPath;
            if (osName.indexOf("mac") >= 0 || osName.indexOf("darwin") >= 0)
                libPath = "/libton_client_jni.dylib";
            else if (osName.indexOf("win") >= 0)
                libPath = "/ton_client_jni.dll";
            else    // Linux
                libPath = "/libton_client_jni.so";
            System.load(createTempFile(libPath));
        } catch(IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static String createTempFile(String resourceName) throws IOException {
        InputStream inputStream = TONContext.class.getResourceAsStream(resourceName);
        if (inputStream == null)
            throw new IOException("Cannot find resource '" + resourceName + "'");
        File tempFile = File.createTempFile("TONLibrary", resourceName.substring(resourceName.lastIndexOf('.')));
        FileOutputStream outputStream = new FileOutputStream(tempFile);
        byte[] array = new byte[8192];
        for (int i = inputStream.read(array); i != -1; i = inputStream.read(array)) {
            outputStream.write(array, 0, i);
        }
        inputStream.close();
        outputStream.close();
        tempFile.deleteOnExit();
        log.info("Using '" + tempFile.getAbsolutePath() + "' as '" + resourceName + "'");
        return tempFile.getAbsolutePath();
    }

    private static int requestCount = 0;
    private static HashMap> responses = new HashMap<>();
    private static HashMap> callbacks = new HashMap<>();
    private static HashMap appObjects = new HashMap<>();

    static Number toNumber(String value) {
        if (value.indexOf('.') < 0) {
            if (value.length() > 6)
                return Long.valueOf(value);
            else
                return Integer.valueOf(value);
        } else {
            if (value.length() > 7)
                return Double.valueOf(value);
            else
                return Float.valueOf(value);
        }
    }

    private static void responseHandler(int id, String params, int type, boolean finished) {
        log.info("<= " + id + " " + params + " type=" + type + " finished=" + finished);
        CompletableFuture future;
        Callback callback;
        Object appObject;

        synchronized (responses) {
            future = finished?responses.remove(id):responses.get(id);
            callback = finished?callbacks.remove(id):callbacks.get(id);
            appObject = finished?appObjects.remove(id):appObjects.get(id);
        }
        switch (type) {
            case 0:     // RESULT
                if (future == null) {
                    System.out.println("ResponseId not found " + id);
                } else {
                    future.complete(params);
                }
                break;
            case 1:     // ERROR
                Throwable throwable;
                try {
                    JsonNode error = jsonMapper.readTree(params);
                    throwable = new TONException(Integer.parseInt(error.findValue("code").toString()), error.findValue("message").toString());
                } catch (Throwable t) {
                    throwable = t;
                }
                future.completeExceptionally(throwable);
                break;
            case 2:     // NOP
                if (future != null)
                    future.completeExceptionally(new TONException(0, "No result"));
                break;
            /*
            case 3:
                try {
                    JsonNode json = jsonMapper.readTree(params);
                    JsonNode requ = json.get("request_data");
                    String mName = requ.get("type").asText();
                    mName = Character.toLowerCase(mName.charAt(0)) + mName.substring(1);
                    log.info("-------- " + appObject.getClass() + " " + mName);
                } catch(JsonProcessingException e) {
                    log.severe(e.toString());
                }
                break;
            */
            case 3:
            case 4:
            case 100:   // CUSTOM (Callback)
                if (callback == null) {
                    System.out.println("Callback not found " + id);
                } else {
                    callback.invoke(params, type);
                }
        }
    }

    public static TONContext create(Object config) throws TONException {
        String result = createContext(config==null?"":config.toString());
        log.info("Create context: " + config + " => " + result);
        try {
            JsonNode json = jsonMapper.readTree(result);
            JsonNode error = json.findValue("error");
            if (error != null)
                throw new TONException(Integer.parseInt(error.findValue("code").toString()), error.findValue("message").toString());
            return new TONContext(Integer.valueOf(json.findValue("result").toString()));
        } catch (Throwable t) {
            throw new TONException(t);
        }
    }

    public static  T convertValue(JsonNode json, Class valueType) {
        return jsonMapper.convertValue(json, valueType);
    }

    private int contextId;
    private static ObjectMapper jsonMapper = new ObjectMapper();

    private TONContext(int contextId) {
        this.contextId = contextId;
    }

    public void destroy() {
        if (contextId >= 0) {
            destroyContext(contextId);
            contextId = -1;
        }
    }

    public CompletableFuture request(String functionName, String params) {
        return requestCallback(functionName, params, null, null, null);
    }

    private  CompletableFuture requestCallback(String functionName, String params, BiConsumer consumer, Class clazz, Object appObject) {
        CompletableFuture future;

        synchronized (responses) {
            future = new CompletableFuture<>();
            responses.put(++requestCount, future);
            if (consumer != null) {
                callbacks.put(requestCount, new Callback(consumer,clazz));
                //System.out.println(callbacks);
            }
            if (appObject != null) {
                appObjects.put(requestCount, appObject);
            }
            log.info("=> " + requestCount + " " +functionName + " " + params);
            request(contextId, functionName, params, requestCount);
        }
        return future;
    }

    private  CompletableFuture requestJSONCallback(String functionName, String params, BiConsumer consumer, Class clazz, Object appObject) {
        return requestCallback(functionName, params, consumer, clazz, appObject)
            .thenApply(r -> {
                try {
                    return jsonMapper.readTree(r);
                } catch (JsonProcessingException ex) {
                    throw new CompletionException(ex);
                }
            });
    }

    public  CompletableFuture requestJSONCallback(String functionName, String params, BiConsumer consumer, Class clazz) {
        return requestJSONCallback(functionName, params, consumer, clazz, null);
    }

    public CompletableFuture requestJSON(String functionName, String params) {
        return requestJSONCallback(functionName, params, null, null);
    }

    public CompletableFuture requestJSONAppObject(String functionName, String params, Object appObject) {
        return requestJSONCallback(functionName, params, null, null, appObject);
    }


/*
    public  CompletableFuture requestValue(String functionName, String params, Class valueType) {
        return requestValueCallback(functionName, params, valueType, null, null);
    }

    public  CompletableFuture requestValueCallback(String functionName, String params, Class valueType, Consumer consumer, Class clazz) {
        return requestCallback(functionName, params, consumer, clazz)
            .thenApply(r -> {
                try {
                    return jsonMapper.readValue(r, valueType);
                } catch (JsonProcessingException ex) {
                    throw new CompletionException(ex);
                }
            });
    }
*/
    public static void main(String... args) throws Exception {
        TONContext ctx = TONContext.create("{}");
        Crypto crypto = new Crypto(ctx);

        System.out.println(Arrays.asList(crypto.factorize("EE").get()));
        //ctx.request("client.get_api_reference", "{}");
        System.out.println(ctx.request("client.version", "").get());

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy