Class MapResolver


  • public class MapResolver
    extends Object

    The MapResolver converts the raw Maps created from the JsonParser to higher quality Maps representing the implied object graph. It does this by replacing @ref values with the Map indicated by the @id key with the same value.

    This approach 'wires' the original object graph. During the resolution process, if 'peer' classes can be found for given Maps (for example, an @type entry is available which indicates the class that would have been associated to the Map, then the associated class is consulted to help 'improve' the quality of the primitive values within the map fields. For example, if the peer class indicated that a field was of type 'short', and the Map had a long value (JSON only returns long's for integer types), then the long would be converted to a short.

    The final Map representation is a very high-quality graph that represents the original JSON graph. It can be passed as input to JsonWriter, and the JsonWriter will write out the equivalent JSON to what was originally read. This technique allows json-io to be used on a machine that does not have any of the Java classes from the original graph, read it in a JSON graph (any JSON graph), return the equivalent maps, allow mutations of those maps, and finally this graph can be written out.

    Author:
    John DeRegnaucourt ([email protected])
    Copyright (c) Cedar Software LLC

    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.
    • Field Detail

      • missingFields

        protected final Collection<com.cedarsoftware.util.io.Resolver.Missingfields> missingFields
    • Constructor Detail

      • MapResolver

        protected MapResolver​(JsonReader reader)
    • Method Detail

      • traverseFields

        public void traverseFields​(Deque<JsonObject<String,​Object>> stack,
                                   JsonObject<String,​Object> jsonObj)
        Walk the JsonObject fields and perform necessary substitutions so that all references matched up. This code patches @ref and @id pairings up, in the 'Map of Map' mode. Where the JSON may contain an @id of an object which can have more than one @ref to it, this code will make sure that each
        Parameters:
        stack - Stack (Deque) used for graph traversal.
        jsonObj - a Map-of-Map representation of the current object being examined (containing all fields).
      • traverseCollection

        protected void traverseCollection​(Deque<JsonObject<String,​Object>> stack,
                                          JsonObject<String,​Object> jsonObj)
        Process java.util.Collection and it's derivatives. Collections are written specially so that the serialization does not expose the Collection's internal structure, for example a TreeSet. All entries are processed, except unresolved references, which are filled in later. For an indexable collection, the unresolved references are set back into the proper element location. For non-indexable collections (Sets), the unresolved references are added via .add().
        Parameters:
        stack - a Stack (Deque) used to support graph traversal.
        jsonObj - a Map-of-Map representation of the JSON input stream.
      • convertMapsToObjects

        protected Object convertMapsToObjects​(JsonObject<String,​Object> root)
        Walk a JsonObject (Map of String keys to values) and return the Java object equivalent filled in as best as possible (everything except unresolved reference fields or unresolved array/collection elements).
        Parameters:
        root - JsonObject reference to a Map-of-Maps representation of the JSON input after it has been completely read.
        Returns:
        Properly constructed, typed, Java object graph built from a Map of Maps representation (JsonObject root).
      • cleanup

        protected void cleanup()
      • traverseMap

        protected void traverseMap​(Deque<JsonObject<String,​Object>> stack,
                                   JsonObject<String,​Object> jsonObj)
        Process java.util.Map and it's derivatives. These can be written specially so that the serialization would not expose the derivative class internals (internal fields of TreeMap for example).
        Parameters:
        stack - a Stack (Deque) used to support graph traversal.
        jsonObj - a Map-of-Map representation of the JSON input stream.
      • convertMapToKeysItems

        protected static void convertMapToKeysItems​(JsonObject<String,​Object> map)
        Convert an input JsonObject map (known to represent a Map.class or derivative) that has regular keys and values to have its keys placed into @keys, and its values placed into @items.
        Parameters:
        map - Map to convert
      • createJavaObjectInstance

        protected Object createJavaObjectInstance​(Class clazz,
                                                  JsonObject jsonObj)
        This method creates a Java Object instance based on the passed in parameters. If the JsonObject contains a key '@type' then that is used, as the type was explicitly set in the JSON stream. If the key '@type' does not exist, then the passed in Class is used to create the instance, handling creating an Array or regular Object instance.
        The '@type' is not often specified in the JSON input stream, as in many cases it can be inferred from a field reference or array component type.
        Parameters:
        clazz - Instance will be create of this class.
        jsonObj - Map-of-Map representation of object to create.
        Returns:
        a new Java object of the appropriate type (clazz) using the jsonObj to provide enough hints to get the right class instantiated. It is not populated when returned.
      • coerceCertainTypes

        protected Object coerceCertainTypes​(String type)
      • getReferencedObj

        protected JsonObject getReferencedObj​(Long ref)
      • patchUnresolvedReferences

        protected void patchUnresolvedReferences()
        For all fields where the value was "@ref":"n" where 'n' was the id of an object that had not yet been encountered in the stream, make the final substitution.
      • rehashMaps

        protected void rehashMaps()
        Process Maps/Sets (fix up their internal indexing structure) This is required because Maps hash items using hashCode(), which will change between VMs. Rehashing the map fixes this.
        If useMaps==true, then move @keys to keys and @items to values and then drop these two entries from the map.
        This hashes both Sets and Maps because the JDK sets are implemented as Maps. If you have a custom built Set, this would not 'treat' it and you would need to provider a custom reader for that set.
      • notCustom

        protected boolean notCustom​(Class cls)