net.solarnetwork.node.reactor.io.json.JsonReactorSerializationService.java Source code

Java tutorial

Introduction

Here is the source code for net.solarnetwork.node.reactor.io.json.JsonReactorSerializationService.java

Source

/* ==================================================================
 * JsonReactorSerializationService.java - Aug 25, 2014 4:52:05 PM
 * 
 * Copyright 2007-2014 SolarNetwork.net Dev Team
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation; either version 2 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 
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
 * 02111-1307 USA
 * ==================================================================
 */

package net.solarnetwork.node.reactor.io.json;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import net.solarnetwork.node.reactor.Instruction;
import net.solarnetwork.node.reactor.ReactorSerializationService;
import net.solarnetwork.node.reactor.support.BasicInstruction;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * JSON-based IO support for ReactorService.
 * 
 * @author matt
 * @version 1.1
 */
public class JsonReactorSerializationService implements ReactorSerializationService {

    private ObjectMapper objectMapper = defaultObjectMapper();

    private static ObjectMapper defaultObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS'Z'");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        mapper.setDateFormat(sdf);
        return mapper;
    }

    @Override
    public List<Instruction> decodeInstructions(String instructorId, Object in, String type,
            Map<String, ?> properties) {
        if (!"application/json".equalsIgnoreCase(type)) {
            throw new IllegalArgumentException("The [" + type + "] is not supported.");
        }

        if (in instanceof JsonNode) {
            try {
                return decodeInstructions(instructorId, (JsonNode) in);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            throw new IllegalArgumentException("The data object [" + in + "] is not supported.");
        }
    }

    private List<Instruction> decodeInstructions(String instructorId, JsonNode root) throws IOException {
        List<Instruction> results = new ArrayList<Instruction>();
        if (root.isArray()) {
            for (JsonNode child : root) {
                Instruction instr = decodeInstruction(instructorId, child);
                if (instr != null) {
                    results.add(instr);
                }
            }
        }
        return results;
    }

    private String getStringFieldValue(JsonNode node, String fieldName, String placeholder) {
        JsonNode child = node.get(fieldName);
        return (child == null ? placeholder : child.asText());
    }

    /**
     * Decode a single instruction. Example JSON:
     * 
     * <pre>
     * {
     *    "topic" : "Mock/Topic",
     *    "id" : "1",
     *    "instructionDate" : "2014-01-01 12:00:00.000Z",
     *    "parameters" : [
     *       { "name" : "foo", "value" : "bar" }
     *    ]
     * }
     * </pre>
     * 
     * @param instructorId
     *        the instructor ID
     * @param node
     *        the JSON node
     * @return the Instruction, or <em>null</em> if unable to parse
     */
    private Instruction decodeInstruction(String instructorId, JsonNode node) {
        final String topic = getStringFieldValue(node, "topic", null);
        final String instructionId = getStringFieldValue(node, "id", null);
        final String instructionDate = getStringFieldValue(node, "instructionDate", null);
        final Date date = (instructionDate == null ? null : objectMapper.convertValue(instructionDate, Date.class));

        BasicInstruction result = new BasicInstruction(topic, date, instructionId, instructorId, null);

        JsonNode params = node.get("parameters");
        if (params != null && params.isArray()) {
            for (JsonNode p : params) {
                String paramName = getStringFieldValue(p, "name", null);
                String paramValue = getStringFieldValue(p, "value", null);
                if (paramName != null) {
                    result.addParameter(paramName, paramValue);
                }
            }
        }

        return result;
    }

    @Override
    public Object encodeInstructions(Collection<Instruction> instructions, String type, Map<String, ?> properties) {
        throw new UnsupportedOperationException();
    }

    public ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

}