Package org.jolokia.client.request

Source Code of org.jolokia.client.request.J4pRequestHandler

package org.jolokia.client.request;

/*
*  Copyright 2009-2010 Roland Huss
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.*;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.json.simple.*;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
* Class doing the hard work of conversion between HTTP request/responses and
* J4p request/responses.
*
* @author roland
* @since Apr 25, 2010
*/
public class J4pRequestHandler {

    // j4p agent URL for the agent server
    private String j4pServerUrl;

    // Escape patterns
    private static final Pattern SLASH_PATTERN = Pattern.compile("/+");
    private static final Pattern ESCAPED_SLASH_PATTERN = Pattern.compile("%2F");

    public J4pRequestHandler(String pJ4pServerUrl) {
        j4pServerUrl = pJ4pServerUrl;
    }

    /**
     * Get the HttpRequest for executing the given single request
     *
     * @param pRequest request to convert
     * @param pPreferredMethod HTTP method preferred
     * @return the request used with HttpClient to obtain the result.
     */
    public HttpUriRequest getHttpRequest(J4pRequest pRequest,String pPreferredMethod) throws UnsupportedEncodingException {
        String method = pPreferredMethod;
        if (method == null) {
            method = pRequest.getPreferredHttpMethod();
        }
        if (method == null) {
            method = HttpGet.METHOD_NAME;
        }
        if (method.equals(HttpGet.METHOD_NAME)) {
            List<String> parts = pRequest.getRequestParts();
            // If parts == null the request decides, that POST *must* be used
            if (parts != null) {
                StringBuilder requestPath = new StringBuilder();
                requestPath.append(pRequest.getType().getValue());
                for (String p : parts) {
                    requestPath.append("/");
                    requestPath.append(escape(p));
                }
                // TODO: Option handling, special escaping
                return new HttpGet(j4pServerUrl + "/" + requestPath.toString());
            }
        }


        // We are using a post method as fallback
        // TODO: Option handling
        JSONObject requestContent = pRequest.toJson();
        HttpPost postReq = new HttpPost(j4pServerUrl);
        postReq.setEntity(new StringEntity(requestContent.toJSONString(),"utf-8"));
        return postReq;
    }

    /**
     * Get an HTTP Request for requesting multips requests at once
     *
     * @param pRequests requests to put into a HTTP request
     * @return HTTP request to send to the server
     */
    public <T extends J4pRequest> HttpUriRequest getHttpRequest(List<T> pRequests) throws UnsupportedEncodingException {
        JSONArray bulkRequest = new JSONArray();
        HttpPost postReq = new HttpPost(j4pServerUrl);
        for (T request : pRequests) {
            JSONObject requestContent = request.toJson();
            bulkRequest.add(requestContent);
        }
        postReq.setEntity(new StringEntity(bulkRequest.toJSONString(),"utf-8"));
        return postReq;
    }


    /**
     * Extract the complete JSON response out of a HTTP response
     *
     * @param pRequest the original J4p request
     * @param pHttpResponse the resulting http response
     * @param <T> J4p Request
     * @return JSON content of the answer
     * @throws J4pException when parsing of the answer fails
     */
    @SuppressWarnings("PMD.PreserveStackTrace")
    public JSONAware extractJsonResponse(HttpResponse pHttpResponse) throws IOException, ParseException {
        HttpEntity entity = pHttpResponse.getEntity();
        try {
            JSONParser parser = new JSONParser();
            Header contentEncoding = entity.getContentEncoding();
            if (contentEncoding != null) {
                return (JSONAware) parser.parse(new InputStreamReader(entity.getContent(), Charset.forName(contentEncoding.getValue())));
            } else {
                return (JSONAware) parser.parse(new InputStreamReader(entity.getContent()));
            }
        } finally {
            if (entity != null) {
                entity.consumeContent();
            }
        }
    }

    /**
     * Extract a {@link J4pResponse} out of a JSON object
     *
     * @param pRequest request which lead to the response
     * @param pJsonResponse JSON response
     * @param <T> request type.
     * @param <R> response type
     * @return the J4p response
     */
    public <R extends J4pResponse<T>,T extends J4pRequest> R extractResponse(T pRequest,JSONObject pJsonResponse) {
        return pRequest.<R>createResponse(pJsonResponse);
    }

    // Escape a part for usage as part of URI path
    private String escape(String pPart) throws UnsupportedEncodingException {
        Matcher matcher = SLASH_PATTERN.matcher(pPart);
        int index = 0;
        StringBuilder ret = new StringBuilder();
        while (matcher.find()) {
            String part = pPart.subSequence(index, matcher.start()).toString();
            ret.append(part).append("/");
            ret.append(escapeSlash(pPart, matcher));
            ret.append("/");
            index = matcher.end();
        }
        if (index != pPart.length()) {
            ret.append(pPart.substring(index,pPart.length()));
        }
        return uriEscape(ret);
    }

    private String escapeSlash(String pPart, Matcher pMatcher) {
        StringBuilder ret = new StringBuilder();
        String separator = pPart.substring(pMatcher.start(), pMatcher.end());
        int len = separator.length();
        for (int i = 0;i<len;i++) {
            if (i == 0 && pMatcher.start() == 0) {
                ret.append("^");
            } else if (i == len - 1 && pMatcher.end() == pPart.length()) {
                ret.append("+");
            } else {
                ret.append("-");
            }
        }
        return ret.toString();
    }

    private String uriEscape(StringBuilder pRet) throws UnsupportedEncodingException {
        // URI Escape unsafe chars
        String encodedRet = URLEncoder.encode(pRet.toString(),"utf-8");
        // Translate all "/" back...
        return ESCAPED_SLASH_PATTERN.matcher(encodedRet).replaceAll("/");
    }

    /**
     * Get the J4p Server URL
     * @return the URL to the Jolokia agent on the server side
     */
    public String getJ4pServerUrl() {
        return j4pServerUrl;
    }
}
TOP

Related Classes of org.jolokia.client.request.J4pRequestHandler

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.