Merging.java

package tools.jackson.datatype.fastutil.util;

import java.util.Collection;
import java.util.Map;

import tools.jackson.core.JacksonException;

import tools.jackson.databind.DatabindException;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.util.ClassUtil;

/**
 * Helper for merging deserialized content into existing containers (with
 * {@code @JsonMerge} or {@code ObjectReader.readerForUpdating()}): collections
 * get elements added, maps get entries added (replacing, not merging, existing values).
 *<p>
 * Internal API: not exported from the module.
 */
public final class Merging
{
    private Merging() { }

    // Content may be `null` (like from an empty String, if coerced so): nothing to add

    @SuppressWarnings("unchecked")
    public static <C> C addAll(DeserializationContext ctxt, C intoValue, Collection<?> elements)
        throws JacksonException
    {
        if (elements == null) {
            return intoValue;
        }
        try {
            ((Collection<Object>) intoValue).addAll(elements);
        } catch (UnsupportedOperationException e) {
            throw failure(ctxt, intoValue, e);
        }
        return intoValue;
    }

    @SuppressWarnings("unchecked")
    public static <M> M putAll(DeserializationContext ctxt, M intoValue, Map<?, ?> entries)
        throws JacksonException
    {
        if (entries == null) {
            return intoValue;
        }
        try {
            ((Map<Object, Object>) intoValue).putAll(entries);
        } catch (UnsupportedOperationException e) {
            throw failure(ctxt, intoValue, e);
        }
        return intoValue;
    }

    /**
     * @return Exception to throw when adding to the existing value fails, since it
     *    may be unmodifiable (like one from {@code IntLists.unmodifiable()})
     */
    public static DatabindException failure(DeserializationContext ctxt, Object intoValue,
            UnsupportedOperationException e)
    {
        // fastutil's exceptions usually have no message
        final String detail = ClassUtil.exceptionMessage(e);
        return DatabindException.from(ctxt, String.format(
                "Cannot merge into value of type %s (unmodifiable?)%s",
                ClassUtil.classNameOf(intoValue), (detail == null) ? "" : ": " + detail), e);
    }
}