Package org.wiztools.restclient

Source Code of org.wiztools.restclient.XMLUtil

package org.wiztools.restclient;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.XMLStreamException;
import nu.xom.Attribute;
import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Serializer;
import nu.xom.ParsingException;
import org.wiztools.commons.MultiValueMap;
import org.wiztools.commons.StringUtil;

/**
*
* @author rsubramanian
*/
public final class XMLUtil {

    private XMLUtil() {
    }
    private static final Logger LOG = Logger.getLogger(XMLUtil.class.getName());
    private static final String[] VERSIONS = new String[]{
        "2.0", "2.1", "2.2a1", "2.2a2", "2.2", "2.3b1", "2.3", "2.3.1", "2.3.2", "2.3.3", RCConstants.VERSION
    };
    public static final String XML_MIME = "application/xml";
   
    static {
        // Sort the version array for binary search
        Arrays.sort(VERSIONS);
    }

    private static void checkIfVersionValid(final String restVersion)
            throws XMLException {
        if (restVersion == null) {
            throw new XMLException("Attribute `version' not available for root element <rest-client>");
        }
        int res = Arrays.binarySearch(VERSIONS, restVersion);
        if (res == -1) {
            throw new XMLException("Version not supported");
        }
    }

    private static Document request2XML(final Request bean)
            throws XMLException {
        try {

            Element reqRootElement = new Element("rest-client");
            // set version attributes to rest-client root tag
            Attribute versionAttributes = new Attribute("version", RCConstants.VERSION);
            reqRootElement.addAttribute(versionAttributes);

            Element reqChildElement = new Element("request");

            { // HTTP Version
                Element e = new Element("http-version");
                e.appendChild(bean.getHttpVersion().versionNumber());
                reqChildElement.appendChild(e);
            }

            { // HTTP Follow Redirect
                Element e = new Element("http-follow-redirects");
                e.appendChild(String.valueOf(bean.isFollowRedirect()));
                reqChildElement.appendChild(e);
            }

            { // creating the URL child element
                Element e = new Element("URL");
                e.appendChild(bean.getUrl().toString());
                reqChildElement.appendChild(e);
            }

            { // creating the method child element
                Element e = new Element("method");
                e.appendChild(bean.getMethod().name());
                reqChildElement.appendChild(e);
            }

            { // creating the auth-methods child element
                List<HTTPAuthMethod> authMethods = bean.getAuthMethods();
                if (authMethods == null || authMethods.size() > 0) {

                    { // auth-methods
                        Element e = new Element("auth-methods");
                        String methods = "";
                        for (HTTPAuthMethod authMethod : authMethods) {
                            methods = methods + authMethod + ",";
                        }
                        String authenticationMethod = methods.substring(0, methods.length() == 0 ? 0 : methods.length() - 1);
                        e.appendChild(authenticationMethod);
                        reqChildElement.appendChild(e);
                    }

                    { // creating the auth-preemptive child element
                        Element e = new Element("auth-preemptive");
                        e.appendChild(String.valueOf(bean.isAuthPreemptive()));
                        reqChildElement.appendChild(e);
                    }

                    // creating the auth-host child element
                    String authHost = bean.getAuthHost();
                    if (!StringUtil.isStrEmpty(authHost)) {
                        Element e = new Element("auth-host");
                        e.appendChild(authHost);
                        reqChildElement.appendChild(e);
                    }
                    // creating the auth-realm child element
                    String authRealm = bean.getAuthRealm();
                    if (!StringUtil.isStrEmpty(authRealm)) {
                        Element e = new Element("auth-realm");
                        e.appendChild(authRealm);
                        reqChildElement.appendChild(e);
                    }
                    // creating the auth-username child element
                    String authUsername = bean.getAuthUsername();
                    if (!StringUtil.isStrEmpty(authUsername)) {
                        Element e = new Element("auth-username");
                        e.appendChild(authUsername);
                        reqChildElement.appendChild(e);
                    }
                    // creating the auth-password child element
                    String authPassword = null;
                    if (bean.getAuthPassword() != null) {
                        authPassword = new String(bean.getAuthPassword());
                        if (!StringUtil.isStrEmpty(authPassword)) {
                            String encPassword = Base64.encodeObject(authPassword);

                            Element e = new Element("auth-password");
                            e.appendChild(encPassword);
                            reqChildElement.appendChild(e);
                        }
                    }
                }
            }
           
            // Creating SSL elements
            String sslTruststore = bean.getSslTrustStore();
            if (!StringUtil.isStrEmpty(sslTruststore)) {
                { // 1. Create truststore entry
                    Element e = new Element("ssl-truststore");
                    e.appendChild(sslTruststore);
                    reqChildElement.appendChild(e);
                }

                { // 2. Create password entry
                    String sslPassword = new String(bean.getSslTrustStorePassword());
                    String encPassword = Base64.encodeObject(sslPassword);
                    Element e = new Element("ssl-truststore-password");
                    e.appendChild(encPassword);
                    reqChildElement.appendChild(e);
                }

                { // 3. Create Hostname Verifier entry
                    String sslHostnameVerifier = bean.getSslHostNameVerifier().name();
                    Element e = new Element("ssl-hostname-verifier");
                    e.appendChild(sslHostnameVerifier);
                    reqChildElement.appendChild(e);
                }
            }

            // creating the headers child element
            MultiValueMap<String, String> headers = bean.getHeaders();
            if (!headers.isEmpty()) {
                Element e = new Element("headers");
                for (String key : headers.keySet()) {
                    for(String value: headers.get(key)) {
                        Element ee = new Element("header");
                        ee.addAttribute(new Attribute("key", key));
                        ee.addAttribute(new Attribute("value", value));
                        e.appendChild(ee);
                    }
                }
                reqChildElement.appendChild(e);
            }

            // creating the body child element
            ReqEntity rBean = bean.getBody();
            if (rBean != null) {
                String contentType = rBean.getContentType();
                String charSet = rBean.getCharSet();
                String body = rBean.getBody();
                Element e = new Element("body");
                e.addAttribute(new Attribute("content-type", contentType));
                e.addAttribute(new Attribute("charset", charSet));
                e.appendChild(body);
                reqChildElement.appendChild(e);
            }
            // creating the test-script child element
            String testScript = bean.getTestScript();
            if (testScript != null) {

                Element e = new Element("test-script");
                e.appendChild(testScript);
                reqChildElement.appendChild(e);
            }
            reqRootElement.appendChild(reqChildElement);

            Document xomDocument = new Document(reqRootElement);

            return xomDocument;
        } catch (Exception ex) {
            throw new XMLException(ex.getMessage(), ex);
        }
    }

