/**
* diqube: Distributed Query Base.
*
* Copyright (C) 2015 Bastian Gloeckle
*
* This file is part of diqube.
*
* diqube is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diqube.ui.websocket.result;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import org.diqube.context.AutoInstatiate;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Serializes arbitrary {@link JsonResult} objects to JSON.
*
* @author Bastian Gloeckle
*/
@AutoInstatiate
public class JsonResultSerializer {
private JsonFactory jsonFactory = new JsonFactory();
private ObjectMapper mapper = new ObjectMapper(jsonFactory);
/**
* Encapsulate the given {@link JsonResult} with a {@link JsonResultEnvelope} and serialize it.
*
* @param requestId
* The requestId the client provided when it sent the request (to which this is a result).
* @param status
* One of {@link JsonResultEnvelope#STATUS_DATA}, {@link JsonResultEnvelope#STATUS_DONE},
* {@link JsonResultEnvelope#STATUS_EXCEPTION} or {@link JsonResultEnvelope#STATUS_AUTHENTICATION_EXCEPTION}
* depending on what result you want to inform the client of.
* @param payload
* the actual {@link JsonResult}. Can be <code>null</code> if status ==
* {@link JsonResultEnvelope#STATUS_DONE}.
* @throws JsonPayloadSerializerException
* If anything goes wrong.
*/
public String serializeWithEnvelope(String requestId, String status, JsonResult payload)
throws JsonPayloadSerializerException {
JsonResultDataType annotation = null;
JsonNode payloadJson = null;
if (payload != null) {
annotation = payload.getClass().getAnnotation(JsonResultDataType.class);
// serialize payload to tree node
payloadJson = mapper.valueToTree(payload);
}
// serialize envelope to tree with inserted payload node
JsonResultEnvelope resultEnvelope =
new JsonResultEnvelope(requestId, status, (annotation != null) ? annotation.value() : "null");
ObjectNode envelopeJson = mapper.valueToTree(resultEnvelope);
if (payloadJson != null)
envelopeJson.set(JsonResultEnvelope.PROPERTY_DATA, payloadJson);
// serialize the envelope tree to a string.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(baos, Charset.forName("UTF-8"));
try {
mapper.writeTree(jsonFactory.createGenerator(osw), envelopeJson);
osw.close();
return new String(baos.toByteArray(), Charset.forName("UTF-8"));
} catch (IOException e) {
throw new JsonPayloadSerializerException("Could not serialize result");
}
}
public static class JsonPayloadSerializerException extends Exception {
private static final long serialVersionUID = 1L;
public JsonPayloadSerializerException(String msg) {
super(msg);
}
}
}