/*
   * Unit test to test [JACKSON-177]
   */
  public void testHibernateCglib() throws Exception {
    /* 03-Sep-2010, tatu: This often fails form Eclipse (on some platforms like Mac OS X),
     *   so let's only run it from Ant/CLI
     */
    if (!runsFromAnt()) {
      return;
    }

    Enhancer enh = new Enhancer();
    enh.setInterfaces(new Class[] {BeanInterfaceHib.class});
    enh.setCallback(
        new MethodInterceptor() {
          @Override
          public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
              throws Throwable {
            if ("getX".equals(method.getName())) {
              return Integer.valueOf(13);
            }
            return proxy.invokeSuper(obj, args);
          }
        });
    BeanInterfaceHib bean = (BeanInterfaceHib) enh.create();
    ObjectMapper mapper = new ObjectMapper();
    Map<String, Object> result = writeAndMap(mapper, bean);
    assertEquals(1, result.size());
    assertEquals(Integer.valueOf(13), result.get("x"));
  }
 public void testGlobalVisibilityForGetters() {
   ObjectMapper m = new ObjectMapper();
   m.configure(MapperFeature.AUTO_DETECT_GETTERS, false);
   POJOPropertiesCollector coll = collector(m, SimpleGetterVisibility.class, true);
   // should be 1, expect that we disabled getter auto-detection, so
   Map<String, POJOPropertyBuilder> props = coll.getPropertyMap();
   assertEquals(0, props.size());
 }
  @Override
  public boolean isEmpty(SerializerProvider prov, Map<?, ?> value) {
    if (value.isEmpty()) {
      return true;
    }

    // 05-Nove-2015, tatu: Simple cases are cheap, but for recursive
    //   emptiness checking we actually need to see if values are empty as well.
    Object supp = _suppressableValue;
    if ((supp == null) && !_suppressNulls) {
      return false;
    }
    JsonSerializer<Object> valueSer = _valueSerializer;
    final boolean checkEmpty = (MARKER_FOR_EMPTY == supp);
    if (valueSer != null) {
      for (Object elemValue : value.values()) {
        if (elemValue == null) {
          if (_suppressNulls) {
            continue;
          }
          return false;
        }
        if (checkEmpty) {
          if (!valueSer.isEmpty(prov, elemValue)) {
            return false;
          }
        } else if ((supp == null) || !supp.equals(value)) {
          return false;
        }
      }
      return true;
    }
    // But if not statically known, try this:
    for (Object elemValue : value.values()) {
      if (elemValue == null) {
        if (_suppressNulls) {
          continue;
        }
        return false;
      }
      try {
        valueSer = _findSerializer(prov, elemValue);
      } catch (JsonMappingException e) { // Ugh... can not just throw as-is, so...
        // 05-Nov-2015, tatu: For now, probably best not to assume empty then
        return false;
      }
      if (checkEmpty) {
        if (!valueSer.isEmpty(prov, elemValue)) {
          return false;
        }
      } else if ((supp == null) || !supp.equals(value)) {
        return false;
      }
    }
    return true;
  }
 public void testMergeWithRename() {
   POJOPropertiesCollector coll = collector(mapper, MergedProperties.class, true);
   Map<String, POJOPropertyBuilder> props = coll.getPropertyMap();
   assertEquals(1, props.size());
   POJOPropertyBuilder prop = props.get("x");
   assertNotNull(prop);
   assertTrue(prop.hasSetter());
   assertFalse(prop.hasGetter());
   assertTrue(prop.hasField());
 }
 public void testSimpleIgnoreAndRename() {
   POJOPropertiesCollector coll = collector(mapper, IgnoredRenamedSetter.class, true);
   Map<String, POJOPropertyBuilder> props = coll.getPropertyMap();
   assertEquals(1, props.size());
   POJOPropertyBuilder prop = props.get("y");
   assertNotNull(prop);
   assertTrue(prop.hasSetter());
   assertFalse(prop.hasGetter());
   assertFalse(prop.hasField());
 }
 public void testSimpleGetterVisibility() {
   POJOPropertiesCollector coll = collector(mapper, SimpleGetterVisibility.class, true);
   Map<String, POJOPropertyBuilder> props = coll.getPropertyMap();
   assertEquals(1, props.size());
   POJOPropertyBuilder prop = props.get("a");
   assertNotNull(prop);
   assertFalse(prop.hasSetter());
   assertTrue(prop.hasGetter());
   assertFalse(prop.hasField());
 }
 public void testSimpleFieldVisibility() {
   // false -> deserialization
   POJOPropertiesCollector coll = collector(mapper, SimpleFieldDeser.class, false);
   Map<String, POJOPropertyBuilder> props = coll.getPropertyMap();
   assertEquals(1, props.size());
   POJOPropertyBuilder prop = props.get("values");
   assertNotNull(prop);
   assertFalse(prop.hasSetter());
   assertFalse(prop.hasGetter());
   assertTrue(prop.hasField());
 }
 // [Issue#232]
 public void testBigDecimalAsPlainStringTreeConversion() throws Exception {
   ObjectMapper mapper = new ObjectMapper();
   mapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN);
   Map<String, Object> map = new HashMap<String, Object>();
   String PI_STR = "3.00000000";
   map.put("pi", new BigDecimal(PI_STR));
   JsonNode tree = mapper.valueToTree(map);
   assertNotNull(tree);
   assertEquals(1, tree.size());
   assertTrue(tree.has("pi"));
 }
 public void testCollectionOfIgnored() {
   POJOPropertiesCollector coll = collector(mapper, ImplicitIgnores.class, false);
   // should be 1, due to ignorals
   Map<String, POJOPropertyBuilder> props = coll.getPropertyMap();
   assertEquals(1, props.size());
   // but also have 2 ignored properties
   Collection<String> ign = coll.getIgnoredPropertyNames();
   assertEquals(2, ign.size());
   assertTrue(ign.contains("a"));
   assertTrue(ign.contains("b"));
 }
 public void testExplicitIgnoralWithBean() throws Exception {
   IgnoreSome value = new IgnoreSome();
   Map<String, Object> result = writeAndMap(MAPPER, value);
   assertEquals(2, result.size());
   // verify that specified fields are ignored
   assertFalse(result.containsKey("b"));
   assertFalse(result.containsKey("c"));
   // and that others are not
   assertEquals(Integer.valueOf(value.a), result.get("a"));
   assertEquals(value.getD(), result.get("d"));
 }
 public void testExplicitIgnoralWithMap() throws Exception {
   // test simulating need to filter out metadata like class name
   MyMap value = new MyMap();
   value.put("a", "b");
   value.put("@class", MyMap.class.getName());
   Map<String, Object> result = writeAndMap(MAPPER, value);
   assertEquals(1, result.size());
   // verify that specified field is ignored
   assertFalse(result.containsKey("@class"));
   // and that others are not
   assertEquals(value.get("a"), result.get("a"));
 }
 // Check if a value exists before getting it
 // AG
 static Object getFromMap(Object map, String key) {
   if (map instanceof Map<?, ?>) {
     Map<?, ?> castMap = (Map<?, ?>) map;
     if (castMap.containsKey(key)) {
       return castMap.get(key);
     } else {
       return null;
     }
   } else {
     return null;
   }
 }
 public void testSimpleKeyDeser() throws Exception {
   ObjectMapper mapper = new ObjectMapper();
   SimpleModule module = new SimpleModule("test", Version.unknownVersion());
   module.addKeyDeserializer(String.class, new ContextualDeser("???"));
   mapper.registerModule(module);
   MapBean result = mapper.readValue("{\"map\":{\"a\":3}}", MapBean.class);
   Map<String, Integer> map = result.map;
   assertNotNull(map);
   assertEquals(1, map.size());
   Map.Entry<String, Integer> entry = map.entrySet().iterator().next();
   assertEquals(Integer.valueOf(3), entry.getValue());
   assertEquals("map:a", entry.getKey());
 }
 public void testSimpleKeySer() throws Exception {
   ObjectMapper mapper = new ObjectMapper();
   SimpleModule module = new SimpleModule("test", Version.unknownVersion());
   module.addKeySerializer(String.class, new ContextualKeySerializer("prefix"));
   mapper.registerModule(module);
   Map<String, Object> input = new HashMap<String, Object>();
   input.put("a", Integer.valueOf(3));
   String json =
       mapper
           .writerWithType(
               TypeFactory.defaultInstance()
                   .constructMapType(HashMap.class, String.class, Object.class))
           .writeValueAsString(input);
   assertEquals("{\"prefix:a\":3}", json);
 }
  /**
   * 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.
   */
  public void serializeFieldsUsing(
      Map<?, ?> value, JsonGenerator gen, SerializerProvider provider, JsonSerializer<Object> ser)
      throws IOException {
    final JsonSerializer<Object> keySerializer = _keySerializer;
    final Set<String> ignored = _ignoredEntries;
    final TypeSerializer typeSer = _valueTypeSerializer;

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      Object keyElem = entry.getKey();
      if (ignored != null && ignored.contains(keyElem)) continue;

      if (keyElem == null) {
        provider.findNullKeySerializer(_keyType, _property).serialize(null, gen, provider);
      } else {
        keySerializer.serialize(keyElem, gen, provider);
      }
      final Object valueElem = entry.getValue();
      if (valueElem == null) {
        provider.defaultSerializeNull(gen);
      } else {
        try {
          if (typeSer == null) {
            ser.serialize(valueElem, gen, provider);
          } else {
            ser.serializeWithType(valueElem, gen, provider, typeSer);
          }
        } catch (Exception e) {
          wrapAndThrow(provider, e, value, String.valueOf(keyElem));
        }
      }
    }
  }
  // [Issue#41]
  public void testIncorrectDups41() throws Exception {
    final String INPUT = "\"foo\",\"bar\",\"foo\"";
    CsvSchema schema =
        CsvSchema.builder().addColumn("Col1").addColumn("Col2").addColumn("Col3").build();

    MappingIterator<Object> iter = MAPPER.readerFor(Object.class).with(schema).readValues(INPUT);

    Map<?, ?> m = (Map<?, ?>) iter.next();
    assertFalse(iter.hasNextValue());
    iter.close();

    if (m.size() != 3) {
      fail("Should have 3 entries, but got: " + m);
    }
    assertEquals("foo", m.get("Col1"));
    assertEquals("bar", m.get("Col2"));
    assertEquals("foo", m.get("Col3"));
  }
  /**
   * Helper method used when we have a JSON Filter to use for potentially filtering out Map entries.
   *
   * @since 2.5
   */
  public void serializeFilteredFields(
      Map<?, ?> value,
      JsonGenerator gen,
      SerializerProvider provider,
      PropertyFilter filter,
      Object suppressableValue) // since 2.5
      throws IOException {
    final Set<String> ignored = _ignoredEntries;
    final MapProperty prop = new MapProperty(_valueTypeSerializer, _property);
    final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      // First, serialize key; unless ignorable by key
      final Object keyElem = entry.getKey();
      if (ignored != null && ignored.contains(keyElem)) continue;

      JsonSerializer<Object> keySerializer;
      if (keyElem == null) {
        keySerializer = provider.findNullKeySerializer(_keyType, _property);
      } else {
        keySerializer = _keySerializer;
      }
      // or by value; nulls often suppressed
      final Object valueElem = entry.getValue();

      JsonSerializer<Object> valueSer;
      // And then value
      if (valueElem == null) {
        if (_suppressNulls) {
          continue;
        }
        valueSer = provider.getDefaultNullValueSerializer();
      } else {
        valueSer = _valueSerializer;
        if (valueSer == null) {
          valueSer = _findSerializer(provider, valueElem);
        }
        // also may need to skip non-empty values:
        if (checkEmpty) {
          if (valueSer.isEmpty(provider, valueElem)) {
            continue;
          }
        } else if (suppressableValue != null) {
          if (suppressableValue.equals(valueElem)) {
            continue;
          }
        }
      }
      // and with that, ask filter to handle it
      prop.reset(keyElem, keySerializer, valueSer);
      try {
        filter.serializeAsField(valueElem, gen, provider, prop);
      } catch (Exception e) {
        wrapAndThrow(provider, e, value, String.valueOf(keyElem));
      }
    }
  }
  /** Serialization method called when exclusion filtering needs to be applied. */
  public void serializeOptionalFields(
      Map<?, ?> value, JsonGenerator gen, SerializerProvider provider, Object suppressableValue)
      throws IOException {
    // If value type needs polymorphic type handling, some more work needed:
    if (_valueTypeSerializer != null) {
      serializeTypedFields(value, gen, provider, suppressableValue);
      return;
    }
    final Set<String> ignored = _ignoredEntries;
    final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      // First find key serializer
      final Object keyElem = entry.getKey();
      JsonSerializer<Object> keySerializer;
      if (keyElem == null) {
        keySerializer = provider.findNullKeySerializer(_keyType, _property);
      } else {
        if (ignored != null && ignored.contains(keyElem)) continue;
        keySerializer = _keySerializer;
      }

      // Then value serializer
      final Object valueElem = entry.getValue();
      JsonSerializer<Object> valueSer;
      if (valueElem == null) {
        if (_suppressNulls) { // all suppressions include null-suppression
          continue;
        }
        valueSer = provider.getDefaultNullValueSerializer();
      } else {
        valueSer = _valueSerializer;
        if (valueSer == null) {
          valueSer = _findSerializer(provider, valueElem);
        }
        // also may need to skip non-empty values:
        if (checkEmpty) {
          if (valueSer.isEmpty(provider, valueElem)) {
            continue;
          }
        } else if (suppressableValue != null) {
          if (suppressableValue.equals(valueElem)) {
            continue;
          }
        }
      }
      // and then serialize, if all went well
      try {
        keySerializer.serialize(keyElem, gen, provider);
        valueSer.serialize(valueElem, gen, provider);
      } catch (Exception e) {
        wrapAndThrow(provider, e, value, String.valueOf(keyElem));
      }
    }
  }
