io.soliton.protobuf.json.JsonRpcCallback.java Source code

Java tutorial

Introduction

Here is the source code for io.soliton.protobuf.json.JsonRpcCallback.java

Source

/**
 * Copyright 2013 Julien Silland
 *
 * 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.
 */

package io.soliton.protobuf.json;

import com.google.common.base.Charsets;
import com.google.common.util.concurrent.FutureCallback;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.stream.JsonWriter;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;

import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * Implements the logic executed upon a service method returning a result or
 * throwing an exception.
 *
 * @author Julien Silland (julien@soliton.io)
 */
class JsonRpcCallback implements FutureCallback<JsonRpcResponse> {

    private static final Gson GSON_PP = new GsonBuilder().disableHtmlEscaping().generateNonExecutableJson()
            .setPrettyPrinting().create();
    private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().generateNonExecutableJson().create();

    private final JsonElement id;
    private final Channel channel;
    private final boolean prettyPrint;

    /**
     * Exhaustive constructor.
     *
     * @param id the identifier of the request, as sent by the client
     * @param channel the channel on which the communication is taking place
     * @param prettyPrint determines whether the output should be pretty-printed
     */
    public JsonRpcCallback(JsonElement id, Channel channel, boolean prettyPrint) {
        this.id = id;
        this.channel = channel;
        this.prettyPrint = prettyPrint;
    }

    @Override
    public void onSuccess(JsonRpcResponse response) {
        ByteBuf responseBuffer = Unpooled.buffer();
        JsonWriter writer = new JsonWriter(
                new OutputStreamWriter(new ByteBufOutputStream(responseBuffer), Charsets.UTF_8));
        (prettyPrint ? GSON_PP : GSON).toJson(response.toJson(), writer);
        try {
            writer.flush();
        } catch (IOException ioe) {
            // Deliberately ignored, no I/O is involved
        }
        FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
                responseBuffer);
        httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/json");
        httpResponse.headers().set(HttpHeaders.Names.CONTENT_LENGTH, responseBuffer.readableBytes());
        channel.writeAndFlush(httpResponse);
    }

    @Override
    public void onFailure(Throwable t) {
        JsonRpcError error = new JsonRpcError(HttpResponseStatus.INTERNAL_SERVER_ERROR, t.getMessage());
        JsonRpcResponse response = JsonRpcResponse.error(error, id);
        onSuccess(response);
    }
}