    private static Map<String, String> getHeadersFromHeaderNode(final Element node)
            throws XMLException {
        Map<String, String> m = new LinkedHashMap<String, String>();

        for (int i = 0; i < node.getChildElements().size(); i++) {
            Element headerElement = node.getChildElements().get(i);
            if (!"header".equals(headerElement.getQualifiedName())) {
                throw new XMLException("<headers> element should contain only <header> elements");
            }

            m.put(headerElement.getAttributeValue("key"),
                    headerElement.getAttributeValue("value"));

        }
        return m;
    }

    private static Request xml2Request(final Document doc)
            throws MalformedURLException, XMLException {
        RequestBean requestBean = new RequestBean();

        // get the rootNode
        Element rootNode = doc.getRootElement();

        if (!"rest-client".equals(rootNode.getQualifiedName())) {
            throw new XMLException("Root node is not <rest-client>");
        }

        // checking correct rest version
        checkIfVersionValid(rootNode.getAttributeValue("version"));

        // assign rootnode to current node and also finding 'request' node
        Element tNode = null;
        Element requestNode = null;

        // if more than two request element is present then throw the exception
        if (rootNode.getChildElements().size() != 1) {
            throw new XMLException("There can be only one child node for root node: <request>");
        }
        // minimum one request element is present in xml
        if (rootNode.getFirstChildElement("request") == null) {
            throw new XMLException("The child node of <rest-client> should be <request>");
        }
        requestNode = rootNode.getFirstChildElement("request");
        for (int i = 0; i < requestNode.getChildElements().size(); i++) {
            tNode = requestNode.getChildElements().get(i);
            String nodeName = tNode.getQualifiedName();
            if ("http-version".equals(nodeName)) {
                String t = tNode.getValue();
                HTTPVersion httpVersion = "1.1".equals(t) ? HTTPVersion.HTTP_1_1 : HTTPVersion.HTTP_1_0;
                requestBean.setHttpVersion(httpVersion);
            }
            else if("http-follow-redirects".equals(nodeName)) {
                requestBean.setFollwoRedirect(Boolean.valueOf(tNode.getValue()));
            }
            else if ("URL".equals(nodeName)) {
                URL url = new URL(tNode.getValue());
                requestBean.setUrl(url);
            }
            else if ("method".equals(nodeName)) {
                requestBean.setMethod(HTTPMethod.get(tNode.getValue()));
            }
            else if ("auth-methods".equals(nodeName)) {
                String[] authenticationMethods = tNode.getValue().split(",");
                for (int j = 0; j < authenticationMethods.length; j++) {
                    requestBean.addAuthMethod(HTTPAuthMethod.get(authenticationMethods[j]));
                }
            }
            else if ("auth-preemptive".equals(nodeName)) {
                if (tNode.getValue().equals("true")) {
                    requestBean.setAuthPreemptive(true);
                } else {
                    requestBean.setAuthPreemptive(false);
                }
            }
            else if ("auth-host".equals(nodeName)) {
                requestBean.setAuthHost(tNode.getValue());
            }
            else if ("auth-realm".equals(nodeName)) {
                requestBean.setAuthRealm(tNode.getValue());
            }
            else if ("auth-username".equals(nodeName)) {
                requestBean.setAuthUsername(tNode.getValue());
            }
            else if ("auth-password".equals(nodeName)) {
                String password = (String) Base64.decodeToObject(tNode.getValue());
                requestBean.setAuthPassword(password.toCharArray());
            }
            else if ("ssl-truststore".equals(nodeName)) {
                String sslTrustStore = tNode.getValue();
                requestBean.setSslTrustStore(sslTrustStore);
            }
            else if ("ssl-truststore-password".equals(nodeName)) {
                String sslTrustStorePassword = (String) Base64.decodeToObject(tNode.getValue());
                requestBean.setSslTrustStorePassword(sslTrustStorePassword.toCharArray());
            }
            else if("ssl-hostname-verifier".equals(nodeName)){
                String sslHostnameVerifierStr = tNode.getValue();
                SSLHostnameVerifier sslHostnameVerifier = SSLHostnameVerifier.valueOf(sslHostnameVerifierStr);
                requestBean.setSslHostNameVerifier(sslHostnameVerifier);
            }
            else if ("headers".equals(nodeName)) {
                Map<String, String> m = getHeadersFromHeaderNode(tNode);
                for (String key : m.keySet()) {
                    requestBean.addHeader(key, m.get(key));
                }
            }
            else if ("body".equals(nodeName)) {
                requestBean.setBody(new ReqEntityBean(tNode.getValue(), tNode.getAttributeValue("content-type"),
                        tNode.getAttributeValue("charset")));
            }
            else if ("test-script".equals(nodeName)) {
                requestBean.setTestScript(tNode.getValue());
            }
            else {
                throw new XMLException("Invalid element encountered: <" + nodeName + ">");
            }
        }
        return requestBean;
    }