Exemple #19
0
  /** Method called to serialize fields, when the value type is not statically known. */
  public void serializeFields(Map<?, ?> value, JsonGenerator jgen, SerializerProvider provider)
      throws IOException, JsonGenerationException {
    // If value type needs polymorphic type handling, some more work needed:
    if (_valueTypeSerializer != null) {
      serializeTypedFields(value, jgen, provider);
      return;
    }
    final JsonSerializer<Object> keySerializer = _keySerializer;

    final HashSet<String> ignored = _ignoredEntries;
    final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES);

    PropertySerializerMap serializers = _dynamicValueSerializers;

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      Object valueElem = entry.getValue();
      // First, serialize key
      Object keyElem = entry.getKey();
      if (keyElem == null) {
        provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider);
      } else {
        // [JACKSON-314] skip entries with null values?
        if (skipNulls && valueElem == null) continue;
        // One twist: is entry ignorable? If so, skip
        if (ignored != null && ignored.contains(keyElem)) continue;
        keySerializer.serialize(keyElem, jgen, provider);
      }

      // And then value
      if (valueElem == null) {
        provider.defaultSerializeNull(jgen);
      } else {
        Class<?> cc = valueElem.getClass();
        JsonSerializer<Object> serializer = serializers.serializerFor(cc);
        if (serializer == null) {
          if (_valueType.hasGenericTypes()) {
            serializer =
                _findAndAddDynamic(
                    serializers, provider.constructSpecializedType(_valueType, cc), provider);
          } else {
            serializer = _findAndAddDynamic(serializers, cc, provider);
          }
          serializers = _dynamicValueSerializers;
        }
        try {
          serializer.serialize(valueElem, jgen, provider);
        } catch (Exception e) {
          // [JACKSON-55] Need to add reference information
          String keyDesc = "" + keyElem;
          wrapAndThrow(provider, e, value, keyDesc);
        }
      }
    }
  }
 /**
  * Method called locate all members used for value injection (if any), constructor {@link
  * com.fasterxml.jackson.databind.deser.impl.ValueInjector} instances, and add them to builder.
  */
 protected void addInjectables(
     DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder)
     throws JsonMappingException {
   Map<Object, AnnotatedMember> raw = beanDesc.findInjectables();
   if (raw != null) {
     boolean fixAccess = ctxt.canOverrideAccessModifiers();
     for (Map.Entry<Object, AnnotatedMember> entry : raw.entrySet()) {
       AnnotatedMember m = entry.getValue();
       if (fixAccess) {
         m.fixAccess(); // to ensure we can call it
       }
       builder.addInjectable(
           m.getName(),
           beanDesc.resolveType(m.getGenericType()),
           beanDesc.getClassAnnotations(),
           m,
           entry.getKey());
     }
   }
 }
 protected Map<?, ?> _orderEntries(Map<?, ?> input, JsonGenerator gen, SerializerProvider provider)
     throws IOException {
   // minor optimization: may already be sorted?
   if (input instanceof SortedMap<?, ?>) {
     return input;
   }
   // [databind#1411]: TreeMap does not like null key...
   if (input.containsKey(null)) {
     TreeMap<Object, Object> result = new TreeMap<Object, Object>();
     for (Map.Entry<?, ?> entry : input.entrySet()) {
       Object key = entry.getKey();
       if (key == null) {
         _writeNullKeyedEntry(gen, provider, entry.getValue());
         continue;
       }
       result.put(key, entry.getValue());
     }
     return result;
   }
   return new TreeMap<Object, Object>(input);
 }
 /**
  * Method that will find if bean has any managed- or back-reference properties, and if so add them
  * to bean, to be linked during resolution phase.
  */
 protected void addReferenceProperties(
     DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder)
     throws JsonMappingException {
   // and then back references, not necessarily found as regular properties
   Map<String, AnnotatedMember> refs = beanDesc.findBackReferenceProperties();
   if (refs != null) {
     for (Map.Entry<String, AnnotatedMember> en : refs.entrySet()) {
       String name = en.getKey();
       AnnotatedMember m = en.getValue();
       Type genericType;
       if (m instanceof AnnotatedMethod) {
         genericType = ((AnnotatedMethod) m).getGenericParameterType(0);
       } else {
         genericType = m.getRawType();
       }
       SimpleBeanPropertyDefinition propDef = new SimpleBeanPropertyDefinition(m);
       builder.addBackReferenceProperty(
           name, constructSettableProperty(ctxt, beanDesc, propDef, genericType));
     }
   }
 }
  /** @since 2.5 */
  public void serializeTypedFields(
      Map<?, ?> value,
      JsonGenerator gen,
      SerializerProvider provider,
      Object suppressableValue) // since 2.5
      throws IOException {
    final Set<String> ignored = _ignoredEntries;
    final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      Object keyElem = entry.getKey();
      JsonSerializer<Object> keySerializer;
      if (keyElem == null) {
        keySerializer = provider.findNullKeySerializer(_keyType, _property);
      } else {
        // One twist: is entry ignorable? If so, skip
        if (ignored != null && ignored.contains(keyElem)) continue;
        keySerializer = _keySerializer;
      }
      final Object valueElem = entry.getValue();

      // And then value
      JsonSerializer<Object> valueSer;
      if (valueElem == null) {
        if (_suppressNulls) { // all suppression include null suppression
          continue;
        }
        valueSer = provider.getDefaultNullValueSerializer();
      } else {
        valueSer = _valueSerializer;
        if (valueSer == null) {
          valueSer = _findSerializer(provider, valueElem);
        }
        // also may need to skip non-empty values:
        if (checkEmpty) {
          if (valueSer.isEmpty(provider, valueElem)) {
            continue;
          }
        } else if (suppressableValue != null) {
          if (suppressableValue.equals(valueElem)) {
            continue;
          }
        }
      }
      keySerializer.serialize(keyElem, gen, provider);
      try {
        valueSer.serializeWithType(valueElem, gen, provider, _valueTypeSerializer);
      } catch (Exception e) {
        wrapAndThrow(provider, e, value, String.valueOf(keyElem));
      }
    }
  }
  public void testDetection() throws Exception {
    Map<String, Object> result = writeAndMap(MAPPER, new SimpleBean());
    assertEquals(3, result.size());
    assertEquals("1", result.get("jaxb"));
    assertEquals("2", result.get("jaxb2"));
    assertEquals("3", result.get("jaxb3"));

    result = writeAndMap(MAPPER, new SimpleBean2());
    assertEquals(3, result.size());
    assertEquals("1", result.get("jaxb"));
    assertEquals("2", result.get("jaxb2"));
    assertEquals("3", result.get("jaxb3"));
  }
