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

com.oracle.coherence.io.json.internal.MapConverter Maven / Gradle / Ivy

/*
 * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.oracle.coherence.io.json.internal;

import com.oracle.coherence.io.json.genson.Context;
import com.oracle.coherence.io.json.genson.Converter;
import com.oracle.coherence.io.json.genson.Genson;

import com.oracle.coherence.io.json.genson.annotation.HandleClassMetadata;

import com.oracle.coherence.io.json.genson.reflect.TypeUtil;
import com.oracle.coherence.io.json.genson.stream.ObjectReader;
import com.oracle.coherence.io.json.genson.stream.ObjectWriter;

import java.lang.reflect.Type;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Map converter.
 * 

* NOTE: this {@link Converter} produces a serialization format that is incompatible * with other JSON parsers. * * @param the type of the map keys * @param the type of the map values * * @author Aleks Seovic 2018.05.30 * @since 20.06 */ @HandleClassMetadata public class MapConverter implements Converter> { // ----- constructors --------------------------------------------------- /** * Constructs a new {@code MapConverter} using the provided {@link Converter converters} * to convert keys and values. * * @param convKey the {@link Converter} for keys * @param convValue the {@link Converter} for values */ protected MapConverter(Converter convKey, Converter convValue) { this.f_convKey = convKey; this.f_convValue = convValue; } // ----- Converter interfaces ------------------------------------------- @Override public void serialize(Map object, ObjectWriter writer, Context ctx) throws Exception { writer.beginObject(); boolean isSorted = object instanceof SortedMap; boolean isOrdered = object instanceof LinkedHashMap; if (isSorted) { writer.writeMetadata("sorted", true); } else if (isOrdered) { writer.writeMetadata("ordered", true); } writer.writeName("entries").beginArray(); for (Map.Entry entry : object.entrySet()) { writer.beginObject().writeName("key"); f_convKey.serialize(entry.getKey(), writer, ctx); writer.writeName("value"); f_convValue.serialize(entry.getValue(), writer, ctx); writer.endObject(); } writer.endArray().endObject(); } @Override @SuppressWarnings("unchecked") public Map deserialize(ObjectReader reader, Context ctx) throws Exception { Map map; reader.nextObjectMetadata(); boolean isSorted = (Boolean) reader.metadata().getOrDefault("sorted", false); boolean isOrdered = (Boolean) reader.metadata().getOrDefault("ordered", false); String className = (String) reader.metadata().getOrDefault("class", getMapTypeBasedOnFlags(isSorted, isOrdered)); try { Class> mapClass = (Class>) ctx.genson.classFor(className); map = mapClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { map = isSorted ? new TreeMap<>() : isOrdered ? new LinkedHashMap<>() : new HashMap<>(); } reader.next(); if ("entries".equals(reader.name())) { reader.beginArray(); while (reader.hasNext()) { reader.next(); reader.beginObject(); K key = null; V value = null; while (reader.hasNext()) { reader.next(); if ("key".equals(reader.name())) { key = f_convKey.deserialize(reader, ctx); } else if ("value".equals(reader.name())) { value = f_convValue.deserialize(reader, ctx); } } map.put(key, value); reader.endObject(); } reader.endArray(); } reader.endObject(); return map; } /** * Return the map type (as string) based on the provided flags. * * @param isSorted flag indicating the map should be sorted * @param isOrdered flag indicating the map should be ordered * * @return the map type (as string) based on the provided flags. */ private static String getMapTypeBasedOnFlags(boolean isSorted, boolean isOrdered) { return isSorted ? TreeMap.class.getName() : isOrdered ? LinkedHashMap.class.getName() : HashMap.class.getName(); } /** * A {@link MapConverter} factory. */ public static class Factory implements com.oracle.coherence.io.json.genson.Factory>> { // ----- constructors ----------------------------------------------- /** * Creates a new {@code Factory}. */ protected Factory() { } // ----- Factory interface ------------------------------------------ @Override @SuppressWarnings({"unchecked", "rawtypes"}) public Converter> create(Type type, Genson genson) { Type expandedType = type; if (TypeUtil.getRawClass(type).getTypeParameters().length == 0) { expandedType = TypeUtil.expandType(TypeUtil.lookupGenericType(Map.class, TypeUtil.getRawClass(type)), type); } Type keyType = TypeUtil.typeOf(0, expandedType); Type valueType = TypeUtil.typeOf(1, expandedType); return new MapConverter(genson.provideConverter(keyType), genson.provideConverter(valueType)); } // ----- constants -------------------------------------------------- /** * Singleton {@code Factory} instance. */ public static final Factory INSTANCE = new Factory(); } // ----- data members --------------------------------------------------- /** * The {@link Converter} for the {@link Map} keys. */ protected final Converter f_convKey; /** * The {@link Converter} for the {@link Map} values. */ protected final Converter f_convValue; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy