com.github.consiliens.harv.gson.IRequestLogRecordSerializer.java Source code

Java tutorial

Introduction

Here is the source code for com.github.consiliens.harv.gson.IRequestLogRecordSerializer.java

Source

/*******************************************************************************
 * Copyright (c) 2011 consiliens (consiliens@gmail.com).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 ******************************************************************************/
package com.github.consiliens.harv.gson;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map.Entry;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
import org.apache.http.StatusLine;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;

import com.github.consiliens.harv.util.Utils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.subgraph.vega.api.model.requests.IRequestLogRecord;

public final class IRequestLogRecordSerializer implements JsonSerializer<IRequestLogRecord> {
    // TODO: Default to true.
    private final String entitiesExternalPath;

    /** Defaults to saving entities as internal strings. **/
    public IRequestLogRecordSerializer() {
        entitiesExternalPath = "";
    }

    /**
     * If entitiesExternalPath is set then entites will be stored as external
     * files. If entitiesExternalPath is empty then entities are stored as
     * internal strings.
     **/
    public IRequestLogRecordSerializer(final String entitiesExternalPath) {
        this.entitiesExternalPath = entitiesExternalPath;
    }

    // TODO: Support more than just string values.
    public static JsonArray paramsToJsonArray(final HttpParams params) {
        JsonArray paramsJson = new JsonArray();

        // BasicHttpParams has no way to access HashMap parameters so use
        // reflection.
        try {
            final Field parameters = BasicHttpParams.class.getDeclaredField(R.parameters);
            parameters.setAccessible(true);
            HashMap<?, ?> targetParameters = (HashMap<?, ?>) parameters.get(params);

            if (!targetParameters.isEmpty()) {
                for (Entry<?, ?> entry : targetParameters.entrySet()) {
                    JsonArray entryJson = new JsonArray();
                    entryJson.add(new JsonPrimitive(entry.getKey().toString()));
                    // TODO: Is there a way to easily support non-string values?
                    entryJson.add(new JsonPrimitive(entry.getValue().toString()));

                    paramsJson.add(entryJson);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return paramsJson;
    }

    private static JsonArray headersToJsonArray(HttpRequest request) {
        return headersToJsonArray(request.getAllHeaders());
    }

    private static JsonArray headersToJsonArray(HttpResponse response) {
        return headersToJsonArray(response.getAllHeaders());
    }

    private static JsonArray headersToJsonArray(Header[] headers) {
        final JsonArray headersArray = new JsonArray();

        for (Header header : headers) {
            JsonArray nvPair = new JsonArray();

            nvPair.add(new JsonPrimitive(header.getName()));
            nvPair.add(new JsonPrimitive(header.getValue()));

            headersArray.add(nvPair);
        }

        return headersArray;
    }

    public static JsonObject ProtocolVersionToJsonObject(RequestLine requestLine) {
        return ProtocolVersionToJsonObject(requestLine.getProtocolVersion());
    }

    public static JsonObject ProtocolVersionToJsonObject(StatusLine statusLine) {
        return ProtocolVersionToJsonObject(statusLine.getProtocolVersion());
    }

    public static JsonObject ProtocolVersionToJsonObject(ProtocolVersion protocolVersion) {
        JsonObject protocolJson = new JsonObject();

        protocolJson.addProperty(R.protocol, protocolVersion.getProtocol());
        protocolJson.addProperty(R.major, protocolVersion.getMajor());
        protocolJson.addProperty(R.minor, protocolVersion.getMinor());

        return protocolJson;
    }

    @Override
    public JsonElement serialize(IRequestLogRecord src, Type typeOfSrc, JsonSerializationContext context) {
        // Update deserializer when serialize logic changes.
        JsonObject recordJson = new JsonObject();

        recordJson.addProperty(R.requestId, src.getRequestId());
        recordJson.addProperty(R.timestamp, src.getTimestamp());
        recordJson.addProperty(R.requestMilliseconds, src.getRequestMilliseconds());

        // HttpHost getHttpHost();
        JsonObject hostJson = new JsonObject();
        HttpHost host = src.getHttpHost();
        hostJson.addProperty(R.hostName, host.getHostName());
        hostJson.addProperty(R.port, host.getPort());
        hostJson.addProperty(R.schemeName, host.getSchemeName());
        recordJson.add(R.httpHost, hostJson);

        // HttpRequest getRequest();
        JsonObject requestJson = new JsonObject();
        HttpRequest httpRequest = src.getRequest();

        if (httpRequest instanceof HttpEntityEnclosingRequest) {
            final HttpEntity requestEntity = ((HttpEntityEnclosingRequest) httpRequest).getEntity();
            try {
                if (entitiesExternalPath.isEmpty()) {
                    // From internal string.
                    requestJson.addProperty(R.entity, Utils.streamToString(requestEntity.getContent()));
                } else {
                    // From file.
                    final String fileName = Utils.streamToFile(requestEntity.getContent(), entitiesExternalPath);
                    requestJson.addProperty(R.entity, R.shaPrefix + fileName);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        requestJson.add(R.allHeaders, headersToJsonArray(httpRequest));
        requestJson.add(R.params, paramsToJsonArray(httpRequest.getParams()));

        JsonObject requestLineJson = new JsonObject();
        RequestLine requestRequestLine = httpRequest.getRequestLine();

        requestLineJson.add(R.protocolVersion, ProtocolVersionToJsonObject(requestRequestLine));
        requestLineJson.addProperty(R.method, requestRequestLine.getMethod());
        requestLineJson.addProperty(R.uri, requestRequestLine.getUri());

        requestJson.add(R.requestLine, requestLineJson);
        recordJson.add(R.request, requestJson);

        // Serialize response.
        JsonObject responseJson = new JsonObject();
        HttpResponse httpResponse = src.getResponse();

        responseJson.add(R.allHeaders, headersToJsonArray(httpResponse));

        // Only write an entity if it's not null.
        HttpEntity responseEntity = httpResponse.getEntity();
        if (responseEntity != null) {
            try {
                if (entitiesExternalPath.isEmpty()) {
                    // Internal string.
                    responseJson.addProperty("entity", Utils.streamToString(responseEntity.getContent()));
                } else {
                    // From file.
                    final String fileName = Utils.streamToFile(responseEntity.getContent(), entitiesExternalPath);
                    responseJson.addProperty(R.entity, R.shaPrefix + fileName);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Locale locale = httpResponse.getLocale();
        JsonObject localeJson = new JsonObject();
        localeJson.addProperty(R.language, locale.getLanguage());
        localeJson.addProperty(R.country, locale.getCountry());

        // Variant is likely to be empty so check before writing.
        final String variant = locale.getVariant();
        if (!variant.isEmpty())
            localeJson.addProperty(R.variant, variant);

        responseJson.add(R.locale, localeJson);
        responseJson.add(R.params, paramsToJsonArray(httpResponse.getParams()));

        StatusLine statusLine = httpResponse.getStatusLine();
        JsonObject statusLineJson = new JsonObject();

        // Match constructor order of BasicStatusLine
        statusLineJson.add(R.protocolVersion, ProtocolVersionToJsonObject(statusLine));
        statusLineJson.addProperty(R.statusCode, statusLine.getStatusCode());
        statusLineJson.addProperty(R.reasonPhrase, statusLine.getReasonPhrase());

        responseJson.add(R.statusLine, statusLineJson);
        recordJson.add(R.response, responseJson);

        return recordJson;
    }
}