org.xframium.utility.WebServiceClientUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.xframium.utility.WebServiceClientUtil.java

Source

/*******************************************************************************
 * xFramium
 *
 * Copyright 2016 by Moreland Labs, Ltd. (http://www.morelandlabs.com)
 *
 * Some open source application is free software: you can redistribute 
 * it and/or modify it under the terms of the GNU General Public 
 * License as published by the Free Software Foundation, either 
 * version 3 of the License, or (at your option) any later version.
 *  
 * Some open source application is distributed in the hope that it will 
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with xFramium.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @license GPL-3.0+ <http://spdx.org/licenses/GPL-3.0+>
 *******************************************************************************/
package org.xframium.utility;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xframium.exception.ScriptConfigurationException;
import org.xframium.exception.ScriptException;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;

import net.minidev.json.JSONArray;

public class WebServiceClientUtil {
    private static Log log = LogFactory.getLog(WebServiceClientUtil.class);
    //
    // Constants
    //

    private static final String HTTP_GET = "GET";
    private static final String HTTP_DELETE = "DELETE";
    private static final String HTTP_POST = "POST";
    private static final String HTTP_PUT = "PUT";

    private static final String CONTENT_XML = "xml";
    private static final String CONTENT_JSON = "json";

    private static final String PATH_DIVIDER = "/";

    //
    // Class Data
    //

    private static XPathFactory xPathFactory = XPathFactory.newInstance();
    private static DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();

    //
    // Behaviors
    //

    public static Map<String, String> callWebService(CallDetails callDetails, ResponceDetails responceDetails) {
        Map<String, String> rtn = new HashMap<String, String>();

        try {
            Responce result = makeCall(callDetails);

            processResult(result, responceDetails, rtn);
        } catch (Throwable e) {
            throw new IllegalStateException("Call failed with:", e);
        }

        return rtn;
    }

    //
    // Data Structures
    //

    public static class CallDetails {
        private String url = null;
        private String method = null;
        private String media_type = null;
        private String type = null;
        private String username = null;
        private String password = null;
        private ArrayList<CallParameter> parameters = new ArrayList<CallParameter>();
        private String payload = null;
        private boolean valid = false;
        private HashMap<String, String> headers = new HashMap<String, String>();

        public CallDetails() {
        }

        public CallDetails(String url, String method, String media_type, String type, String username,
                String password, String payload, boolean valid) {
            super();
            this.url = url;
            this.method = method;
            this.media_type = media_type;
            this.type = type;
            this.username = username;
            this.password = password;
            this.payload = payload;
            this.valid = valid;
        }

        public String getUrl() {
            return url;
        }

        public String getMethod() {
            return method;
        }

        public String getMediaType() {
            return media_type;
        }

        public String getType() {
            return type;
        }

        public String getUsername() {
            return username;
        }

        public String getPassword() {
            return password;
        }

        public ArrayList<CallParameter> getParameters() {
            return parameters;
        }

        public String getPayload() {
            return payload;
        }

