public JsonSerializer<?> findSerializer(
      SerializationConfig config, JavaType type, BeanDescription beanDesc) {
    final Class<?> rawType = type.getRawClass();

    if (_jdk7Helper != null) {
      Class<?> path = _jdk7Helper.getClassJavaNioFilePath();
      if (path.isAssignableFrom(rawType)) {
        return ToStringSerializer.instance;
      }
    }
    if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
      return (JsonSerializer<?>) instantiate(SERIALIZER_FOR_DOM_NODE);
    }
    String className = rawType.getName();
    String factoryName;
    if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
        || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
      factoryName = SERIALIZERS_FOR_JAVAX_XML;
    } else {
      return null;
    }

    Object ob = instantiate(factoryName);
    if (ob == null) { // could warn, if we had logging system (j.u.l?)
      return null;
    }
    return ((Serializers) ob).findSerializer(config, type, beanDesc);
  }
 protected EndpointConfig add(Annotation[] annotations, boolean forWriting) {
   // Same as [issue-10] with JSON provider; must check for null:
   if (annotations != null) {
     for (Annotation annotation : annotations) {
       Class<?> type = annotation.annotationType();
       if (type == JsonView.class) {
         // Can only use one view; but if multiple defined, use first (no exception)
         Class<?>[] views = ((JsonView) annotation).value();
         _activeView = (views.length > 0) ? views[0] : null;
       } else if (type == JsonRootName.class) {
         _rootName = ((JsonRootName) annotation).value();
       } else if (type == JacksonFeatures.class) {
         JacksonFeatures feats = (JacksonFeatures) annotation;
         if (forWriting) {
           _serEnable = nullIfEmpty(feats.serializationEnable());
           _serDisable = nullIfEmpty(feats.serializationDisable());
         } else {
           _deserEnable = nullIfEmpty(feats.deserializationEnable());
           _deserDisable = nullIfEmpty(feats.deserializationDisable());
         }
       } else if (type == JacksonAnnotationsInside.class) {
         // skip; processed below (in parent), so encountering here is of no use
       } else {
         // For all unrecognized types, check meta-annotation(s) to see if they are bundles
         JacksonAnnotationsInside inside = type.getAnnotation(JacksonAnnotationsInside.class);
         if (inside != null) {
           add(type.getAnnotations(), forWriting);
         }
       }
     }
   }
   return this;
 }
  public JsonDeserializer<?> findDeserializer(
      JavaType type, DeserializationConfig config, BeanDescription beanDesc)
      throws JsonMappingException {
    final Class<?> rawType = type.getRawClass();

    if (_jdk7Helper != null) {
      JsonDeserializer<?> deser = _jdk7Helper.getDeserializerForJavaNioFilePath(rawType);
      if (deser != null) {
        return deser;
      }
    }
    if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
      return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_NODE);
    }
    if ((CLASS_DOM_DOCUMENT != null) && CLASS_DOM_DOCUMENT.isAssignableFrom(rawType)) {
      return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT);
    }
    String className = rawType.getName();
    String factoryName;
    if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
        || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
      factoryName = DESERIALIZERS_FOR_JAVAX_XML;
    } else {
      return null;
    }
    Object ob = instantiate(factoryName);
    if (ob == null) { // could warn, if we had logging system (j.u.l?)
      return null;
    }
    return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc);
  }
  /**
   * Helper method called to construct and initialize instance of {@link TypeResolverBuilder} if
   * given annotated element indicates one is needed.
   */
  @SuppressWarnings("deprecation")
  protected TypeResolverBuilder<?> _findTypeResolver(
      MapperConfig<?> config, Annotated ann, JavaType baseType) {
    // First: maybe we have explicit type resolver?
    TypeResolverBuilder<?> b;
    JsonTypeInfo info = _findAnnotation(ann, JsonTypeInfo.class);
    JsonTypeResolver resAnn = _findAnnotation(ann, JsonTypeResolver.class);

    if (resAnn != null) {
      if (info == null) {
        return null;
      }
      /* let's not try to force access override (would need to pass
       * settings through if we did, since that's not doable on some
       * platforms)
       */
      b = config.typeResolverBuilderInstance(ann, resAnn.value());
    } else { // if not, use standard one, if indicated by annotations
      if (info == null) {
        return null;
      }
      // bit special; must return 'marker' to block use of default typing:
      if (info.use() == JsonTypeInfo.Id.NONE) {
        return _constructNoTypeResolverBuilder();
      }
      b = _constructStdTypeResolverBuilder();
    }
    // Does it define a custom type id resolver?
    JsonTypeIdResolver idResInfo = _findAnnotation(ann, JsonTypeIdResolver.class);
    TypeIdResolver idRes =
        (idResInfo == null) ? null : config.typeIdResolverInstance(ann, idResInfo.value());
    if (idRes != null) { // [JACKSON-359]
      idRes.init(baseType);
    }
    b = b.init(info.use(), idRes);
    /* 13-Aug-2011, tatu: One complication wrt [JACKSON-453]; external id
     *   only works for properties; so if declared for a Class, we will need
     *   to map it to "PROPERTY" instead of "EXTERNAL_PROPERTY"
     */
    JsonTypeInfo.As inclusion = info.include();
    if (inclusion == JsonTypeInfo.As.EXTERNAL_PROPERTY && (ann instanceof AnnotatedClass)) {
      inclusion = JsonTypeInfo.As.PROPERTY;
    }
    b = b.inclusion(inclusion);
    b = b.typeProperty(info.property());
    Class<?> defaultImpl = info.defaultImpl();

    // 08-Dec-2014, tatu: To deprecated `JsonTypeInfo.None` we need to use other placeholder(s);
    //   and since `java.util.Void` has other purpose (to indicate "deser as null"), we'll instead
    //   use `JsonTypeInfo.class` itself. But any annotation type will actually do, as they have no
    //   valid use (can not instantiate as default)
    if (defaultImpl != JsonTypeInfo.None.class && !defaultImpl.isAnnotation()) {
      b = b.defaultImpl(defaultImpl);
    }
    b = b.typeIdVisibility(info.visible());
    return b;
  }
 /**
  * Since 2.7 we only need to check for class extension, as all implemented types are classes, not
  * interfaces. This has performance implications for some cases, as we do not need to go over
  * interfaces implemented, just superclasses
  *
  * @since 2.7
  */
 private boolean hasSuperClassStartingWith(Class<?> rawType, String prefix) {
   for (Class<?> supertype = rawType.getSuperclass();
       supertype != null;
       supertype = supertype.getSuperclass()) {
     if (supertype == Object.class) {
       return false;
     }
     if (supertype.getName().startsWith(prefix)) {
       return true;
     }
   }
   return false;
 }
  protected void verifyNonDup(AnnotatedWithParams newOne, int typeIndex, boolean explicit) {
    final int mask = (1 << typeIndex);
    _hasNonDefaultCreator = true;
    AnnotatedWithParams oldOne = _creators[typeIndex];
    // already had an explicitly marked one?
    if (oldOne != null) {
      boolean verify;

      if ((_explicitCreators & mask) != 0) { // already had explicitly annotated, leave as-is
        // but skip, if new one not annotated
        if (!explicit) {
          return;
        }
        // both explicit: verify
        verify = true;
      } else {
        // otherwise only verify if neither explicitly annotated.
        verify = !explicit;
      }

      // one more thing: ok to override in sub-class
      if (verify && (oldOne.getClass() == newOne.getClass())) {
        // [databind#667]: avoid one particular class of bogus problems
        Class<?> oldType = oldOne.getRawParameterType(0);
        Class<?> newType = newOne.getRawParameterType(0);

        if (oldType == newType) {
          throw new IllegalArgumentException(
              "Conflicting "
                  + TYPE_DESCS[typeIndex]
                  + " creators: already had explicitly marked "
                  + oldOne
                  + ", encountered "
                  + newOne);
        }
        // otherwise, which one to choose?
        if (newType.isAssignableFrom(oldType)) {
          // new type more generic, use old
          return;
        }
        // new type more specific, use it
      }
    }
    if (explicit) {
      _explicitCreators |= mask;
    }
    _creators[typeIndex] = _fixAccess(newOne);
  }
  @Override
  public JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef)
      throws JsonMappingException {

    if (serDef == null) {
      return null;
    }
    JsonSerializer<?> ser;

    if (serDef instanceof JsonSerializer) {
      ser = (JsonSerializer<?>) serDef;
    } else {
      /* Alas, there's no way to force return type of "either class
       * X or Y" -- need to throw an exception after the fact
       */
      if (!(serDef instanceof Class)) {
        throw new IllegalStateException(
            "AnnotationIntrospector returned serializer definition of type "
                + serDef.getClass().getName()
                + "; expected type JsonSerializer or Class<JsonSerializer> instead");
      }
      Class<?> serClass = (Class<?>) serDef;
      // there are some known "no class" markers to consider too:
      if (serClass == JsonSerializer.None.class || serClass == NoClass.class) {
        return null;
      }
      if (!JsonSerializer.class.isAssignableFrom(serClass)) {
        throw new IllegalStateException(
            "AnnotationIntrospector returned Class "
                + serClass.getName()
                + "; expected Class<JsonSerializer>");
      }
      HandlerInstantiator hi = _config.getHandlerInstantiator();
      if (hi != null) {
        ser = hi.serializerInstance(_config, annotated, serClass);
      } else {
        ser =
            (JsonSerializer<?>)
                ClassUtil.createInstance(serClass, _config.canOverrideAccessModifiers());
      }
    }
    return (JsonSerializer<Object>) _handleResolvable(ser);
  }
 private Object instantiate(String className) {
   try {
     return Class.forName(className).newInstance();
   } catch (LinkageError e) {
   }
   // too many different kinds to enumerate here:
   catch (Exception e) {
   }
   return null;
 }
 /**
  * Helper method used to skip processing for types that we know can not be (i.e. are never
  * consider to be) beans: things like primitives, Arrays, Enums, and proxy types.
  *
  * <p>Note that usually we shouldn't really be getting these sort of types anyway; but better safe
  * than sorry.
  */
 protected boolean isPotentialBeanType(Class<?> type) {
   String typeStr = ClassUtil.canBeABeanType(type);
   if (typeStr != null) {
     throw new IllegalArgumentException(
         "Can not deserialize Class " + type.getName() + " (of type " + typeStr + ") as a Bean");
   }
   if (ClassUtil.isProxyType(type)) {
     throw new IllegalArgumentException(
         "Can not deserialize Proxy class " + type.getName() + " as a Bean");
   }
   /* also: can't deserialize some local classes: static are ok; in-method not;
    * and with [JACKSON-594], other non-static inner classes are ok
    */
   typeStr = ClassUtil.isLocalType(type, true);
   if (typeStr != null) {
     throw new IllegalArgumentException(
         "Can not deserialize Class " + type.getName() + " (of type " + typeStr + ") as a Bean");
   }
   return true;
 }
