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