/*
* Copyright (c) 2013-2017 Cinchapi Inc.
*
* 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 com.cinchapi.concourse.server.http;
import com.cinchapi.concourse.thrift.AccessToken;
import com.cinchapi.concourse.thrift.TransactionToken;
import com.cinchapi.concourse.util.DataServices;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
/**
* An {@link Endpoint} that can
* {@link #serve(HttpRequest, AccessToken, TransactionToken, String, HttpResponse)}
* a request with a generic object, that is intelligently serialized to an
* appropriate JSON payload.
*
* @author Jeff Nelson
*/
public abstract class JsonEndpoint extends Endpoint {
/**
* The encoder to use to serialize the JSON response.
*/
private final Gson encoder;
/**
* Construct a new instance that uses that default {@link Gson json encoder}
*/
public JsonEndpoint() {
this(DataServices.gson());
}
/**
* Construct a new instance that uses the specified {@link Gson json
* encoder}.
*
* @param encoder an instance of {@link Gson} to use when encoding the
* response from
* {@link #serve(HttpRequest, AccessToken, TransactionToken, String, HttpResponse)}
*
*/
public JsonEndpoint(Gson encoder) {
super();
this.encoder = encoder;
}
/**
* Construct a new instance.
*
* @param encoder an instance of {@link Gson} to use when encoding the
* response from
* {@link #serve(HttpRequest, AccessToken, TransactionToken, String, HttpResponse)}
* @param action
* @param path
*/
public JsonEndpoint(Gson encoder, String action, String path) {
super(action, path);
this.encoder = encoder;
}
/**
* Construct a new instance.
*
* @param action
* @param path
*/
public JsonEndpoint(String action, String path) {
this(DataServices.gson(), action, path);
}
@Override
public final String serve(HttpRequest request, HttpResponse response,
AccessToken creds, TransactionToken transaction, String environment)
throws Exception {
Object payload = serve(request, creds, transaction, environment,
response);
JsonElement encoded;
if(payload == null) {
encoded = NO_DATA;
}
else if(payload instanceof JsonElement) {
encoded = (JsonElement) payload;
}
else {
encoded = encoder.toJsonTree(payload);
}
return encoded.toString();
}
/**
* Serve the {@code request} and return the appropriate payload with the
* {@code response}.
*
* <p>
* If this method returns, it is assumed that the request was successful.
* If, for any reason, an error occurs, this method should throw an
* Exception and it will be wrapped in the appropriate response for the
* caller.
* </p>
*
* @param request an {@link HttpRequest object} that contains all the
* information about the request
* @param creds an {@link AccessToken} for the authenticated user, if a user
* session exists
* @param transaction a {@link TransactionToken} for appropriately routing
* the data actions
* @param environment the environment of the
* {@link com.cinchapi.concourse.plugin.ConcourseRuntime} in
* which the data action should occur
* @param response an {@link HttpResponse object} that contains all the
* information that should be issued within the response
* @return the payload
* @throws Exception
*/
protected abstract Object serve(HttpRequest request, AccessToken creds,
TransactionToken transaction, String environment,
HttpResponse response) throws Exception;
}