    private static Document response2XML(final Response bean)
            throws XMLException {

        try {

            Element respRootElement = new Element("rest-client");
            Element respChildElement = new Element("response");
            Element respChildSubElement = null;
            Element respChildSubSubElement = null;

            // set version attributes to rest-client root tag
            Attribute versionAttributes = new Attribute("version", RCConstants.VERSION);
            respRootElement.addAttribute(versionAttributes);

            // adding first sub child element - execution-time and append to response child element
            respChildSubElement = new Element("execution-time");
            respChildSubElement.appendChild(String.valueOf(bean.getExecutionTime()));
            respChildElement.appendChild(respChildSubElement);

            // adding second sub child element - status and code attributes and append to response child element
            respChildSubElement = new Element("status");
            Attribute codeAttributes = new Attribute("code", String.valueOf(bean.getStatusCode()));
            respChildSubElement.addAttribute(codeAttributes);
            respChildSubElement.appendChild(bean.getStatusLine());
            respChildElement.appendChild(respChildSubElement);

            // adding third sub child element - headers
            MultiValueMap<String, String> headers = bean.getHeaders();
            if (!headers.isEmpty()) {
                Attribute keyAttribute = null;
                Attribute valueAttribute = null;
                // creating sub child-child element
                respChildSubElement = new Element("headers");
                for (String key : headers.keySet()) {
                    for(String value: headers.get(key)) {
                        respChildSubSubElement = new Element("header");
                        keyAttribute = new Attribute("key", key);
                        valueAttribute = new Attribute("value", value);
                        respChildSubSubElement.addAttribute(keyAttribute);
                        respChildSubSubElement.addAttribute(valueAttribute);
                        respChildSubElement.appendChild(respChildSubSubElement);
                    }
                }
                // add response child element - headers
                respChildElement.appendChild(respChildSubElement);
            }

            String responseBody = bean.getResponseBody();
            if (responseBody != null) {
                //creating the body child element and append to response child element
                respChildSubElement = new Element("body");
                respChildSubElement.appendChild(responseBody);
                respChildElement.appendChild(respChildSubElement);
            }
            // test result
            TestResult testResult = bean.getTestResult();
            if (testResult != null) {
                //creating the test-result child element
                respChildSubElement = new Element("test-result");

                // Counts:
                Element e_runCount = new Element("run-coun");
                e_runCount.appendChild(String.valueOf(testResult.getRunCount()));
                Element e_failureCount = new Element("failure-coun");
                e_failureCount.appendChild(String.valueOf(testResult.getFailureCount()));
                Element e_errorCount = new Element("error-coun");
                e_errorCount.appendChild(String.valueOf(testResult.getErrorCount()));
                respChildSubElement.appendChild(e_runCount);
                respChildSubElement.appendChild(e_failureCount);
                respChildSubElement.appendChild(e_errorCount);

                // Failures
                if (testResult.getFailureCount() > 0) {
                    Element e_failures = new Element("failures");
                    List<TestFailureResult> l = testResult.getFailures();
                    for (TestFailureResult b : l) {
                        Element e_message = new Element("message");
                        e_message.appendChild(b.getExceptionMessage());
                        Element e_line = new Element("line-number");
                        e_line.appendChild(String.valueOf(b.getLineNumber()));
                        Element e_failure = new Element("failure");
                        e_failure.appendChild(e_message);
                        e_failure.appendChild(e_line);
                        e_failures.appendChild(e_failure);
                    }
                    respChildSubElement.appendChild(e_failures);
                }

                //Errors
                if (testResult.getFailureCount() > 0) {
                    Element e_errors = new Element("errors");
                    List<TestFailureResult> l = testResult.getErrors();
                    for (TestFailureResult b : l) {
                        Element e_message = new Element("message");
                        e_message.appendChild(b.getExceptionMessage());
                        Element e_line = new Element("line-number");
                        e_line.appendChild(String.valueOf(b.getLineNumber()));
                        Element e_error = new Element("error");
                        e_error.appendChild(e_message);
                        e_error.appendChild(e_line);
                        e_errors.appendChild(e_error);
                    }
                    respChildSubElement.appendChild(e_errors);
                }
                // Trace
                Element e_trace = new Element("trace");
                e_trace.appendChild(testResult.toString());
                respChildSubElement.appendChild(e_trace);

                respChildElement.appendChild(respChildSubElement);
            }

            respRootElement.appendChild(respChildElement);

            Document xomDocument = new Document(respRootElement);

            return xomDocument;

        } catch (Exception ex) {
            throw new XMLException(ex.getMessage(), ex);
        }
    }