Ejemplo n.º 10
0
  @SuppressWarnings("unchecked")
  public static <T> T convert(Context context, Class<T> type) {
    if (type.isAssignableFrom(Context.class)) {
      return (T) context;
    }
    if (type.isAssignableFrom(Map.class)) {
      return (T) context.keyValues();
    }
    if (isUrlEncodedForm(context)) {
      return convertValue(context.keyValues(), type);
    }

    String json;
    try {
      json = context.request().getContent();
    } catch (IOException e) {
      throw new IllegalArgumentException("Unable read request content", e);
    }

    return fromJson(json, type);
  }
 /**
  * The method to be called by {@link ObjectMapper} and {@link ObjectWriter} to generate <a
  * href="http://json-schema.org/">JSON schema</a> for given type.
  *
  * @param type The type for which to generate schema
  */
 public JsonSchema generateJsonSchema(Class<?> type) throws JsonMappingException {
   if (type == null) {
     throw new IllegalArgumentException("A class must be provided");
   }
   /* no need for embedded type information for JSON schema generation (all
    * type information it needs is accessible via "untyped" serializer)
    */
   JsonSerializer<Object> ser = findValueSerializer(type, null);
   JsonNode schemaNode =
       (ser instanceof SchemaAware)
           ? ((SchemaAware) ser).getSchema(this, null)
           : JsonSchema.getDefaultSchemaNode();
   if (!(schemaNode instanceof ObjectNode)) {
     throw new IllegalArgumentException(
         "Class "
             + type.getName()
             + " would not be serialized as a JSON object and therefore has no schema");
   }
   return new JsonSchema((ObjectNode) schemaNode);
 }
  /**
   * Method called to see if given method has annotations that indicate a more specific type than
   * what the argument specifies. If annotations are present, they must specify compatible Class;
   * instance of which can be assigned using the method. This means that the Class has to be raw
   * class of type, or its sub-class (or, implementing class if original Class instance is an
   * interface).
   *
   * @param a Method or field that the type is associated with
   * @param type Type derived from the setter argument
   * @return Original type if no annotations are present; or a more specific type derived from it if
   *     type annotation(s) was found
   * @throws JsonMappingException if invalid annotation is found
   */
  private JavaType modifyTypeByAnnotation(DeserializationContext ctxt, Annotated a, JavaType type)
      throws JsonMappingException {
    // first: let's check class for the instance itself:
    AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
    Class<?> subclass = intr.findDeserializationType(a, type);
    if (subclass != null) {
      try {
        type = type.narrowBy(subclass);
      } catch (IllegalArgumentException iae) {
        throw new JsonMappingException(
            "Failed to narrow type "
                + type
                + " with concrete-type annotation (value "
                + subclass.getName()
                + "), method '"
                + a.getName()
                + "': "
                + iae.getMessage(),
            null,
            iae);
      }
    }

    // then key class
    if (type.isContainerType()) {
      Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType());
      if (keyClass != null) {
        // illegal to use on non-Maps
        if (!(type instanceof MapLikeType)) {
          throw new JsonMappingException(
              "Illegal key-type annotation: type " + type + " is not a Map(-like) type");
        }
        try {
          type = ((MapLikeType) type).narrowKey(keyClass);
        } catch (IllegalArgumentException iae) {
          throw new JsonMappingException(
              "Failed to narrow key type "
                  + type
                  + " with key-type annotation ("
                  + keyClass.getName()
                  + "): "
                  + iae.getMessage(),
              null,
              iae);
        }
      }
      JavaType keyType = type.getKeyType();
      /* 21-Mar-2011, tatu: ... and associated deserializer too (unless already assigned)
       *   (not 100% why or how, but this does seem to get called more than once, which
       *   is not good: for now, let's just avoid errors)
       */
      if (keyType != null && keyType.getValueHandler() == null) {
        Object kdDef = intr.findKeyDeserializer(a);
        if (kdDef != null) {
          KeyDeserializer kd = ctxt.keyDeserializerInstance(a, kdDef);
          if (kd != null) {
            type = ((MapLikeType) type).withKeyValueHandler(kd);
            keyType = type.getKeyType(); // just in case it's used below
          }
        }
      }

      // and finally content class; only applicable to structured types
      Class<?> cc = intr.findDeserializationContentType(a, type.getContentType());
      if (cc != null) {
        try {
          type = type.narrowContentsBy(cc);
        } catch (IllegalArgumentException iae) {
          throw new JsonMappingException(
              "Failed to narrow content type "
                  + type
                  + " with content-type annotation ("
                  + cc.getName()
                  + "): "
                  + iae.getMessage(),
              null,
              iae);
        }
      }
      // ... as well as deserializer for contents:
      JavaType contentType = type.getContentType();
      if (contentType.getValueHandler()
          == null) { // as with above, avoid resetting (which would trigger exception)
        Object cdDef = intr.findContentDeserializer(a);
        if (cdDef != null) {
          JsonDeserializer<?> cd = null;
          if (cdDef instanceof JsonDeserializer<?>) {
            cdDef = (JsonDeserializer<?>) cdDef;
          } else {
            Class<?> cdClass =
                _verifyAsClass(cdDef, "findContentDeserializer", JsonDeserializer.None.class);
            if (cdClass != null) {
              cd = ctxt.deserializerInstance(a, cdClass);
            }
          }
          if (cd != null) {
            type = type.withContentValueHandler(cd);
          }
        }
      }
    }
    return type;
  }