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

com.gs.api.accelrx.web.client.request.MultipartFormBodyImpl Maven / Gradle / Ivy

The newest version!
package com.gs.api.accelrx.web.client.request;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.gs.api.accelrx.MultipartFormBody;
import com.gs.api.accelrx.web.api.FileUpload;
import io.reactivex.rxjava3.core.Observable;

import java.util.List;
import java.util.Map;

public class MultipartFormBodyImpl implements MultipartFormBody {
    private static final String DELIMITER = "--";
    private static final String CONTENT_DISPOSITION_HEADER = "Content-Disposition";
    private static final String APPLICATION_JSON_UTF8 = "application/json; charset=utf-8";
    private static final ObjectMapper objectMapper = new ObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_NULL);

    private final List fieldOrder = Lists.newArrayList();
    private final Map properties = Maps.newHashMap();
    private final Map paramArgs = Maps.newHashMap();

    public enum PropertyType {FILE, OBJECT, VALUE}

    @Override
    public Observable getBody(String boundary) {
        Observable buffer = fieldOrder.stream()
                .filter(field -> paramArgs.get(field) != null)
                .map(field -> {
                    PropertyType propertyType = properties.get(field);
                    Object paramValue = paramArgs.get(field);

                    if (propertyType == PropertyType.FILE) {
                        FileUpload fileUpload = (FileUpload) paramValue;
                        return filePart(field, fileUpload, boundary);
                    }

                    if (propertyType == PropertyType.OBJECT) {
                        String payloadAsString;

                        try {
                            payloadAsString = objectMapper.writeValueAsString(paramValue);
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                            throw new RuntimeException(e);
                        }

                        return objectPart(field, payloadAsString, boundary);
                    }

                    return propertyPart(field, String.valueOf(paramValue), boundary);
                }).reduce(Observable.empty(), Observable::concatWith);

        buffer = closingBoundary(buffer, boundary);
        return buffer;
    }

    public MultipartFormBodyImpl withProperty(String name, Object arg) {
        fieldOrder.add(name);
        paramArgs.put(name, arg);
        properties.put(name, PropertyType.VALUE);
        return this;
    }

    public MultipartFormBodyImpl withObject(String name, Object obj) {
        fieldOrder.add(name);
        paramArgs.put(name, obj);
        properties.put(name, PropertyType.OBJECT);
        return this;
    }

    public MultipartFormBodyImpl withFile(String name, Object file) {
        fieldOrder.add(name);
        paramArgs.put(name, file);
        properties.put(name, PropertyType.FILE);
        return this;
    }

    private Observable propertyPart(String key, String property, String boundary) {
        Observable buffer = boundary(Observable.empty(), boundary);
        buffer = propertyContentDisposition(buffer, key);
        buffer = blankLine(buffer);
        buffer = line(buffer, property);
        return buffer;
    }

    private Observable objectPart(String key, String payload, String boundary) {
        Observable buffer = boundary(Observable.empty(), boundary);
        buffer = propertyContentDisposition(buffer, key);
        buffer = contentTypeHeader(buffer, APPLICATION_JSON_UTF8);
        buffer = blankLine(buffer);
        buffer = line(buffer, payload);
        return buffer;
    }

    private Observable filePart(String key, FileUpload fileUpload, String boundary) {
        Observable buffer = boundary(Observable.empty(), boundary);
        buffer = fileContentDisposition(buffer, key, fileUpload.getFileName());
        buffer = contentTypeHeader(buffer, fileUpload.getContentType());
        buffer = blankLine(buffer);
        buffer = file(buffer, fileUpload.getFile());
        buffer = blankLine(buffer);
        return buffer;
    }

    private Observable line(Observable buffer, String str) {
        return buffer.concatWith(Observable.just((str + "\r\n").getBytes()));
    }

    private Observable boundary(Observable buffer, String boundary) {
        return line(buffer, DELIMITER + boundary);
    }

    private Observable closingBoundary(Observable buffer, String boundary) {
        return line(buffer, DELIMITER + boundary + DELIMITER);
    }

    private Observable blankLine(Observable buffer) {
        return line(buffer, "");
    }

    private Observable contentTypeHeader(Observable buffer, String contentType) {
        return line(buffer, String.format("Content-Type" + ": %s", contentType));
    }

    private Observable fileContentDisposition(Observable buffer, String key, String fileName) {
        return line(buffer, String.format(CONTENT_DISPOSITION_HEADER + ": form-data; name=\"%s\"; filename=\"%s\"", key, fileName));
    }

    private Observable propertyContentDisposition(Observable buffer, String key) {
        return line(buffer, String.format(CONTENT_DISPOSITION_HEADER + ": form-data; name=\"%s\"", key));
    }

    private Observable file(Observable buffer, Observable file) {
        return buffer.concatWith(file);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy