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

me.shib.java.lib.jiraclient.RestClient Maven / Gradle / Ivy

package me.shib.java.lib.jiraclient;

import net.sf.json.JSON;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;

/**
 * A simple REST client that speaks JSON.
 */
public class RestClient {

    private HttpClient httpClient = null;
    private ICredentials creds = null;
    private URI uri = null;

    /**
     * Creates a REST client instance with a URI.
     *
     * @param httpclient Underlying HTTP client to use
     * @param uri        Base URI of the remote REST service
     */
    public RestClient(HttpClient httpclient, URI uri) {
        this(httpclient, null, uri);
    }

    /**
     * Creates an authenticated REST client instance with a URI.
     *
     * @param httpclient Underlying HTTP client to use
     * @param creds      Credentials to send with each request
     * @param uri        Base URI of the remote REST service
     */
    public RestClient(HttpClient httpclient, ICredentials creds, URI uri) {
        this.httpClient = httpclient;
        this.creds = creds;
        this.uri = uri;
    }

    /**
     * Build a URI from a path.
     *
     * @param path Path to append to the base URI
     * @return the full URI
     * @throws URISyntaxException when the path is invalid
     */
    public URI buildURI(String path) throws URISyntaxException {
        return buildURI(path, null);
    }

    /**
     * Build a URI from a path and query parmeters.
     *
     * @param path   Path to append to the base URI
     * @param params Map of key value pairs
     * @return the full URI
     * @throws URISyntaxException when the path is invalid
     */
    public URI buildURI(String path, Map params) throws URISyntaxException {
        URIBuilder ub = new URIBuilder(uri);
        ub.setPath(ub.getPath() + path);

        if (params != null) {
            for (Map.Entry ent : params.entrySet())
                ub.addParameter(ent.getKey(), ent.getValue());
        }

        return ub.build();
    }

    private JSON request(HttpRequestBase req) throws RestException, IOException {
        req.addHeader("Accept", "application/json");

        if (creds != null)
            creds.authenticate(req);

        HttpResponse resp = httpClient.execute(req);
        HttpEntity ent = resp.getEntity();
        StringBuilder result = new StringBuilder();

        if (ent != null) {
            String encoding = null;
            if (ent.getContentEncoding() != null) {
                encoding = ent.getContentEncoding().getValue();
            }

            if (encoding == null) {
                Header contentTypeHeader = resp.getFirstHeader("Content-Type");
                HeaderElement[] contentTypeElements = contentTypeHeader.getElements();
                for (HeaderElement he : contentTypeElements) {
                    NameValuePair nvp = he.getParameterByName("charset");
                    if (nvp != null) {
                        encoding = nvp.getValue();
                    }
                }
            }

            InputStreamReader isr = encoding != null ?
                    new InputStreamReader(ent.getContent(), encoding) :
                    new InputStreamReader(ent.getContent());
            BufferedReader br = new BufferedReader(isr);
            String line = "";

            while ((line = br.readLine()) != null) {
                result.append(line);
            }

            isr.close();
            br.close();
            isr = null;
            br = null;
        }
        EntityUtils.consumeQuietly(ent);

        StatusLine sl = resp.getStatusLine();

        if (sl.getStatusCode() >= 300)
            throw new RestException(sl.getReasonPhrase(), sl.getStatusCode(), result.toString(), resp.getAllHeaders());

        return result.length() > 0 ? JSONSerializer.toJSON(result.toString()) : null;
    }

    private JSON request(HttpEntityEnclosingRequestBase req, String payload)
            throws RestException, IOException {

        if (payload != null) {
            StringEntity ent = null;
            ent = new StringEntity(payload, "UTF-8");
            ent.setContentType("application/json");

            req.addHeader("Content-Type", "application/json");
            req.setEntity(ent);
        }

        return request(req);
    }

    private JSON request(HttpEntityEnclosingRequestBase req, File file)
            throws RestException, IOException {
        if (file != null) {
            File fileUpload = file;
            req.setHeader("X-Atlassian-Token", "nocheck");
            MultipartEntity ent = new MultipartEntity();
            ent.addPart("file", new FileBody(fileUpload));
            req.setEntity(ent);
        }
        return request(req);
    }

    private JSON request(HttpEntityEnclosingRequestBase req, Issue.NewAttachment... attachments)
            throws RestException, IOException {
        if (attachments != null) {
            req.setHeader("X-Atlassian-Token", "nocheck");
            MultipartEntity ent = new MultipartEntity();
            for (Issue.NewAttachment attachment : attachments) {
                String filename = attachment.getFilename();
                Object content = attachment.getContent();
                if (content instanceof byte[]) {
                    ent.addPart("file", new ByteArrayBody((byte[]) content, filename));
                } else if (content instanceof InputStream) {
                    ent.addPart("file", new InputStreamBody((InputStream) content, filename));
                } else if (content instanceof File) {
                    ent.addPart("file", new FileBody((File) content, filename));
                } else if (content == null) {
                    throw new IllegalArgumentException("Missing content for the file " + filename);
                } else {
                    throw new IllegalArgumentException(
                            "Expected file type byte[], java.io.InputStream or java.io.File but provided " +
                                    content.getClass().getName() + " for the file " + filename);
                }
            }
            req.setEntity(ent);
        }
        return request(req);
    }

    private JSON request(HttpEntityEnclosingRequestBase req, JSON payload)
            throws RestException, IOException {

        return request(req, payload != null ? payload.toString() : null);
    }

    /**
     * Executes an HTTP DELETE with the given URI.
     *
     * @param uri Full URI of the remote endpoint
     * @return JSON-encoded result or null when there's no content returned
     * @throws RestException when an HTTP-level error occurs
     * @throws IOException   when an error reading the response occurs
     */
    public JSON delete(URI uri) throws RestException, IOException {
        return request(new HttpDelete(uri));
    }

