@Override
 public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
     throws JsonMappingException {
   // May need to resolve types for delegate-based creators:
   JsonDeserializer<Object> delegate = null;
   if (_valueInstantiator != null) {
     AnnotatedWithParams delegateCreator = _valueInstantiator.getDelegateCreator();
     if (delegateCreator != null) {
       JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
       delegate = findDeserializer(ctxt, delegateType, property);
     }
   }
   JsonDeserializer<?> valueDeser = _valueDeserializer;
   if (valueDeser == null) {
     // #125: May have a content converter
     valueDeser = findConvertingContentDeserializer(ctxt, property, valueDeser);
     if (valueDeser == null) {
       // And we may also need to get deserializer for String
       valueDeser =
           ctxt.findContextualValueDeserializer(_collectionType.getContentType(), property);
     }
   } else { // if directly assigned, probably not yet contextual, so:
     valueDeser = ctxt.handleSecondaryContextualization(valueDeser, property);
   }
   if (isDefaultDeserializer(valueDeser)) {
     valueDeser = null;
   }
   return withResolved(delegate, valueDeser);
 }
Example #2
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);
        }
      }
    }
  }
 public EnumMapDeserializer(
     JavaType mapType,
     KeyDeserializer keyDeserializer,
     JsonDeserializer<?> valueDeser,
     TypeDeserializer valueTypeDeser) {
   super(mapType);
   _mapType = mapType;
   _enumClass = mapType.getKeyType().getRawClass();
   _keyDeserializer = keyDeserializer;
   _valueDeserializer = (JsonDeserializer<Object>) valueDeser;
   _valueTypeDeserializer = valueTypeDeser;
 }
  /** @since 2.8 */
  public static MapSerializer construct(
      Set<String> ignoredEntries,
      JavaType mapType,
      boolean staticValueType,
      TypeSerializer vts,
      JsonSerializer<Object> keySerializer,
      JsonSerializer<Object> valueSerializer,
      Object filterId) {
    JavaType keyType, valueType;

    if (mapType == null) {
      keyType = valueType = UNSPECIFIED_TYPE;
    } 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());
    } else {
      // also: Object.class can not be handled as static, ever
      if (valueType.getRawClass() == Object.class) {
        staticValueType = false;
      }
    }
    MapSerializer ser =
        new MapSerializer(
            ignoredEntries,
            keyType,
            valueType,
            staticValueType,
            vts,
            keySerializer,
            valueSerializer);
    if (filterId != null) {
      ser = ser.withFilterId(filterId);
    }
    return ser;
  }
 private final JsonSerializer<Object> _findSerializer(SerializerProvider provider, Object value)
     throws JsonMappingException {
   final Class<?> cc = value.getClass();
   JsonSerializer<Object> valueSer = _dynamicValueSerializers.serializerFor(cc);
   if (valueSer != null) {
     return valueSer;
   }
   if (_valueType.hasGenericTypes()) {
     return _findAndAddDynamic(
         _dynamicValueSerializers, provider.constructSpecializedType(_valueType, cc), provider);
   }
   return _findAndAddDynamic(_dynamicValueSerializers, cc, provider);
 }
  @Override
  public EnumMap<?, ?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
    // Ok: must point to START_OBJECT
    if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
      return _deserializeFromEmpty(jp, ctxt);
    }
    EnumMap result = constructMap();
    final JsonDeserializer<Object> valueDes = _valueDeserializer;
    final TypeDeserializer typeDeser = _valueTypeDeserializer;

    while ((jp.nextToken()) == JsonToken.FIELD_NAME) {
      String keyName = jp.getCurrentName(); // just for error message
      // but we need to let key deserializer handle it separately, nonetheless
      Enum<?> key = (Enum<?>) _keyDeserializer.deserializeKey(keyName, ctxt);
      if (key == null) {
        if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
          throw ctxt.weirdStringException(
              keyName,
              _enumClass,
              "value not one of declared Enum instance names for " + _mapType.getKeyType());
        }
        /* 24-Mar-2012, tatu: Null won't work as a key anyway, so let's
         *  just skip the entry then. But we must skip the value as well, if so.
         */
        jp.nextToken();
        jp.skipChildren();
        continue;
      }
      // And then the value...
      JsonToken t = jp.nextToken();
      /* note: MUST check for nulls separately: deserializers will
       * not handle them (and maybe fail or return bogus data)
       */
      Object value;

      try {
        if (t == JsonToken.VALUE_NULL) {
          value = valueDes.getNullValue(ctxt);
        } else if (typeDeser == null) {
          value = valueDes.deserialize(jp, ctxt);
        } else {
          value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
        }
      } catch (Exception e) {
        wrapAndThrow(e, result, keyName);
        return null;
      }
      result.put(key, value);
    }
    return result;
  }
 /**
  * Method called to finalize setup of this deserializer, when it is known for which property
  * deserializer is needed for.
  */
 @Override
 public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
     throws JsonMappingException {
   // note: instead of finding key deserializer, with enums we actually
   // work with regular deserializers (less code duplication; but not
   // quite as clean as it ought to be)
   KeyDeserializer kd = _keyDeserializer;
   if (kd == null) {
     kd = ctxt.findKeyDeserializer(_mapType.getKeyType(), property);
   }
   JsonDeserializer<?> vd = _valueDeserializer;
   final JavaType vt = _mapType.getContentType();
   if (vd == null) {
     vd = ctxt.findContextualValueDeserializer(vt, property);
   } else { // if directly assigned, probably not yet contextual, so:
     vd = ctxt.handleSecondaryContextualization(vd, property, vt);
   }
   TypeDeserializer vtd = _valueTypeDeserializer;
   if (vtd != null) {
     vtd = vtd.forProperty(property);
   }
   return withResolved(kd, vd, vtd);
 }
