Class Resolver

java.lang.Object
com.cedarsoftware.io.Resolver
Direct Known Subclasses:
MapResolver, ObjectResolver

public abstract class Resolver extends Object
This class is used to convert a source of Java Maps that were created from the JsonParser. These are in 'raw' form with no 'pointers'. This code will reconstruct the 'shape' of the graph by connecting @ref's to @ids.

The subclasses that override this class can build an object graph using Java classes or a Map-of-Map representation. In both cases, the @ref value will be replaced with the Object (or Map) that had the corresponding @id.

Author:
John DeRegnaucourt (jdereg@gmail.com)
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

License

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 Details

    • stack

      protected final Deque<JsonObject> stack
    • readOptions

      protected ReadOptions readOptions
    • references

      protected ReferenceTracker references
    • converter

      protected final com.cedarsoftware.util.convert.Converter converter
    • returningJavaObjects

      protected final boolean returningJavaObjects
    • missingFieldHandler

      protected final MissingFieldHandler missingFieldHandler
    • unknownTypeClass

      protected final Class<?> unknownTypeClass
    • maxObjectReferences

      protected final int maxObjectReferences
    • maxReferenceChainDepth

      protected final int maxReferenceChainDepth
  • Constructor Details

    • Resolver

      protected Resolver(ReadOptions readOptions, ReferenceTracker references, com.cedarsoftware.util.convert.Converter converter)
  • Method Details

    • getReadOptions

      public ReadOptions getReadOptions()
    • getReferences

      public ReferenceTracker getReferences()
    • getConverter

      public com.cedarsoftware.util.convert.Converter getConverter()
    • readString

      public String readString(JsonObject jsonObj, String fieldName)
      Convenience method for reading a String field from a JsonObject in ClassFactory implementations. Handles type conversion automatically.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the String value, or null if not present or null
    • readInt

      public int readInt(JsonObject jsonObj, String fieldName)
      Convenience method for reading an int field from a JsonObject in ClassFactory implementations. Handles type conversion automatically.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the int value, or 0 if not present or null
    • readLong

      public long readLong(JsonObject jsonObj, String fieldName)
      Convenience method for reading a long field from a JsonObject in ClassFactory implementations. Handles type conversion automatically.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the long value, or 0L if not present or null
    • readFloat

      public float readFloat(JsonObject jsonObj, String fieldName)
      Convenience method for reading a float field from a JsonObject in ClassFactory implementations. Handles type conversion automatically.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the float value, or 0.0f if not present or null
    • readDouble

      public double readDouble(JsonObject jsonObj, String fieldName)
      Convenience method for reading a double field from a JsonObject in ClassFactory implementations. Handles type conversion automatically.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the double value, or 0.0 if not present or null
    • readBoolean

      public boolean readBoolean(JsonObject jsonObj, String fieldName)
      Convenience method for reading a boolean field from a JsonObject in ClassFactory implementations. Handles type conversion automatically.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the boolean value, or false if not present or null
    • readObject

      public <T> T readObject(JsonObject jsonObj, String fieldName, Class<T> type)
      Convenience method for reading a typed object field from a JsonObject in ClassFactory implementations. Handles full deserialization including complex types, cycles, and references.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      type - the target type to convert to
      Returns:
      the fully deserialized object, or null if not present
    • readArray

      public <T> T[] readArray(JsonObject jsonObj, String fieldName, Class<T[]> arrayType)
      Convenience method for reading a typed array field from a JsonObject in ClassFactory implementations. Handles full deserialization including complex types, cycles, and references.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      arrayType - the array type (e.g., String[].class, MyObject[].class)
      Returns:
      the fully deserialized array, or null if not present
    • readList

      public <T> List<T> readList(JsonObject jsonObj, String fieldName)
      Convenience method for reading a List field from a JsonObject in ClassFactory implementations. Handles full deserialization including complex types, cycles, and references.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the fully deserialized List, or null if not present
    • readMap

      public <K, V> Map<K,V> readMap(JsonObject jsonObj, String fieldName)
      Convenience method for reading a Map field from a JsonObject in ClassFactory implementations. Handles full deserialization including complex types, cycles, and references.
      Parameters:
      jsonObj - the JsonObject (typically passed to ClassFactory.newInstance)
      fieldName - the field name to read
      Returns:
      the fully deserialized Map, or null if not present
    • toJava

      public Object toJava(Type type, Object value)
      Resolves a parsed JSON value to a Java object. This is the primary resolution entry point used by ClassFactory implementations and JsonIo for converting parsed JSON into Java objects.
      Parameters:
      type - the target type (may be null to infer from JSON)
      value - the parsed JSON value (JsonObject, array, or primitive)
      Returns:
      the resolved Java object
    • adjustTypeBeforeResolve

      protected void adjustTypeBeforeResolve(JsonObject rootObj, Type rootType)
      Hook for subclasses to adjust the JsonObject's type before resolution begins. Called before instance creation. Default implementation does nothing.
      Parameters:
      rootObj - the JsonObject about to be resolved
      rootType - the expected root type (may be null)
    • reconcileResult

      protected Object reconcileResult(Object result, JsonObject rootObj, Type rootType)
      Hook for subclasses to reconcile the resolved result with the expected type. Called after resolution completes. Default implementation returns result as-is.
      Parameters:
      result - the resolved Java object
      rootObj - the original JsonObject
      rootType - the expected root type (may be null)
      Returns:
      the reconciled result (may be converted or wrapped)
    • traverseJsonObject

      public <T> T traverseJsonObject(JsonObject root)
      Walk a JsonObject (Map of String keys to values) and return the Java object equivalent filled in as good 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).
    • traverseObject

      protected void traverseObject(JsonObject jsonObj)
    • getSealedSupplier

      public SealedSupplier getSealedSupplier()
    • push

      public void push(JsonObject jsonObject)
      Push a JsonObject on the work stack that has not yet had it's fields move over to it's Java peer (.target)
      Parameters:
      jsonObject - JsonObject that supplies the source values for the Java peer (target)
    • traverseFields

      public abstract void traverseFields(JsonObject jsonObj)
    • readWithFactoryIfExists

      protected abstract Object readWithFactoryIfExists(Object o, Type compType)
    • traverseCollection

      protected abstract void traverseCollection(JsonObject jsonObj)
    • traverseArray

      protected abstract void traverseArray(JsonObject jsonObj)
    • addUnresolvedReference

      protected void addUnresolvedReference(com.cedarsoftware.io.Resolver.UnresolvedReference ref)
      Security-aware method to add unresolved references with size limits
    • addMissingField

      protected void addMissingField(Resolver.MissingField field)
      Security-aware method to add missing fields with size limits
    • cleanup

      protected void cleanup()
    • traverseMap

      protected void traverseMap(JsonObject jsonObj)
      Process java.util.Map and it's derivatives. These are written specially so that the serialization does not expose the class internals (internal fields of TreeMap for example).
      Parameters:
      jsonObj - a Map-of-Map representation of the JSON input stream.
    • addMapToRehash

      protected void addMapToRehash(JsonObject jsonObj)
      Add a JsonObject to the list of maps that need rehashing after resolution. This is called by subclasses that override traverseMap() to ensure proper map population via rehashMaps().
    • valueToTarget

      public boolean valueToTarget(JsonObject jsonObject)
    • setArrayElement

      protected void setArrayElement(Object array, int index, Object element)
    • isDirectlyAddableJsonValue

      protected static boolean isDirectlyAddableJsonValue(Object element)
      Checks if the given element is a native JSON value that can be added directly to a collection without further processing. These are the types that JsonParser produces directly from raw JSON:
      • String - from JSON strings
      • Boolean - from JSON true/false
      • Long - from JSON integers
      • Double - from JSON decimals
      • BigInteger - from JSON integers too large for Long
      • BigDecimal - from JSON decimals when configured for high precision
      Note: Arrays are NOT included because they require traversal of their elements. Note: AtomicLong/AtomicInteger/AtomicBoolean are NOT included because JsonParser never produces them directly - they require @type information.
      Parameters:
      element - the element to check
      Returns:
      true if the element can be added directly to a collection without processing
    • wrapArrayAndAddToCollection

      protected void wrapArrayAndAddToCollection(Object[] arrayElement, Type componentType, Collection<Object> col)
      Wraps a raw Object[] array element in a JsonObject, creates its instance, adds it to the collection, and pushes it onto the stack for further processing. This pattern is used when encountering array elements within collections that need to be converted to typed arrays.
      Parameters:
      arrayElement - the raw Object[] to wrap
      componentType - the type for the array elements
      col - the collection to add the created array instance to
    • setArrayElement

      protected static void setArrayElement(Object array, Object[] refArray, int index, Object value, boolean isPrimitive)
      Sets an array element, handling both primitive and reference arrays. This consolidates the repeated pattern of conditionally using ArrayUtilities.setPrimitiveElement() vs direct array assignment.
      Parameters:
      array - the primitive array (used when isPrimitive is true)
      refArray - the reference array (used when isPrimitive is false)
      index - the array index to set
      value - the value to assign
      isPrimitive - true if dealing with a primitive array
    • markFinishedIfNot

      protected static boolean markFinishedIfNot(JsonObject jsonObj)
      Checks if the JsonObject is already finished. If not, marks it as finished. This consolidates the common guard pattern used at the start of traverse methods.
      Parameters:
      jsonObj - the JsonObject to check and mark
      Returns:
      true if the object was already finished (caller should return early), false otherwise
    • ensureCollectionCapacity

      protected static void ensureCollectionCapacity(Collection<?> col, int size)
      Ensures the collection has sufficient capacity if it's an ArrayList. This avoids repeated array resizing during bulk additions.
      Parameters:
      col - the collection to potentially resize
      size - the expected number of elements
    • resolveReference

      protected JsonObject resolveReference(JsonObject jsonObj)
      Resolves a reference JsonObject to the actual referenced JsonObject. Returns null if the jsonObj is not a reference.
      Parameters:
      jsonObj - the JsonObject that may be a reference (@ref)
      Returns:
      the referenced JsonObject, or null if jsonObj is not a reference
    • resolveReferenceInCollection

      protected void resolveReferenceInCollection(JsonObject refHolder, JsonObject parent, Collection<Object> col, int idx, boolean isList)
      Resolves a reference within a collection context. If the referenced object's target is already available, adds it to the collection. Otherwise, registers an unresolved reference to be patched later.
      Parameters:
      refHolder - the JsonObject containing the reference
      parent - the parent JsonObject (for unresolved reference tracking)
      col - the collection to add the resolved target to
      idx - the index in the collection (for unresolved reference tracking)
      isList - true if the collection is index-addressable (List)
    • addResolvedObjectToCollection

      protected void addResolvedObjectToCollection(JsonObject jObj, Collection<Object> col)
      Processes a resolved JsonObject and adds it to a collection. Handles traversal for referenceable types and special EnumSet handling.
      Parameters:
      jObj - the resolved JsonObject to add
      col - the collection to add to
    • convertIfNonRefType

      protected Object convertIfNonRefType(JsonObject jsonObj, Class<?> type)
      Converts a JsonObject to its target type if the type is a non-referenceable class and the Converter supports the conversion from Map. This is used in Maps mode to convert JsonObjects with simple types (UUID, ZonedDateTime, etc.) to their Java equivalents.
      Parameters:
      jsonObj - the JsonObject to potentially convert
      type - the target type (typically from jsonObj.getRawType())
      Returns:
      the converted object if conversion was performed, null otherwise
    • resolveArray

      protected abstract Object resolveArray(Type suggestedType, List<Object> list)