    /**
     * Executes an HTTP DELETE with the given path.
     *
     * @param path Path to be appended to the URI supplied in the construtor
     * @return JSON-encoded result or null when there's no content returned
     * @throws RestException      when an HTTP-level error occurs
     * @throws IOException        when an error reading the response occurs
     * @throws URISyntaxException when an error occurred appending the path to the URI
     */
    public JSON delete(String path) throws RestException, IOException, URISyntaxException {
        return delete(buildURI(path));
    }

    /**
     * Executes an HTTP GET with the given URI.
     *
     * @param uri Full URI of the remote endpoint
     * @return JSON-encoded result or null when there's no content returned
     * @throws RestException when an HTTP-level error occurs
     * @throws IOException   when an error reading the response occurs
     */
    public JSON get(URI uri) throws RestException, IOException {
        return request(new HttpGet(uri));
    }

    /**
     * Executes an HTTP GET with the given path.
     *
     * @param path   Path to be appended to the URI supplied in the construtor
     * @param params Map of key value pairs
     * @return JSON-encoded result or null when there's no content returned
     * @throws RestException      when an HTTP-level error occurs
     * @throws IOException        when an error reading the response occurs
     * @throws URISyntaxException when an error occurred appending the path to the URI
     */
    public JSON get(String path, Map params) throws RestException, IOException, URISyntaxException {
        return get(buildURI(path, params));
    }

    /**
     * Executes an HTTP GET with the given path.
     *
     * @param path Path to be appended to the URI supplied in the construtor
     * @return JSON-encoded result or null when there's no content returned
     * @throws RestException      when an HTTP-level error occurs
     * @throws IOException        when an error reading the response occurs
     * @throws URISyntaxException when an error occurred appending the path to the URI
     */
    public JSON get(String path) throws RestException, IOException, URISyntaxException {
        return get(path, null);
    }


    /**
     * Executes an HTTP POST with the given URI and payload.
     *
     * @param uri     Full URI of the remote endpoint
     * @param payload JSON-encoded data to send to the remote service
     * @return JSON-encoded result or null when there's no content returned
     * @throws RestException when an HTTP-level error occurs
     * @throws IOException   when an error reading the response occurs
     */
    public JSON post(URI uri, JSON payload) throws RestException, IOException {
        return request(new HttpPost(uri), payload);
    }

    /**
     * Executes an HTTP POST with the given URI and payload.
     * 

* At least one JIRA REST endpoint expects malformed JSON. The payload * argument is quoted and sent to the server with the application/json * Content-Type header. You should not use this function when proper JSON * is expected. * * @param uri Full URI of the remote endpoint * @param payload Raw string to send to the remote service * @return JSON-encoded result or null when there's no content returned * @throws RestException when an HTTP-level error occurs * @throws IOException when an error reading the response occurs */ public JSON post(URI uri, String payload) throws RestException, IOException { String quoted = null; if (payload != null && !payload.equals(new JSONObject())) { quoted = String.format("\"%s\"", payload); } return request(new HttpPost(uri), quoted); } /** * Executes an HTTP POST with the given path and payload. * * @param path Path to be appended to the URI supplied in the construtor * @param payload JSON-encoded data to send to the remote service * @return JSON-encoded result or null when there's no content returned * @throws RestException when an HTTP-level error occurs * @throws IOException when an error reading the response occurs * @throws URISyntaxException when an error occurred appending the path to the URI */ public JSON post(String path, JSON payload) throws RestException, IOException, URISyntaxException { return post(buildURI(path), payload); } /** * Executes an HTTP POST with the given path. * * @param path Path to be appended to the URI supplied in the construtor * @return JSON-encoded result or null when there's no content returned * @throws RestException when an HTTP-level error occurs * @throws IOException when an error reading the response occurs * @throws URISyntaxException when an error occurred appending the path to the URI */ public JSON post(String path) throws RestException, IOException, URISyntaxException { return post(buildURI(path), new JSONObject()); } /** * Executes an HTTP POST with the given path and file payload. * * @param path Full URI of the remote endpoint * @param file java.io.File * @throws URISyntaxException * @throws IOException * @throws RestException */ public JSON post(String path, File file) throws RestException, IOException, URISyntaxException { return request(new HttpPost(buildURI(path)), file); } /** * Executes an HTTP POST with the given path and file payloads. * * @param path Full URI of the remote endpoint * @param attachments the name of the attachment * @throws URISyntaxException * @throws IOException * @throws RestException */ public JSON post(String path, Issue.NewAttachment... attachments) throws RestException, IOException, URISyntaxException { return request(new HttpPost(buildURI(path)), attachments); } /** * Executes an HTTP PUT with the given URI and payload. * * @param uri Full URI of the remote endpoint * @param payload JSON-encoded data to send to the remote service * @return JSON-encoded result or null when there's no content returned * @throws RestException when an HTTP-level error occurs * @throws IOException when an error reading the response occurs */ public JSON put(URI uri, JSON payload) throws RestException, IOException { return request(new HttpPut(uri), payload); } /** * Executes an HTTP PUT with the given path and payload. * * @param path Path to be appended to the URI supplied in the construtor * @param payload JSON-encoded data to send to the remote service * @return JSON-encoded result or null when there's no content returned * @throws RestException when an HTTP-level error occurs * @throws IOException when an error reading the response occurs * @throws URISyntaxException when an error occurred appending the path to the URI */ public JSON put(String path, JSON payload) throws RestException, IOException, URISyntaxException { return put(buildURI(path), payload); } /** * Exposes the http client. * * @return the httpClient property */ public HttpClient getHttpClient() { return this.httpClient; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy