All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.telekom.m2m.cot.restsdk.util.ExtensibleObjectSerializer Maven / Gradle / Ivy

package com.telekom.m2m.cot.restsdk.util;

import java.lang.reflect.Type;
import java.sql.Date;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.time.ZonedDateTime;

import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.telekom.m2m.cot.restsdk.inventory.ManagedObject;
import com.telekom.m2m.cot.restsdk.users.DevicePermission;

/**
 * Created by Patrick Steinert on 31.01.16.
 */
public class ExtensibleObjectSerializer implements JsonSerializer, JsonDeserializer {

    private DateTimeFormatter oneLetterISO8601TimeZoneDTF = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
    private DateTimeFormatter twoLetterISO8601TimeZoneDTF = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXX");
    private DateTimeFormatter threeLetterISO8601TimeZoneDTF = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

    @Override
    public JsonElement serialize(ExtensibleObject src, Type typeOfSrc,
                                 JsonSerializationContext context) {
        if (src == null) {
            return null;
        }

        JsonObject object = new JsonObject();
        Map attributes = src.getAttributes();
        for (Map.Entry entry : attributes.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if ("source".equals(key) && (value instanceof ManagedObject)) {
                JsonPrimitive primitive = new JsonPrimitive(((ManagedObject) value).getId());
                JsonObject sourceObject = new JsonObject();
                sourceObject.add("id", primitive);
                object.add(key, sourceObject);
                continue;
            }
            // devicePermissions contain a list of DevicePermission objects which are not extending ExtensibleObject class
            // and should be handled separately
            if("devicePermissions".equals(key)) {
                JsonObject sourceObject = new JsonObject();
                for (Map.Entry> permissionsEntry : ((Map>)value).entrySet()) {
                    JsonArray permissions = new JsonArray();
                    for(DevicePermission permission : permissionsEntry.getValue()) {
                        JsonPrimitive jsonPermission = new JsonPrimitive(permission.toString());
                        permissions.add(jsonPermission);
                    }
                    sourceObject.add(permissionsEntry.getKey(), permissions);
                }
                object.add(key, sourceObject);
                continue;
            }
            object.add(key, context.serialize(value));
        }
        return object;

    }

    @Override
    public ExtensibleObject deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {

        JsonObject object = jsonElement.getAsJsonObject();
        ExtensibleObject mo = new ExtensibleObject();

        Iterator> objectElementIterator = object.entrySet().iterator();
        while (objectElementIterator.hasNext()) {
            Map.Entry element = objectElementIterator.next();
            String key = element.getKey();
            JsonElement value = element.getValue();

            try {
                Class foundClass = Class.forName(key.replace('_', '.'));
                if (foundClass != null) {
                    mo.set(key, jsonDeserializationContext.deserialize(value, foundClass));
                    continue;
                }
            } catch (ClassNotFoundException e) {
            }

            JsonPrimitive tmp;

            if (value.isJsonPrimitive()) {
                tmp = (JsonPrimitive) value;
                Object converted = null;
                if (tmp.isBoolean()) {
                    converted = tmp.getAsBoolean();
                } else if (tmp.isString()) {
                    try {
                        String tmpString = tmp.getAsString();
                        ZonedDateTime zonedDateTime = null;
                        // in the CoT plattform the stored date time objects has different formatted time zones
                        switch(tmpString.length()) {
                            case 24:
                                // e.g. 2017-09-05T17:19:32.601Z
                            case 26:
                                // e.g. 2017-09-05T17:19:32.601+02
                                zonedDateTime = ZonedDateTime.parse(tmp.getAsString(), oneLetterISO8601TimeZoneDTF);
                                break;
                            case 28:
                                // e.g. 2017-09-05T17:19:32.601+0200
                                zonedDateTime = ZonedDateTime.parse(tmp.getAsString(), twoLetterISO8601TimeZoneDTF);
                                break;
                            case 29:
                                // e.g. 2017-09-05T17:19:32.601+02:00
                                zonedDateTime = ZonedDateTime.parse(tmp.getAsString(), threeLetterISO8601TimeZoneDTF);
                                break;
                            default:
                                converted = tmp.getAsString();
                        }
                        if (zonedDateTime != null) {
                            converted = Date.from(zonedDateTime.toInstant());
                        }
                    } catch (DateTimeParseException e) {
                        converted = tmp.getAsString();
                    }

                } else if (tmp.isNumber()) {
                    converted = tmp.getAsNumber();
                }
                mo.set(key, converted);
            } else if (value.isJsonObject()) {
                // Special case for User to avoid crappy nested ExtensibleObjects...
                if (key.equals("devicePermissions")) {
                    mo.set(key, deserializeDevicePermissions((JsonObject)value));
                } else {
                    mo.set(key, jsonDeserializationContext.deserialize(value, type));
                }
            } else if (value.isJsonArray()) {
                // Some of the library fragments are arrays, but they don't need special treatment because all
                // fragments are stored as simple JsonElements in the ExtensibleObject, and not as themselves.
                // We just list them for documentation purposes, in case someone wants to change that in the future.
                switch (key) {
                    case "c8y_SoftwareList":
                    case "c8y_SupportedOperations":
                    default:
                        mo.set(key, value);
                }
            }
        }

        return mo;
    }


    /**
     * Special method to deserialize the devicePermissions of a User which look like this:
     * {"deviceId" : ["*:*:*", "ALARM:*:READ"], "deviceId" : ["*:*:*"]}
     */
    private Map> deserializeDevicePermissions(JsonObject object) {
        Map> permissions = new HashMap<>();
        for (Map.Entry entry : object.entrySet()) {
            List devicePermissions = new ArrayList<>();
            JsonArray value = (JsonArray)entry.getValue();
            for (JsonElement permission : value) {
                devicePermissions.add(new DevicePermission(permission.getAsString()));
            }
            permissions.put(entry.getKey(), devicePermissions);
        }
        return permissions;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy