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; }
@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; }