Exemple #25
0
 @Override
 public void serialize(Map<?, ?> value, JsonGenerator jgen, SerializerProvider provider)
     throws IOException, JsonGenerationException {
   jgen.writeStartObject();
   if (!value.isEmpty()) {
     if (provider.isEnabled(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)) {
       value = _orderEntries(value);
     }
     if (_valueSerializer != null) {
       serializeFieldsUsing(value, jgen, provider, _valueSerializer);
     } else {
       serializeFields(value, jgen, provider);
     }
   }
   jgen.writeEndObject();
 }
Exemple #26
0
  protected void serializeTypedFields(
      Map<?, ?> value, JsonGenerator jgen, SerializerProvider provider)
      throws IOException, JsonGenerationException {
    final JsonSerializer<Object> keySerializer = _keySerializer;
    JsonSerializer<Object> prevValueSerializer = null;
    Class<?> prevValueClass = null;
    final HashSet<String> ignored = _ignoredEntries;
    final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES);

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      Object valueElem = entry.getValue();
      // First, serialize key
      Object keyElem = entry.getKey();
      if (keyElem == null) {
        provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider);
      } else {
        // [JACKSON-314] also may need to skip entries with null values
        if (skipNulls && valueElem == null) continue;
        // One twist: is entry ignorable? If so, skip
        if (ignored != null && ignored.contains(keyElem)) continue;
        keySerializer.serialize(keyElem, jgen, provider);
      }

      // And then value
      if (valueElem == null) {
        provider.defaultSerializeNull(jgen);
      } else {
        Class<?> cc = valueElem.getClass();
        JsonSerializer<Object> currSerializer;
        if (cc == prevValueClass) {
          currSerializer = prevValueSerializer;
        } else {
          currSerializer = provider.findValueSerializer(cc, _property);
          prevValueSerializer = currSerializer;
          prevValueClass = cc;
        }
        try {
          currSerializer.serializeWithType(valueElem, jgen, provider, _valueTypeSerializer);
        } catch (Exception e) {
          // [JACKSON-55] Need to add reference information
          String keyDesc = "" + keyElem;
          wrapAndThrow(provider, e, value, keyDesc);
        }
      }
    }
  }
