001package io.freefair.spring.okhttp.client;
002
003import okhttp3.MediaType;
004import okhttp3.RequestBody;
005import okio.BufferedSink;
006import okio.Okio;
007import org.springframework.core.io.ByteArrayResource;
008import org.springframework.core.io.FileSystemResource;
009import org.springframework.core.io.InputStreamResource;
010import org.springframework.core.io.Resource;
011import org.springframework.lang.Nullable;
012import org.springframework.util.MimeType;
013
014import java.io.IOException;
015import java.io.InputStream;
016
017/**
018 * @author Lars Grefer
019 */
020public class ResourceRequestBody extends RequestBody {
021
022    private final Resource resource;
023
024    @Nullable
025    private final MediaType mediaType;
026
027    public ResourceRequestBody(Resource resource) {
028        this.resource = resource;
029        this.mediaType = null;
030    }
031
032    public ResourceRequestBody(Resource resource, MimeType springMimeType) {
033        this.resource = resource;
034        this.mediaType = MediaType.parse(springMimeType.toString());
035    }
036
037    public ResourceRequestBody(Resource resource, MediaType okhttpMediaType) {
038        this.resource = resource;
039        this.mediaType = okhttpMediaType;
040    }
041
042    @Override
043    @Nullable
044    public MediaType contentType() {
045        return mediaType;
046    }
047
048    @Override
049    public void writeTo(BufferedSink bufferedSink) throws IOException {
050        try (InputStream inputStream = resource.getInputStream()) {
051            bufferedSink.writeAll(Okio.source(inputStream));
052        }
053    }
054
055    @Override
056    public long contentLength() throws IOException {
057        if (resource instanceof InputStreamResource && resource.getClass().equals(InputStreamResource.class)) {
058            return -1;
059        }
060        return resource.contentLength();
061    }
062
063    @Override
064    public boolean isOneShot() {
065        if (resource instanceof InputStreamResource) {
066            return true;
067        }
068
069        if (resource instanceof ByteArrayResource) {
070            return false;
071        }
072
073        if (resource instanceof FileSystemResource) {
074            return false;
075        }
076
077        return super.isOneShot();
078    }
079}