Package com.cedarsoftware.io
Class Resolver
java.lang.Object
com.cedarsoftware.io.Resolver
- Direct Known Subclasses:
MapResolver,ObjectResolver
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.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classDefault implementation of ReferenceTracker.protected static classstores missing fields information to notify client after the complete deserialization resolution -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final com.cedarsoftware.util.convert.Converterprotected final intprotected final intprotected final MissingFieldHandlerprotected ReadOptionsprotected ReferenceTrackerprotected final booleanprotected final Deque<JsonObject>protected final Class<?> -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedResolver(ReadOptions readOptions, ReferenceTracker references, com.cedarsoftware.util.convert.Converter converter) -
Method Summary
Modifier and TypeMethodDescriptionprotected voidaddMapToRehash(JsonObject jsonObj) Add a JsonObject to the list of maps that need rehashing after resolution.protected voidSecurity-aware method to add missing fields with size limitsprotected voidaddResolvedObjectToCollection(JsonObject jObj, Collection<Object> col) Processes a resolved JsonObject and adds it to a collection.protected voidaddUnresolvedReference(com.cedarsoftware.io.Resolver.UnresolvedReference ref) Security-aware method to add unresolved references with size limitsprotected voidadjustTypeBeforeResolve(JsonObject rootObj, Type rootType) Hook for subclasses to adjust the JsonObject's type before resolution begins.protected voidcleanup()protected ObjectconvertIfNonRefType(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.protected static voidensureCollectionCapacity(Collection<?> col, int size) Ensures the collection has sufficient capacity if it's an ArrayList.com.cedarsoftware.util.convert.Converterprotected static booleanisDirectlyAddableJsonValue(Object element) Checks if the given element is a native JSON value that can be added directly to a collection without further processing.protected static booleanmarkFinishedIfNot(JsonObject jsonObj) Checks if the JsonObject is already finished.voidpush(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)<T> T[]readArray(JsonObject jsonObj, String fieldName, Class<T[]> arrayType) Convenience method for reading a typed array field from a JsonObject in ClassFactory implementations.booleanreadBoolean(JsonObject jsonObj, String fieldName) Convenience method for reading a boolean field from a JsonObject in ClassFactory implementations.doublereadDouble(JsonObject jsonObj, String fieldName) Convenience method for reading a double field from a JsonObject in ClassFactory implementations.floatreadFloat(JsonObject jsonObj, String fieldName) Convenience method for reading a float field from a JsonObject in ClassFactory implementations.intreadInt(JsonObject jsonObj, String fieldName) Convenience method for reading an int field from a JsonObject in ClassFactory implementations.<T> List<T>readList(JsonObject jsonObj, String fieldName) Convenience method for reading a List field from a JsonObject in ClassFactory implementations.longreadLong(JsonObject jsonObj, String fieldName) Convenience method for reading a long field from a JsonObject in ClassFactory implementations.<K,V> Map<K, V> readMap(JsonObject jsonObj, String fieldName) Convenience method for reading a Map field from a JsonObject in ClassFactory implementations.<T> TreadObject(JsonObject jsonObj, String fieldName, Class<T> type) Convenience method for reading a typed object field from a JsonObject in ClassFactory implementations.readString(JsonObject jsonObj, String fieldName) Convenience method for reading a String field from a JsonObject in ClassFactory implementations.protected abstract ObjectreadWithFactoryIfExists(Object o, Type compType) protected ObjectreconcileResult(Object result, JsonObject rootObj, Type rootType) Hook for subclasses to reconcile the resolved result with the expected type.protected abstract ObjectresolveArray(Type suggestedType, List<Object> list) protected JsonObjectresolveReference(JsonObject jsonObj) Resolves a reference JsonObject to the actual referenced JsonObject.protected voidresolveReferenceInCollection(JsonObject refHolder, JsonObject parent, Collection<Object> col, int idx, boolean isList) Resolves a reference within a collection context.protected voidsetArrayElement(Object array, int index, Object element) protected static voidsetArrayElement(Object array, Object[] refArray, int index, Object value, boolean isPrimitive) Sets an array element, handling both primitive and reference arrays.Resolves a parsed JSON value to a Java object.protected abstract voidtraverseArray(JsonObject jsonObj) protected abstract voidtraverseCollection(JsonObject jsonObj) abstract voidtraverseFields(JsonObject jsonObj) <T> TtraverseJsonObject(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).protected voidtraverseMap(JsonObject jsonObj) Process java.util.Map and it's derivatives.protected voidtraverseObject(JsonObject jsonObj) booleanvalueToTarget(JsonObject jsonObject) protected voidwrapArrayAndAddToCollection(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.
-
Field Details
-
stack
-
readOptions
-
references
-
converter
protected final com.cedarsoftware.util.convert.Converter converter -
returningJavaObjects
protected final boolean returningJavaObjects -
missingFieldHandler
-
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
-
getReferences
-
getConverter
public com.cedarsoftware.util.convert.Converter getConverter() -
readString
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
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
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
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
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
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
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 readtype- the target type to convert to- Returns:
- the fully deserialized object, or null if not present
-
readArray
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 readarrayType- the array type (e.g., String[].class, MyObject[].class)- Returns:
- the fully deserialized array, or null if not present
-
readList
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
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
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
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 resolvedrootType- the expected root type (may be null)
-
reconcileResult
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 objectrootObj- the original JsonObjectrootType- the expected root type (may be null)- Returns:
- the reconciled result (may be converted or wrapped)
-
traverseJsonObject
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
-
getSealedSupplier
-
push
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
-
readWithFactoryIfExists
-
traverseCollection
-
traverseArray
-
addUnresolvedReference
protected void addUnresolvedReference(com.cedarsoftware.io.Resolver.UnresolvedReference ref) Security-aware method to add unresolved references with size limits -
addMissingField
Security-aware method to add missing fields with size limits -
cleanup
protected void cleanup() -
traverseMap
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
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
-
setArrayElement
-
isDirectlyAddableJsonValue
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
- 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 wrapcomponentType- the type for the array elementscol- 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 setvalue- the value to assignisPrimitive- true if dealing with a primitive array
-
markFinishedIfNot
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
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 resizesize- the expected number of elements
-
resolveReference
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 referenceparent- the parent JsonObject (for unresolved reference tracking)col- the collection to add the resolved target toidx- the index in the collection (for unresolved reference tracking)isList- true if the collection is index-addressable (List)
-
addResolvedObjectToCollection
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 addcol- the collection to add to
-
convertIfNonRefType
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 converttype- the target type (typically from jsonObj.getRawType())- Returns:
- the converted object if conversion was performed, null otherwise
-
resolveArray
-