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

zaber.motion.gateway.Call Maven / Gradle / Ivy

Go to download

A library that aims to provide easy-to-use API for communication with Zaber devices using Zaber ASCII Protocol.

There is a newer version: 6.7.0
Show newest version
package zaber.motion.gateway;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Parser;
import com.sun.jna.Pointer;
import zaber.motion.exceptions.MotionLibException;
import zaber.motion.gateway.GoLibraryLoader.NativeLibrary;
import zaber.motion.exceptions.LibraryIntegrationException;
import zaber.motion.protobufs.Main.Request;
import zaber.motion.protobufs.Main.Response;
import zaber.motion.exceptions.ExceptionConverter;

public final class Call {

    private Call() {
    }

    private static Set garbageCollectorProtector = Collections.synchronizedSet(new HashSet<>());

    public static  T callSync(String request, Message requestData,
                                                 Parser parser) throws MotionLibException {
        Request.Builder builder = Request.newBuilder().setRequest(request);
        Request genRequest = builder.build();

        List messages = new ArrayList();
        messages.add(genRequest.toByteArray());
        if (requestData != null) {
            messages.add(requestData.toByteArray());
        }

        byte[] data = Serialization.serialize(messages);

        List rawResponse = new ArrayList<>(1);

        NativeLibrary.Func callbackSync = new NativeLibrary.Func() {
            @Override
            @SuppressWarnings("checkstyle:magicnumber")
            public void invoke(Pointer response) {
                byte[] sizeArray = response.getByteArray(0, Serialization.SIZE_TYPE_SIZE);
                int size = Serialization.getSizeFromByteArrayLE(sizeArray, 0);
                rawResponse.add(response.getByteArray(0, size));
            }
        };

        int result = NativeLibrary.INSTANCE.call(data, (long) 0, callbackSync, (char) 0);

        if (result != 0) {
            throw new LibraryIntegrationException("Invalid result code: " + result);
        }

        List responses = Serialization.deserialize(rawResponse.get(0));

        return parseResponse(responses, parser);
    }

    public static  CompletableFuture callAsync(String request, Message requestData,
                                                                     Parser parser) throws MotionLibException {
        Request.Builder builder = Request.newBuilder().setRequest(request);
        Request genRequest = builder.build();

        List messages = new ArrayList();
        messages.add(genRequest.toByteArray());
        if (requestData != null) {
            messages.add(requestData.toByteArray());
        }

        byte[] data = Serialization.serialize(messages);

        CompletableFuture future = new CompletableFuture<>();

        NativeLibrary.Func callbackAsync = new NativeLibrary.Func() {
            @Override
            @SuppressWarnings("checkstyle:magicnumber")
            public void invoke(Pointer response) {
                byte[] sizeArray = response.getByteArray(0, Serialization.SIZE_TYPE_SIZE);
                int size = Serialization.getSizeFromByteArrayLE(sizeArray, 0);
                future.complete(response.getByteArray(0, size));
            }
        };

        garbageCollectorProtector.add(callbackAsync);

        int result = NativeLibrary.INSTANCE.call(data, (long) 0, callbackAsync, (char) 1);

        if (result != 0) {
            throw new LibraryIntegrationException("Invalid result code: " + result);
        }

        return future.thenApply(rawResponse -> {
            garbageCollectorProtector.remove(callbackAsync);

            List rawResponses = Serialization.deserialize(rawResponse);
            try {
                return parseResponse(rawResponses, parser);
            } catch (MotionLibException e) {
                throw new CompletionException(e);
            }
        });
    }

    private static  T parseResponse(List messages, Parser parser)
                                                       throws MotionLibException {
        try {
            Response response = Response.parseFrom(messages.get(0));

            if (response.getResponse() != Response.ResponseType.OK) {
                if (messages.size() > 1) {
                    throw ExceptionConverter.convert(response.getErrorType(), response.getErrorMessage(), messages.get(1));
                }
                throw ExceptionConverter.convert(response.getErrorType(), response.getErrorMessage());
            }
            if (parser != null && messages.size() == 1) {
                throw new LibraryIntegrationException("No response from library");
            }
            if (parser == null && messages.size() > 1) {
                throw new LibraryIntegrationException("Response from library ignored");
            }
            if (parser != null) {
                return parser.parseFrom(messages.get(1));
            }
            return null;
        } catch (InvalidProtocolBufferException e) {
            throw new LibraryIntegrationException("Cannot parse response from library", e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy