package cc.blynk.utils; import cc.blynk.server.core.model.DashBoard; import cc.blynk.server.core.model.DashboardSettings; import cc.blynk.server.core.model.Profile; import cc.blynk.server.core.model.auth.App; import cc.blynk.server.core.model.auth.FacebookTokenResponse; import cc.blynk.server.core.model.auth.User; import cc.blynk.server.core.model.device.Device; import cc.blynk.server.core.model.device.Tag; import cc.blynk.server.core.model.widgets.Widget; import cc.blynk.server.core.model.widgets.notifications.Notification; import cc.blynk.server.core.model.widgets.notifications.Twitter; import cc.blynk.server.core.protocol.exceptions.IllegalCommandBodyException; import cc.blynk.server.core.stats.model.Stat; import cc.blynk.utils.serialization.DeviceIgnoreMixIn; import cc.blynk.utils.serialization.NotificationIgnoreMixIn; import cc.blynk.utils.serialization.TwitterIgnoreMixIn; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; import com.fasterxml.jackson.databind.ObjectWriter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.StringJoiner; import java.util.zip.DeflaterOutputStream; /** * User: ddumanskiy * Date: 21.11.13 * Time: 15:31 */ public final class JsonParser { private static final Logger log = LogManager.getLogger(JsonParser.class); //it is threadsafe public static final ObjectMapper mapper = init(); private static final ObjectReader userReader = mapper.readerFor(User.class); private static final ObjectReader profileReader = mapper.readerFor(Profile.class); private static final ObjectReader dashboardReader = mapper.readerFor(DashBoard.class); private static final ObjectReader dashboardSettingsReader = mapper.readerFor(DashboardSettings.class); private static final ObjectReader widgetReader = mapper.readerFor(Widget.class); private static final ObjectReader appReader = mapper.readerFor(App.class); private static final ObjectReader deviceReader = mapper.readerFor(Device.class); private static final ObjectReader tagReader = mapper.readerFor(Tag.class); private static final ObjectReader facebookTokenReader = mapper.readerFor(FacebookTokenResponse.class); private static final ObjectWriter userWriter = mapper.writerFor(User.class); private static final ObjectWriter profileWriter = mapper.writerFor(Profile.class); private static final ObjectWriter dashboardWriter = mapper.writerFor(DashBoard.class); private static final ObjectWriter deviceWriter = mapper.writerFor(Device.class); private static final ObjectWriter appWriter = mapper.writerFor(App.class); public static final ObjectWriter restrictiveDashWriter = init() .addMixIn(Twitter.class, TwitterIgnoreMixIn.class) .addMixIn(Notification.class, NotificationIgnoreMixIn.class) .addMixIn(Device.class, DeviceIgnoreMixIn.class) .writerFor(DashBoard.class); private static final ObjectWriter statWriter = init().writerWithDefaultPrettyPrinter().forType(Stat.class); public static ObjectMapper init() { return new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .setSerializationInclusion(JsonInclude.Include.NON_NULL) .setSerializationInclusion(JsonInclude.Include.NON_EMPTY) .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } public static String toJson(User user) { return toJson(userWriter, user); } public static String toJson(Profile profile) { return toJson(profileWriter, profile); } public static String toJson(DashBoard dashBoard) { return toJson(dashboardWriter, dashBoard); } public static byte[] gzipDash(DashBoard dash) { return writeJsonAsCompressedBytes(dashboardWriter, dash); } public static byte[] gzipDashRestrictive(DashBoard dash) { return writeJsonAsCompressedBytes(restrictiveDashWriter, dash); } public static byte[] gzipProfile(Profile profile) { return writeJsonAsCompressedBytes(profileWriter, profile); } private static byte[] writeJsonAsCompressedBytes(ObjectWriter objectWriter, Object o) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (OutputStream out = new DeflaterOutputStream(baos)) { objectWriter.writeValue(out, o); } catch (Exception e) { log.error("Error compressing data.", e); return null; } return baos.toByteArray(); } public static String toJsonRestrictiveDashboard(DashBoard dashBoard) { return toJson(restrictiveDashWriter, dashBoard); } public static String toJson(Device device) { return toJson(deviceWriter, device); } public static String toJson(App app) { return toJson(appWriter, app); } public static String toJson(Stat stat) { return toJson(statWriter, stat); } public static void writeUser(File file, User user) throws IOException { userWriter.writeValue(file, user); } private static String toJson(ObjectWriter writer, Object o) { try { return writer.writeValueAsString(o); } catch (Exception e) { log.error("Error jsoning object.", e); } return "{}"; } public static String toJson(Object o) { try { return mapper.writeValueAsString(o); } catch (Exception e) { log.error("Error jsoning object.", e); } return null; } public static <T> T readAny(String val, Class<T> c) { try { return mapper.readValue(val, c); } catch (Exception e) { log.error("Error reading json object.", e); } return null; } public static User parseUserFromFile(File userFile) throws IOException { return userReader.readValue(userFile); } public static User parseUserFromString(String userString) throws IOException { return userReader.readValue(userString); } public static Profile parseProfileFromString(String profileString) throws IOException { return profileReader.readValue(profileString); } public static FacebookTokenResponse parseFacebookTokenResponse(String response) throws IOException { return facebookTokenReader.readValue(response); } public static DashboardSettings parseDashboardSettings(String reader) { try { return dashboardSettingsReader.readValue(reader); } catch (IOException e) { log.error(e.getMessage()); throw new IllegalCommandBodyException("Error parsing dashboard settings."); } } public static DashBoard parseDashboard(String reader) { try { return dashboardReader.readValue(reader); } catch (IOException e) { log.error(e.getMessage()); throw new IllegalCommandBodyException("Error parsing dashboard."); } } public static Widget parseWidget(String reader) { try { return widgetReader.readValue(reader); } catch (IOException e) { log.error(e.getMessage()); throw new IllegalCommandBodyException("Error parsing widget."); } } public static App parseApp(String reader) { try { return appReader.readValue(reader); } catch (IOException e) { log.error(e.getMessage()); throw new IllegalCommandBodyException("Error parsing app."); } } public static Device parseDevice(String reader) { try { return deviceReader.readValue(reader); } catch (IOException e) { log.error(e.getMessage()); throw new IllegalCommandBodyException("Error parsing device."); } } public static Tag parseTag(String reader) { try { return tagReader.readValue(reader); } catch (IOException e) { log.error(e.getMessage()); throw new IllegalCommandBodyException("Error parsing tag."); } } public static String valueToJsonAsString(String[] values) { StringJoiner sj = new StringJoiner(",", "[", "]"); for (String value : values) { sj.add(makeJsonStringValue(value)); } return sj.toString(); } public static String valueToJsonAsString(String value) { return "[\"" + value + "\"]"; } private static String makeJsonStringValue(String value) { return "\"" + value + "\""; } }