/* * Copyright 2011-16 Fraunhofer ISE * * This file is part of OpenMUC. * For more information visit http://www.openmuc.org * * OpenMUC 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 3 of the License, or * (at your option) any later version. * * OpenMUC 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 OpenMUC. If not, see <http://www.gnu.org/licenses/>. * */ package org.openmuc.framework.lib.json; import java.util.List; import org.openmuc.framework.config.ChannelConfig; import org.openmuc.framework.config.ChannelScanInfo; import org.openmuc.framework.config.DeviceConfig; import org.openmuc.framework.config.DeviceScanInfo; import org.openmuc.framework.config.DriverConfig; import org.openmuc.framework.config.DriverInfo; import org.openmuc.framework.data.Flag; import org.openmuc.framework.data.Record; import org.openmuc.framework.data.Value; import org.openmuc.framework.data.ValueType; import org.openmuc.framework.dataaccess.Channel; import org.openmuc.framework.dataaccess.DeviceState; import org.openmuc.framework.lib.json.restObjects.RestChannelConfig; import org.openmuc.framework.lib.json.restObjects.RestChannelConfigMapper; import org.openmuc.framework.lib.json.restObjects.RestDeviceConfig; import org.openmuc.framework.lib.json.restObjects.RestDeviceConfigMapper; import org.openmuc.framework.lib.json.restObjects.RestDriverConfig; import org.openmuc.framework.lib.json.restObjects.RestDriverConfigMapper; import org.openmuc.framework.lib.json.restObjects.RestRecord; import org.openmuc.framework.lib.json.restObjects.RestScanProgressInfo; import org.openmuc.framework.lib.json.restObjects.RestUserConfig; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; public class ToJson { private final Gson gson; private final JsonObject jsonObject; public ToJson() { GsonBuilder gsonBuilder = new GsonBuilder().serializeSpecialFloatingPointValues(); gson = gsonBuilder.create(); jsonObject = new JsonObject(); } public JsonObject getJsonObject() { return jsonObject; } public void addJsonObject(String propertyName, JsonObject jsonObject) { this.jsonObject.add(propertyName, jsonObject); } @Override public String toString() { return gson.toJson(jsonObject); } public void addRecord(Record record, ValueType valueType) throws ClassCastException { jsonObject.add(Const.RECORD, getRecordAsJsonElement(record, valueType)); } public void addRecordList(List<Record> recordList, ValueType valueType) throws ClassCastException { JsonArray jsa = new JsonArray(); if (recordList != null) { for (Record record : recordList) { jsa.add(getRecordAsJsonElement(record, valueType)); } } jsonObject.add(Const.RECORDS, jsa); } public void addChannelRecordList(List<Channel> channels) throws ClassCastException { JsonArray jsa = new JsonArray(); for (Channel channel : channels) { jsa.add(channelRecordToJson(channel)); } jsonObject.add(Const.RECORDS, jsa); } public void addDeviceState(DeviceState deviceState) { jsonObject.addProperty(Const.STATE, deviceState.name()); } public void addNumber(String propertyName, Number value) { jsonObject.addProperty(propertyName, value); } public void addBoolean(String propertyName, boolean value) { jsonObject.addProperty(propertyName, value); } public void addString(String propertyName, String value) { jsonObject.addProperty(propertyName, value); } public void addStringList(String propertyName, List<String> stringList) { jsonObject.add(propertyName, gson.toJsonTree(stringList).getAsJsonArray()); } public void addDriverList(List<DriverConfig> driverConfigList) { JsonArray jsa = new JsonArray(); for (DriverConfig driverConfig : driverConfigList) { jsa.add(gson.toJsonTree(driverConfig.getId())); } jsonObject.add(Const.DRIVERS, jsa); } public void addDeviceList(List<DeviceConfig> deviceConfigList) { JsonArray jsa = new JsonArray(); for (DeviceConfig deviceConfig : deviceConfigList) { jsa.add(gson.toJsonTree(deviceConfig.getId())); } jsonObject.add(Const.DEVICES, jsa); } public void addChannelList(List<Channel> channelList) { JsonArray jsa = new JsonArray(); for (Channel channelConfig : channelList) { jsa.add(gson.toJsonTree(channelConfig.getId())); } jsonObject.add(Const.CHANNELS, jsa); } public void addDriverInfo(DriverInfo driverInfo) { jsonObject.add(Const.INFOS, gson.toJsonTree(driverInfo)); } public void addDriverConfig(DriverConfig config) { RestDriverConfig restConfig = RestDriverConfigMapper.getRestDriverConfig(config); jsonObject.add(Const.CONFIGS, gson.toJsonTree(restConfig, RestDriverConfig.class).getAsJsonObject()); } public void addDeviceConfig(DeviceConfig config) { RestDeviceConfig restConfig = RestDeviceConfigMapper.getRestDeviceConfig(config); jsonObject.add(Const.CONFIGS, gson.toJsonTree(restConfig, RestDeviceConfig.class).getAsJsonObject()); } public void addChannelConfig(ChannelConfig config) { RestChannelConfig restConfig = RestChannelConfigMapper.getRestChannelConfig(config); jsonObject.add(Const.CONFIGS, gson.toJsonTree(restConfig, RestChannelConfig.class).getAsJsonObject()); } public void addDeviceScanProgressInfo(RestScanProgressInfo restScanProgressInfo) { jsonObject.add(Const.SCAN_PROGRESS_INFO, gson.toJsonTree(restScanProgressInfo)); } public void addDeviceScanInfoList(List<DeviceScanInfo> deviceScanInfoList) { JsonArray jsa = new JsonArray(); for (DeviceScanInfo deviceScanInfo : deviceScanInfoList) { JsonObject jso = new JsonObject(); jso.addProperty(Const.ID, deviceScanInfo.getId()); jso.addProperty(Const.DEVICEADDRESS, deviceScanInfo.getDeviceAddress()); jso.addProperty(Const.SETTINGS, deviceScanInfo.getSettings()); jso.addProperty(Const.DESCRIPTION, deviceScanInfo.getDescription()); jsa.add(jso); } jsonObject.add(Const.DEVICES, jsa); } public void addChannelScanInfoList(List<ChannelScanInfo> channelScanInfoList) { JsonArray jsa = new JsonArray(); for (ChannelScanInfo channelScanInfo : channelScanInfoList) { JsonObject jso = new JsonObject(); jso.addProperty(Const.CHANNELADDRESS, channelScanInfo.getChannelAddress()); jso.addProperty(Const.VALUETYPE, channelScanInfo.getValueType().name()); jso.addProperty(Const.VALUETYPELENGTH, channelScanInfo.getValueTypeLength()); jso.addProperty(Const.DESCRIPTION, channelScanInfo.getDescription()); jso.addProperty(Const.METADATA, channelScanInfo.getMetaData()); jsa.add(jso); } jsonObject.add(Const.CHANNELS, jsa); } public void addRestUserConfig(RestUserConfig restUserConfig) { jsonObject.add(Const.CONFIGS, gson.toJsonTree(restUserConfig, RestUserConfig.class).getAsJsonObject()); } public static JsonObject getDriverConfigAsJsonObject(DriverConfig config) { RestDriverConfig restConfig = RestDriverConfigMapper.getRestDriverConfig(config); Gson gson = new Gson(); return gson.toJsonTree(restConfig, RestDriverConfig.class).getAsJsonObject(); } public static JsonObject getDeviceConfigAsJsonObject(DeviceConfig config) { RestDeviceConfig restConfig = RestDeviceConfigMapper.getRestDeviceConfig(config); Gson gson = new Gson(); return gson.toJsonTree(restConfig, RestDeviceConfig.class).getAsJsonObject(); } public static JsonObject getChannelConfigAsJsonObject(ChannelConfig config) { RestChannelConfig restConfig = RestChannelConfigMapper.getRestChannelConfig(config); Gson gson = new Gson(); return gson.toJsonTree(restConfig, RestChannelConfig.class).getAsJsonObject(); } private JsonObject channelRecordToJson(Channel channel) throws ClassCastException { JsonObject jso = new JsonObject(); jso.addProperty(Const.ID, channel.getId()); jso.addProperty(Const.VALUETYPE, channel.getValueType().toString()); jso.add(Const.RECORD, getRecordAsJsonElement(channel.getLatestRecord(), channel.getValueType())); return jso; } private JsonElement getRecordAsJsonElement(Record record, ValueType valueType) throws ClassCastException { return gson.toJsonTree(getRestRecord(record, valueType), RestRecord.class); } private RestRecord getRestRecord(Record rc, ValueType valueType) throws ClassCastException { Value value = rc.getValue(); Flag flag = rc.getFlag(); RestRecord rrc = new RestRecord(); rrc.setTimestamp(rc.getTimestamp()); flag = handleInfinityAndNaNValue(value, valueType, flag); if (flag != Flag.VALID) { rrc.setFlag(flag); rrc.setValue(null); return rrc; } rrc.setFlag(flag); setRestRecordValue(valueType, value, rrc); return rrc; } private void setRestRecordValue(ValueType valueType, Value value, RestRecord rrc) throws ClassCastException { if (value == null) { rrc.setValue(null); } else { switch (valueType) { case FLOAT: rrc.setValue(value.asFloat()); break; case DOUBLE: rrc.setValue(value.asDouble()); break; case SHORT: rrc.setValue(value.asShort()); break; case INTEGER: rrc.setValue(value.asInt()); break; case LONG: rrc.setValue(value.asLong()); break; case BYTE: rrc.setValue(value.asByte()); break; case BOOLEAN: rrc.setValue(value.asBoolean()); break; case BYTE_ARRAY: rrc.setValue(value.asByteArray()); break; case STRING: rrc.setValue(value.asString()); break; default: rrc.setValue(null); break; } } } private Flag handleInfinityAndNaNValue(Value value, ValueType valueType, Flag flag) { if (value != null) { switch (valueType) { case DOUBLE: if (Double.isInfinite(value.asDouble())) { return Flag.VALUE_IS_INFINITY; } else if (Double.isNaN(value.asDouble())) { return Flag.VALUE_IS_NAN; } break; case FLOAT: if (Float.isInfinite(value.asFloat())) { return Flag.VALUE_IS_INFINITY; } else if (Float.isNaN(value.asFloat())) { return Flag.VALUE_IS_NAN; } break; default: // is not a floating point number return flag; } } return flag; } }