Exemple #27
0
 @Override
 public void serializeWithType(
     Map<?, ?> value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer)
     throws IOException, JsonGenerationException {
   typeSer.writeTypePrefixForObject(value, jgen);
   if (!value.isEmpty()) {
     if (provider.isEnabled(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)) {
       value = _orderEntries(value);
     }
     if (_valueSerializer != null) {
       serializeFieldsUsing(value, jgen, provider, _valueSerializer);
     } else {
       serializeFields(value, jgen, provider);
     }
   }
   typeSer.writeTypeSuffixForObject(value, jgen);
 }
  /** Test to verify that we can mix "untyped" access as Maps with schema information... */
  public void testSimpleAsMaps() throws Exception {
    CsvSchema schema = MAPPER.schemaFor(FiveMinuteUser.class);
    MappingIterator<Map<?, ?>> it =
        MAPPER.reader(schema).forType(Map.class).readValues("Joe,Smith,MALE,false,");
    assertTrue(it.hasNext());
    Map<?, ?> result = it.nextValue();
    assertEquals(5, result.size());
    assertEquals("Joe", result.get("firstName"));
    assertEquals("Smith", result.get("lastName"));
    assertEquals("MALE", result.get("gender"));
    assertEquals("false", result.get("verified"));
    assertEquals("", result.get("userImage"));

    assertFalse(it.hasNextValue());
    it.close();
  }
 @Override
 public void serialize(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider)
     throws IOException {
   gen.writeStartObject(value);
   if (!value.isEmpty()) {
     if (_sortKeys || provider.isEnabled(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)) {
       value = _orderEntries(value, gen, provider);
     }
     PropertyFilter pf;
     if ((_filterId != null) && (pf = findPropertyFilter(provider, _filterId, value)) != null) {
       serializeFilteredFields(value, gen, provider, pf, _suppressableValue);
     } else if ((_suppressableValue != null) || _suppressNulls) {
       serializeOptionalFields(value, gen, provider, _suppressableValue);
     } else if (_valueSerializer != null) {
       serializeFieldsUsing(value, gen, provider, _valueSerializer);
     } else {
       serializeFields(value, gen, provider);
     }
   }
   gen.writeEndObject();
 }
  /**
   * General-purpose serialization for contents, where we do not necessarily know the value
   * serialization, but we do know that no value suppression is needed (which simplifies processing
   * a bit)
   */
  public void serializeFields(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider)
      throws IOException {
    // If value type needs polymorphic type handling, some more work needed:
    if (_valueTypeSerializer != null) {
      serializeTypedFields(value, gen, provider, null);
      return;
    }
    final JsonSerializer<Object> keySerializer = _keySerializer;
    final Set<String> ignored = _ignoredEntries;
    Object keyElem = null;

    try {
      for (Map.Entry<?, ?> entry : value.entrySet()) {
        Object valueElem = entry.getValue();
        // First, serialize key
        keyElem = entry.getKey();
        if (keyElem == null) {
          provider.findNullKeySerializer(_keyType, _property).serialize(null, gen, provider);
        } else {
          // One twist: is entry ignorable? If so, skip
          if ((ignored != null) && ignored.contains(keyElem)) {
            continue;
          }
          keySerializer.serialize(keyElem, gen, provider);
        }
        // And then value
        if (valueElem == null) {
          provider.defaultSerializeNull(gen);
          continue;
        }
        JsonSerializer<Object> serializer = _valueSerializer;
        if (serializer == null) {
          serializer = _findSerializer(provider, valueElem);
        }
        serializer.serialize(valueElem, gen, provider);
      }
    } catch (Exception e) { // Add reference information
      wrapAndThrow(provider, e, value, String.valueOf(keyElem));
    }
  }