    private static Response xml2Response(final Document doc)
            throws XMLException {
        ResponseBean responseBean = new ResponseBean();

        // get the rootNode
        Element rootNode = doc.getRootElement();

        if (!"rest-client".equals(rootNode.getQualifiedName())) {
            throw new XMLException("Root node is not <rest-client>");
        }

        // checking correct rest version
        checkIfVersionValid(rootNode.getAttributeValue("version"));

        // assign rootnode to current node and also finding 'response' node
        Element tNode = null;
        Element responseNode = null;

        // if more than two request element is present then throw the exception
        if (rootNode.getChildElements().size() != 1) {
            throw new XMLException("There can be only one child node for root node: <response>");
        }
        // minimum one response element is present in xml
        if (rootNode.getFirstChildElement("response") == null) {
            throw new XMLException("The child node of <rest-client> should be <response>");
        }
        responseNode = rootNode.getFirstChildElement("response");
        for (int i = 0; i < responseNode.getChildElements().size(); i++) {
            tNode = responseNode.getChildElements().get(i);
            String nodeName = tNode.getQualifiedName();

            if ("execution-time".equals(nodeName)) {
                responseBean.setExecutionTime(Long.parseLong(tNode.getValue()));
            } else if ("status".equals(nodeName)) {
                responseBean.setStatusLine(tNode.getValue());
                responseBean.setStatusCode(Integer.parseInt(tNode.getAttributeValue("code")));
            } else if ("headers".equals(nodeName)) {
                Map<String, String> m = getHeadersFromHeaderNode(tNode);
                for (String key : m.keySet()) {
                    responseBean.addHeader(key, m.get(key));
                }
            } else if ("body".equals(nodeName)) {
                responseBean.setResponseBody(tNode.getValue());
            } else if ("test-result".equals(nodeName)) {
                //responseBean.setTestResult(node.getTextContent()); TODO
                TestResultBean testResultBean = new TestResultBean();

                for (int j = 0; j < tNode.getChildCount(); j++) {
                    String nn = tNode.getQualifiedName();
                    if ("run-count".equals(nn)) {
                        throw new XMLException("<headers> element should contain only <header> elements");
                    } else if ("failure-count".equals(nn)) {
                        throw new XMLException("<headers> element should contain only <header> elements");
                    } else if ("error-count".equals(nn)) {
                        throw new XMLException("<headers> element should contain only <header> elements");
                    } else if ("failures".equals(nn)) {
                        throw new XMLException("<headers> element should contain only <header> elements");
                    } else if ("errors".equals(nn)) {
                        throw new XMLException("<headers> element should contain only <header> elements");
                    }
                }
                responseBean.setTestResult(testResultBean);
            } else {
                throw new XMLException("Unrecognized element found: <" + nodeName + ">");
            }
        }
        return responseBean;
    }

