public <T> void registerAdapter(Class<T> klass, BiAdapter adapter) { adapters.put(klass.getCanonicalName(), adapter); String typeName = adapter.typeName(); if (typeName != null) adapters.put(typeName, adapter); revision++; BossBiMapper.recalculateMapper(); }
/** * Try to deserialize map containing serialized object, e.g. having "__type" or "__t" key. Important. Is this * implementation can't deserialize the map, what usually means it has no known/properly serialized object in it, it * juts desearliazes it in place with {@link #deserializeInPlace(Map, BiDeserializer)} and return the same (but * updated) map instance. * * @param map possible containing the serialized object * @param <T> * * @return deserialized object or deserialized map */ public <T> T deserialize(Map map, BiDeserializer deserializer) { String typeName = (String) map.get("__type"); if (typeName == null) typeName = (String) map.get("__t"); if (typeName != null) { BiAdapter adapter = adapters.get(typeName); if (adapter != null) { return (T) adapter.deserialize(Binder.from(map), deserializer); } } deserializeInPlace(map, deserializer); return (T) map; }
/** * Update the map deserialziing it's values - e.g. in place. Saves memory but has strong side effects of discarding * source data. * * @param map to update * @param deserializer to use to deserialize map values */ public void deserializeInPlace(Map map, BiDeserializer deserializer) { map.forEach((key, value) -> { if (value instanceof Map) { String typeName = (String) ((Map) value).get("__type"); if (typeName == null) typeName = (String) ((Map) value).get("__t"); if (typeName == null) deserializeInPlace((Map) value, deserializer); else { BiAdapter adapter = adapters.get(typeName); if (adapter != null) { map.put(key, adapter.deserialize(Binder.from(value), deserializer)); } } } else if (value instanceof Collection) { map.put(key, ((Collection) value).stream() .map(x -> deserializer.deserialize(x)) .collect(Collectors.toList()) ); } }); }
/** * unregister class. All associated adapters will be removed. * * @param klass * * @return true if the class was registered before, wither as {@link BiSerializable} class or with {@link * BiAdapter}. */ public boolean unregister(Class klass) { String key = klass.getCanonicalName(); BiAdapter a = adapters.get(key); if (a == null) return false; adapters.remove(key); key = a.typeName(); if (key != null) adapters.remove(key); revision++; return true; }