        public boolean isValid() {
            return valid;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public void setMethod(String method) {
            this.method = method;
        }

        public void setMediaType(String media_type) {
            this.media_type = media_type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public void setParameters(ArrayList<CallParameter> parameters) {
            this.parameters = parameters;
        }

        public void setPayload(String payload) {
            this.payload = payload;
        }

        public void setValid(boolean valid) {
            this.valid = valid;
        }

        public HashMap<String, String> getHeaders() {
            return headers;
        }
    }

    public static class CallParameter {
        private String name = null;
        private String value = null;

        public CallParameter() {
        }

        public CallParameter(String name, String value) {
            super();
            this.name = name;
            this.value = value;
        }

        public String getName() {
            return name;
        }

        public String getValue() {
            return value;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    public static class Responce {
        private String payload = null;

        public Responce() {
        }

        public Responce(String payload) {
            super();
            this.payload = payload;

            if (log.isInfoEnabled())
                log.info("Return Payload " + payload);

        }

        public String getPayload() {
            return payload;
        }

        public void setPayload(String payload) {
            this.payload = payload;
        }
    }

    public static class ResponceDetails {
        private String type = null;
        private ArrayList<ResponceVariable> parameters = new ArrayList<ResponceVariable>();

        public ResponceDetails() {
        }

        public ResponceDetails(String type) {
            super();
            this.type = type;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public ArrayList<ResponceVariable> getParameters() {
            return parameters;
        }
    }

    public static class ResponceVariable {
        private String name = null;
        private String path = null;

        public ResponceVariable() {
        }

        public ResponceVariable(String name, String path) {
            super();
            this.name = name;
            this.path = path;
        }

        public String getName() {
            return name;
        }

        public String getPath() {
            return path;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setPath(String path) {
            this.path = path;
        }

    }

    //
    // Helpers
    //

    private static Responce makeCall(CallDetails callDetails) throws Exception {
        Responce rtn = null;

        String targetURL = buildURL(callDetails);

        HttpURLConnection con = null;

        try {
            if (log.isInfoEnabled())
                log.info("Executing " + callDetails.method + " WebService call to " + targetURL);

            URL obj = new URL(targetURL);

            con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod(callDetails.method);
            con.setRequestProperty("User-Agent", "xFramium");

            if (callDetails.headers.size() > 0) {
                Iterator<String> names = callDetails.headers.keySet().iterator();
                while (names.hasNext()) {
                    String name = names.next();
                    String value = callDetails.headers.get(name);

                    con.setRequestProperty(name, value);
                }
            }

            setBasicAuthIfRequested(con, callDetails);

            if ((HTTP_GET.equalsIgnoreCase(callDetails.method))
                    || (HTTP_DELETE.equalsIgnoreCase(callDetails.method))) {
                int responseCode = con.getResponseCode();

                if (responseCode == HttpURLConnection.HTTP_OK) // success
                {
                    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }

                    in.close();

                    rtn = new Responce(response.toString());
                }
            } else if ((HTTP_POST.equals(callDetails.method)) || (HTTP_PUT.equals(callDetails.method))) {
                con.setDoOutput(true);
                con.setRequestProperty("Content-Type", callDetails.media_type);

                if (log.isInfoEnabled())
                    log.info("Payload is " + callDetails.payload);

                OutputStream os = con.getOutputStream();
                os.write(callDetails.payload.getBytes());
                os.flush();

                int responseCode = con.getResponseCode();

                if (responseCode == HttpURLConnection.HTTP_OK) // success
                {
                    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine).append("\n");
                    }

                    in.close();
                    os.close();

                    rtn = new Responce(response.toString());
                } else {
                    BufferedReader in = new BufferedReader(new InputStreamReader(con.getErrorStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine).append("\n");
                    }

                    in.close();
                    os.close();

                    throw new ScriptException(response.toString());
                }
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }

        return rtn;
    }

    private static String buildURL(CallDetails callDetails) {
        StringBuilder rtn = new StringBuilder();

        rtn.append(callDetails.url);

        if (callDetails.parameters.size() > 0) {
            rtn.append(PATH_DIVIDER);

            Iterator<CallParameter> params = callDetails.parameters.iterator();
            while (params.hasNext()) {
                CallParameter param = params.next();

                rtn.append(param.name);
                rtn.append(PATH_DIVIDER);
                rtn.append(param.value);
            }
        }

        return rtn.toString();
    }

    private static void processResult(Responce result, ResponceDetails responceDetails,
            Map<String, String> contextMap) throws Exception {
        if (CONTENT_XML.equalsIgnoreCase(responceDetails.type)) {
            //
            // In this case, result.payload is an XML document and the paths in
            // responceDetails.parameters are XPATH
            // expressions
            //

            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document document = dBuilder.parse(new ByteArrayInputStream(result.payload.getBytes()));
            XPath xPath = xPathFactory.newXPath();

            Iterator<ResponceVariable> params = responceDetails.parameters.iterator();
            while (params.hasNext()) {
                ResponceVariable param = params.next();

                Node node = (Node) xPath.evaluate(param.path, document, XPathConstants.NODE);

                if (node == null) {
                    throw new ScriptConfigurationException("No result found. Check xpath expression " + param.path);
                }

                String value = node.getTextContent();

                contextMap.put(param.name, value);
            }
        } else if (CONTENT_JSON.equalsIgnoreCase(responceDetails.type)) {
            //
            // In this case, result.payload is an JSON document and the paths in
            // responceDetails.parameters are JASONPATH
            // (https://github.com/jayway/JsonPath) expressions
            //

            DocumentContext ctx = JsonPath.parse(result.payload);

            Iterator<ResponceVariable> params = responceDetails.parameters.iterator();
            while (params.hasNext()) {
                ResponceVariable param = params.next();

                /* String value = ctx.read( param.path );
                    
                 contextMap.put( param.name, value );*/

                JSONArray value = (JSONArray) ctx.read(param.path);

                contextMap.put(param.name, value.toJSONString());
            }
        }
    }

    private static void setBasicAuthIfRequested(HttpURLConnection con, CallDetails callDetails) {
        if ((callDetails.username != null) && (callDetails.password != null)) {
            String userpass = callDetails.username + ":" + callDetails.password;
            String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());

            con.setRequestProperty("Authorization", basicAuth);
        }
    }
}