Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.jackson.databind.ser.std;
  
  import java.util.*;
  
  
Standard serializer implementation for serializing {link java.util.Map} types.

Note: about the only configurable setting currently is ability to filter out entries with specified names.

 
 public class MapSerializer
     extends ContainerSerializer<Map<?,?>>
     implements ContextualSerializer
 {
     protected final static JavaType UNSPECIFIED_TYPE = TypeFactory.unknownType();
    
    
Map-valued property being serialized with this instance
 
     protected final BeanProperty _property;
    
    
Set of entries to omit during serialization, if any
 
     protected final HashSet<String_ignoredEntries;

    
Whether static types should be used for serialization of values or not (if not, dynamic runtime type is used)
 
     protected final boolean _valueTypeIsStatic;

    
Declared type of keys
 
     protected final JavaType _keyType;

    
Declared type of contained values
 
     protected final JavaType _valueType;

    
Key serializer to use, if it can be statically determined
 
     protected JsonSerializer<Object_keySerializer;
    
    
Value serializer to use, if it can be statically determined
 
     protected JsonSerializer<Object_valueSerializer;

    
Type identifier serializer used for values, if any.
 
     protected final TypeSerializer _valueTypeSerializer;

    
If value type can not be statically determined, mapping from runtime value types to serializers are stored in this object.
 
     
     /*
     /**********************************************************
     /* Life-cycle
     /**********************************************************
      */
     
     @SuppressWarnings("unchecked")
     protected MapSerializer(HashSet<StringignoredEntries,
             JavaType keyTypeJavaType valueTypeboolean valueTypeIsStatic,
             TypeSerializer vts,
             JsonSerializer<?> keySerializerJsonSerializer<?> valueSerializer)
     {
         super(Map.classfalse);
          = ignoredEntries;
          = keyType;
          = valueType;
          = valueTypeIsStatic;
          = vts;
          = (JsonSerializer<Object>) keySerializer;
          = (JsonSerializer<Object>) valueSerializer;
         = PropertySerializerMap.emptyMap();
         = null;
    }
    @SuppressWarnings("unchecked")
    protected MapSerializer(MapSerializer srcBeanProperty property,
            JsonSerializer<?> keySerializerJsonSerializer<?> valueSerializer,
            HashSet<Stringignored)
    {
        super(Map.classfalse);
         = ignored;
         = src._keyType;
         = src._valueType;
         = src._valueTypeIsStatic;
         = src._valueTypeSerializer;
         = (JsonSerializer<Object>) keySerializer;
         = (JsonSerializer<Object>) valueSerializer;
         = src._dynamicValueSerializers;
         = property;
    }
    protected MapSerializer(MapSerializer srcTypeSerializer vts)
    {
        super(Map.classfalse);
         = src._ignoredEntries;
         = src._keyType;
         = src._valueType;
         = src._valueTypeIsStatic;
         = vts;
         = src._keySerializer;
         = src._valueSerializer;
         = src._dynamicValueSerializers;
         = src._property;
    }
    
    @Override
    {
        return new MapSerializer(thisvts);
    }
    public MapSerializer withResolved(BeanProperty property,
            JsonSerializer<?> keySerializerJsonSerializer<?> valueSerializer,
            HashSet<Stringignored)
    {
        return new MapSerializer(thispropertykeySerializervalueSerializerignored);
    }
    
    public static MapSerializer construct(String[] ignoredListJavaType mapType,
            boolean staticValueTypeTypeSerializer vts,
            JsonSerializer<ObjectkeySerializerJsonSerializer<ObjectvalueSerializer)
    {
        HashSet<StringignoredEntries = toSet(ignoredList);
        JavaType keyTypevalueType;
        
        if (mapType == null) {
            keyType = valueType = ;
        } else { 
            keyType = mapType.getKeyType();
            valueType = mapType.getContentType();
        }
        // If value type is final, it's same as forcing static value typing:
        if (!staticValueType) {
            staticValueType = (valueType != null && valueType.isFinal());
        }
        return new MapSerializer(ignoredEntrieskeyTypevalueTypestaticValueTypevts,
                keySerializervalueSerializer);
    }
    private static HashSet<StringtoSet(String[] ignoredEntries) {
        if (ignoredEntries == null || ignoredEntries.length == 0) {
            return null;
        }
        HashSet<Stringresult = new HashSet<String>(ignoredEntries.length);
        for (String prop : ignoredEntries) {
            result.add(prop);
        }
        return result;
    }
    
    /*
    /**********************************************************
    /* Post-processing (contextualization)
    /**********************************************************
     */
//  @Override
            BeanProperty property)
        throws JsonMappingException
    {
        /* 29-Sep-2012, tatu: Actually, we need to do much more contextual
         *    checking here since we finally know for sure the property,
         *    and it may have overrides
         */
        JsonSerializer<?> ser = null;
        JsonSerializer<?> keySer = null;
        // First: if we have a property, may have property-annotation overrides
        if (property != null) {
            AnnotatedMember m = property.getMember();
            if (m != null) {
                Object serDef;
                final AnnotationIntrospector intr = provider.getAnnotationIntrospector();
                serDef = intr.findKeySerializer(m);
                if (serDef != null) {
                    keySer = provider.serializerInstance(mserDef);
                }
                serDef = intr.findContentSerializer(m);
                if (serDef != null) {
                    ser = provider.serializerInstance(mserDef);
                }
            }
        }
        if (ser == null) {
            ser = ;
        }
        if (ser == null) {
            // 30-Sep-2012, tatu: One more thing -- if explicit content type is annotated,
            //   we can consider it a static case as well.
            if ( || hasContentTypeAnnotation(providerproperty)) {
                ser = provider.findValueSerializer(property);
            }
        } else if (ser instanceof ContextualSerializer) {
            ser = ((ContextualSerializerser).createContextual(providerproperty);
        }
        if (keySer == null) {
            keySer = ;
        }
        if (keySer == null) {
            keySer = provider.findKeySerializer(property);
        } else if (keySer instanceof ContextualSerializer) {
            keySer = ((ContextualSerializerkeySer).createContextual(providerproperty);
        }
        HashSet<Stringignored = this.;
        AnnotationIntrospector intr = provider.getAnnotationIntrospector();
        if (intr != null && property != null) {
            String[] moreToIgnore = intr.findPropertiesToIgnore(property.getMember());
            if (moreToIgnore != null) {
                ignored = (ignored == null) ? new HashSet<String>() : new HashSet<String>(ignored);
                for (String str : moreToIgnore) {
                    ignored.add(str);
                }
            }
        }
        return withResolved(propertykeySerserignored);
    }
    
    /*
    /**********************************************************
    /* Accessors
    /**********************************************************
     */
    @Override
    public JavaType getContentType() {
        return ;
    }
    @Override
    public JsonSerializer<?> getContentSerializer() {
        return ;
    }
    
    @Override
    public boolean isEmpty(Map<?,?> value) {
        return (value == null) || value.isEmpty();
    }
    @Override
    public boolean hasSingleElement(Map<?,?> value) {
        return (value.size() == 1);
    }
    
    /*
    /**********************************************************
    /* Extended API
    /**********************************************************
     */

    
Accessor for currently assigned key serializer. Note that this may return null during construction of MapSerializer: depedencies are resolved during createContextual(com.fasterxml.jackson.databind.SerializerProvider,com.fasterxml.jackson.databind.BeanProperty) method (which can be overridden by custom implementations), but for some dynamic types, it is possible that serializer is only resolved during actual serialization.

Since:
2.0
    public JsonSerializer<?> getKeySerializer() {
        return ;
    }
    
    /*
    /**********************************************************
    /* JsonSerializer implementation
    /**********************************************************
     */
    
    @Override
    public void serialize(Map<?,?> valueJsonGenerator jgenSerializerProvider provider)
        throws IOExceptionJsonGenerationException
    {
        jgen.writeStartObject();
        if (!value.isEmpty()) {
            if (provider.isEnabled(.)) {
                value = _orderEntries(value);
            }
            if ( != null) {
                serializeFieldsUsing(valuejgenprovider);
            } else {
                serializeFields(valuejgenprovider);
            }
        }        
        jgen.writeEndObject();
    }
    @Override
    public void serializeWithType(Map<?,?> valueJsonGenerator jgenSerializerProvider provider,
            TypeSerializer typeSer)
        throws IOExceptionJsonGenerationException
    {
        typeSer.writeTypePrefixForObject(valuejgen);
        if (!value.isEmpty()) {
            if (provider.isEnabled(.)) {
                value = _orderEntries(value);
            }
            if ( != null) {
                serializeFieldsUsing(valuejgenprovider);
            } else {
                serializeFields(valuejgenprovider);
            }
        }
        typeSer.writeTypeSuffixForObject(valuejgen);
    }
    /*
    /**********************************************************
    /* JsonSerializer implementation
    /**********************************************************
     */
    
    
Method called to serialize fields, when the value type is not statically known.
    public void serializeFields(Map<?,?> valueJsonGenerator jgenSerializerProvider provider)
        throws IOExceptionJsonGenerationException
    {
        // If value type needs polymorphic type handling, some more work needed:
        if ( != null) {
            serializeTypedFields(valuejgenprovider);
            return;
        }
        final JsonSerializer<ObjectkeySerializer = ;
        
        final HashSet<Stringignored = ;
        final boolean skipNulls = !provider.isEnabled(.);
        PropertySerializerMap serializers = ;
        for (Map.Entry<?,?> entry : value.entrySet()) {
            Object valueElem = entry.getValue();
            // First, serialize key
            Object keyElem = entry.getKey();
            if (keyElem == null) {
                provider.findNullKeySerializer().serialize(nulljgenprovider);
            } else {
                // [JACKSON-314] skip entries with null values?
                if (skipNulls && valueElem == nullcontinue;
                // One twist: is entry ignorable? If so, skip
                if (ignored != null && ignored.contains(keyElem)) continue;
                keySerializer.serialize(keyElemjgenprovider);
            }
            // And then value
            if (valueElem == null) {
                provider.defaultSerializeNull(jgen);
            } else {
                Class<?> cc = valueElem.getClass();
                JsonSerializer<Objectserializer = serializers.serializerFor(cc);
                if (serializer == null) {
                    if (.hasGenericTypes()) {
                        serializer = _findAndAddDynamic(serializers,
                                provider.constructSpecializedType(cc), provider);
                    } else {
                        serializer = _findAndAddDynamic(serializersccprovider);
                    }
                    serializers = ;
                }
                try {
                    serializer.serialize(valueElemjgenprovider);
                } catch (Exception e) {
                    // [JACKSON-55] Need to add reference information
                    String keyDesc = ""+keyElem;
                    wrapAndThrow(providerevaluekeyDesc);
                }
            }
        }
    }

    
Method called to serialize fields, when the value type is statically known, so that value serializer is passed and does not need to be fetched from provider.
    protected void serializeFieldsUsing(Map<?,?> valueJsonGenerator jgenSerializerProvider provider,
            JsonSerializer<Objectser)
            throws IOExceptionJsonGenerationException
    {
        final JsonSerializer<ObjectkeySerializer = ;
        final HashSet<Stringignored = ;
        final TypeSerializer typeSer = ;
        final boolean skipNulls = !provider.isEnabled(.);
        for (Map.Entry<?,?> entry : value.entrySet()) {
            Object valueElem = entry.getValue();
            Object keyElem = entry.getKey();
            if (keyElem == null) {
                provider.findNullKeySerializer().serialize(nulljgenprovider);
            } else {
                // [JACKSON-314] also may need to skip entries with null values
                if (skipNulls && valueElem == nullcontinue;
                if (ignored != null && ignored.contains(keyElem)) continue;
                keySerializer.serialize(keyElemjgenprovider);
            }
            if (valueElem == null) {
                provider.defaultSerializeNull(jgen);
            } else {
                try {
                    if (typeSer == null) {
                        ser.serialize(valueElemjgenprovider);
                    } else {
                        ser.serializeWithType(valueElemjgenprovidertypeSer);
                    }
                } catch (Exception e) {
                    // [JACKSON-55] Need to add reference information
                    String keyDesc = ""+keyElem;
                    wrapAndThrow(providerevaluekeyDesc);
                }
            }
        }
    }
    protected void serializeTypedFields(Map<?,?> valueJsonGenerator jgenSerializerProvider provider)
        throws IOExceptionJsonGenerationException
    {
        final JsonSerializer<ObjectkeySerializer = ;
        JsonSerializer<ObjectprevValueSerializer = null;
        Class<?> prevValueClass = null;
        final HashSet<Stringignored = ;
        final boolean skipNulls = !provider.isEnabled(.);
    
        for (Map.Entry<?,?> entry : value.entrySet()) {
            Object valueElem = entry.getValue();
            // First, serialize key
            Object keyElem = entry.getKey();
            if (keyElem == null) {
                provider.findNullKeySerializer().serialize(nulljgenprovider);
            } else {
                // [JACKSON-314] also may need to skip entries with null values
                if (skipNulls && valueElem == nullcontinue;
                // One twist: is entry ignorable? If so, skip
                if (ignored != null && ignored.contains(keyElem)) continue;
                keySerializer.serialize(keyElemjgenprovider);
            }
    
            // And then value
            if (valueElem == null) {
                provider.defaultSerializeNull(jgen);
            } else {
                Class<?> cc = valueElem.getClass();
                JsonSerializer<ObjectcurrSerializer;
                if (cc == prevValueClass) {
                    currSerializer = prevValueSerializer;
                } else {
                    currSerializer = provider.findValueSerializer(cc);
                    prevValueSerializer = currSerializer;
                    prevValueClass = cc;
                }
                try {
                    currSerializer.serializeWithType(valueElemjgenprovider);
                } catch (Exception e) {
                    // [JACKSON-55] Need to add reference information
                    String keyDesc = ""+keyElem;
                    wrapAndThrow(providerevaluekeyDesc);
                }
            }
        }
    }
    
    @Override
    public JsonNode getSchema(SerializerProvider providerType typeHint)
    {
        ObjectNode o = createSchemaNode("object"true);
        //(ryan) even though it's possible to statically determine the "value" type of the map,
        // there's no way to statically determine the keys, so the "Entries" can't be determined.
        return o;
    }
    
    @Override
    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitorJavaType typeHint)
    {
    	//jackphel Aug 17 2012 : this can definitely more more exact. 
    	visitor.expectObjectFormat(typeHint);
    }
    /*
    /**********************************************************
    /* Internal helper methods
    /**********************************************************
     */
    
            Class<?> typeSerializerProvider providerthrows JsonMappingException
    {
        PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSerializer(typeprovider);
        // did we get a new map of serializers? If so, start using it
        if (map != result.map) {
             = result.map;
        }
        return result.serializer;
    }
            JavaType typeSerializerProvider providerthrows JsonMappingException
    {
        PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSerializer(typeprovider);
        if (map != result.map) {
             = result.map;
        }
        return result.serializer;
    }
    protected Map<?,?> _orderEntries(Map<?,?> input)
    {
        // minor optimization: may already be sorted?
        if (input instanceof SortedMap<?,?>) {
            return input;
        }
        return new TreeMap<Object,Object>(input);
    }
New to GrepCode? Check out our FAQ X