Example #8
0
  public static MapSerializer construct(
      String[] ignoredList,
      JavaType mapType,
      boolean staticValueType,
      TypeSerializer vts,
      JsonSerializer<Object> keySerializer,
      JsonSerializer<Object> valueSerializer) {
    HashSet<String> ignoredEntries = toSet(ignoredList);
    JavaType keyType, valueType;

    if (mapType == null) {
      keyType = valueType = UNSPECIFIED_TYPE;
    } 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(
        ignoredEntries, keyType, valueType, staticValueType, vts, keySerializer, valueSerializer);
  }
  /**
   * Helper method called when current token is no START_ARRAY. Will either throw an exception, or
   * try to handle value as if member of implicit array, depending on configuration.
   */
  private final Collection<String> handleNonArray(
      JsonParser jp, DeserializationContext ctxt, Collection<String> result) throws IOException {
    // [JACKSON-526]: implicit arrays from single values?
    if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) {
      throw ctxt.mappingException(_collectionType.getRawClass());
    }
    // Strings are one of "native" (intrinsic) types, so there's never type deserializer involved
    JsonDeserializer<String> valueDes = _valueDeserializer;
    JsonToken t = jp.getCurrentToken();

    String value;

    if (t == JsonToken.VALUE_NULL) {
      value = (valueDes == null) ? null : valueDes.getNullValue();
    } else {
      value = (valueDes == null) ? _parseString(jp, ctxt) : valueDes.deserialize(jp, ctxt);
    }
    result.add(value);
    return result;
  }
 @Override
 public JavaType getContentType() {
   return _mapType.getContentType();
 }
 @Override
 public JavaType getContentType() {
   return _collectionType.getContentType();
 }
  @Override
  public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property)
      throws JsonMappingException {
    JsonSerializer<?> ser = null;
    JsonSerializer<?> keySer = null;
    final AnnotationIntrospector intr = provider.getAnnotationIntrospector();
    final AnnotatedMember propertyAcc = (property == null) ? null : property.getMember();

    // First: if we have a property, may have property-annotation overrides
    if ((propertyAcc != null) && (intr != null)) {
      Object serDef = intr.findKeySerializer(propertyAcc);
      if (serDef != null) {
        keySer = provider.serializerInstance(propertyAcc, serDef);
      }
      serDef = intr.findContentSerializer(propertyAcc);
      if (serDef != null) {
        ser = provider.serializerInstance(propertyAcc, serDef);
      }
    }
    if (ser == null) {
      ser = _valueSerializer;
    }
    // [databind#124]: May have a content converter
    ser = findContextualConvertingSerializer(provider, property, 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.
      // 20-Aug-2013, tatu: Need to avoid trying to access serializer for java.lang.Object tho
      if (_valueTypeIsStatic && !_valueType.isJavaLangObject()) {
        ser = provider.findValueSerializer(_valueType, property);
      }
    }
    if (keySer == null) {
      keySer = _keySerializer;
    }
    if (keySer == null) {
      keySer = provider.findKeySerializer(_keyType, property);
    } else {
      keySer = provider.handleSecondaryContextualization(keySer, property);
    }
    Set<String> ignored = _ignoredEntries;
    boolean sortKeys = false;
    if ((intr != null) && (propertyAcc != null)) {
      JsonIgnoreProperties.Value ignorals = intr.findPropertyIgnorals(propertyAcc);
      if (ignorals != null) {
        Set<String> newIgnored = ignorals.findIgnoredForSerialization();
        if ((newIgnored != null) && !newIgnored.isEmpty()) {
          ignored = (ignored == null) ? new HashSet<String>() : new HashSet<String>(ignored);
          for (String str : newIgnored) {
            ignored.add(str);
          }
        }
      }
      Boolean b = intr.findSerializationSortAlphabetically(propertyAcc);
      sortKeys = (b != null) && b.booleanValue();
    }
    JsonFormat.Value format = findFormatOverrides(provider, property, Map.class);
    if (format != null) {
      Boolean B = format.getFeature(JsonFormat.Feature.WRITE_SORTED_MAP_ENTRIES);
      if (B != null) {
        sortKeys = B.booleanValue();
      }
    }
    MapSerializer mser = withResolved(property, keySer, ser, ignored, sortKeys);

    // [databind#307]: allow filtering
    if (property != null) {
      AnnotatedMember m = property.getMember();
      if (m != null) {
        Object filterId = intr.findFilterId(m);
        if (filterId != null) {
          mser = mser.withFilterId(filterId);
        }
      }
      JsonInclude.Value inclV = property.findPropertyInclusion(provider.getConfig(), null);
      if (inclV != null) {
        JsonInclude.Include incl = inclV.getContentInclusion();

        if (incl != JsonInclude.Include.USE_DEFAULTS) {
          Object valueToSuppress;
          boolean suppressNulls;
          switch (incl) {
            case NON_DEFAULT:
              valueToSuppress = BeanUtil.getDefaultValue(_valueType);
              suppressNulls = true;
              if (valueToSuppress != null) {
                if (valueToSuppress.getClass().isArray()) {
                  valueToSuppress = ArrayBuilders.getArrayComparator(valueToSuppress);
                }
              }
              break;
            case NON_ABSENT:
              suppressNulls = true;
              valueToSuppress = _valueType.isReferenceType() ? MARKER_FOR_EMPTY : null;
              break;
            case NON_EMPTY:
              suppressNulls = true;
              valueToSuppress = MARKER_FOR_EMPTY;
              break;
            case CUSTOM:
              valueToSuppress = provider.includeFilterInstance(null, inclV.getContentFilter());
              if (valueToSuppress == null) { // is this legal?
                suppressNulls = true;
              } else {
                suppressNulls = provider.includeFilterSuppressNulls(valueToSuppress);
              }
              break;
            case NON_NULL:
              valueToSuppress = null;
              suppressNulls = true;
              break;
            case ALWAYS: // default
            default:
              valueToSuppress = null;
              // 30-Sep-2016, tatu: Should not need to check global flags here,
              //   if inclusion forced to be ALWAYS
              suppressNulls = false;
              break;
          }
          mser = mser.withContentInclusion(valueToSuppress, suppressNulls);
        }
      }
    }
    return mser;
  }