    private static void writeXML(final Document doc, final File f)
            throws IOException, XMLException {

        try {
            OutputStream out = new FileOutputStream(f);
            out = new BufferedOutputStream(out);
            // getDocumentCharset(f) - to retrieve the charset encoding attribute
            Serializer serializer = new Serializer(out, getDocumentCharset(f));
            serializer.write(doc);
            out.close();
        } catch (IOException ex) {
            throw new XMLException(ex.getMessage(), ex);
        }
    }

    private static Document getDocumentFromFile(final File f)
            throws IOException, XMLException {
        try {
            Builder parser = new Builder();
            Document doc = parser.build(f);
            return doc;
        } catch (ParsingException ex) {
            throw new XMLException(ex.getMessage(), ex);
        } catch (IOException ex) {
            throw new XMLException(ex.getMessage(), ex);
        }

    }

    public static String getDocumentCharset(final File f)
            throws IOException, XMLException {
        XMLEventReader reader = null;
        try {
            // using stax to get xml factory objects and read the input file
            XMLInputFactory inputFactory = XMLInputFactory.newInstance();
            reader = inputFactory.createXMLEventReader(new FileInputStream(f));
            XMLEvent event = reader.nextEvent();
            // Always the first element is StartDocument
            // even if the XML does not have explicit declaration:
            StartDocument document = (StartDocument) event;
            return document.getCharacterEncodingScheme();
        }
        catch (XMLStreamException ex) {
            throw new XMLException(ex.getMessage(), ex);
        }
        finally{
            if(reader != null){
                try{
                    reader.close();
                }
                catch(XMLStreamException ex){
                    LOG.warning(ex.getMessage());
                }
            }
        }
    }

    public static void writeRequestXML(final Request bean, final File f)
            throws IOException, XMLException {
        Document doc = request2XML(bean);
        writeXML(doc, f);
    }

    public static void writeResponseXML(final Response bean, final File f)
            throws IOException, XMLException {
        Document doc = response2XML(bean);
        writeXML(doc, f);
    }

    public static Request getRequestFromXMLFile(final File f)
            throws IOException, XMLException {
        Document doc = getDocumentFromFile(f);
        return xml2Request(doc);
    }

    public static Response getResponseFromXMLFile(final File f)
            throws IOException, XMLException {
        Document doc = getDocumentFromFile(f);
        return xml2Response(doc);
    }

    public static String indentXML(final String in)
            throws XMLException, IOException {
        try {
            Builder parser = new Builder();
            Document doc = parser.build(in, null);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Serializer serializer = new Serializer(baos);
            serializer.setIndent(4);
            serializer.setMaxLength(69);
            serializer.write(doc);
            return new String(baos.toByteArray());
        } catch (ParsingException ex) {
            // LOG.log(Level.SEVERE, null, ex);
            throw new XMLException("XML indentation failed.", ex);
        }
    }
}
TOP

Related Classes of org.wiztools.restclient.XMLUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.