pax_global_header00006660000000000000000000000064121505665730014524gustar00rootroot0000000000000052 comment=b8d01a7df1c1f3c682200fdefe99f5a7291f729d jackson-databind-jackson-databind-2.2.2/000077500000000000000000000000001215056657300201155ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/.gitignore000066400000000000000000000002351215056657300221050ustar00rootroot00000000000000# use glob syntax. syntax: glob *.class *~ *.bak *.off *.old .DS_Store # building target # Eclipse .classpath .project .settings # IDEA *.iml *.ipr *.iws jackson-databind-jackson-databind-2.2.2/README.md000066400000000000000000000356221215056657300214040ustar00rootroot00000000000000# Overview This project contains the general-purpose data-binding functionality and tree-model for [Jackson Data Processor](http://wiki.fasterxml.com/JacksonHome) It builds on [core streaming parser/generator](https://github.com/FasterXML/jackson-core) package, and uses [Jackson Annotations](https://github.com/FasterXML//jackson-annotations) for configuration. While the original use case for Jackson was JSON data-binding, it can now be used for other data formats as well, as long as parser and generator implementations exist. Naming of classes uses word 'JSON' in many places even though there is no actual hard dependency to JSON format. [![Build Status](https://fasterxml.ci.cloudbees.com/job/jackson-databind-master/badge/icon)](https://fasterxml.ci.cloudbees.com/job/jackson-databind-master/) ### Differences from Jackson 1.x Project contains versions 2.0 and above: source code for earlier (1.x) versions is available from [Codehaus](http://jackson.codehaus.org) SVN repository Main differences compared to 1.0 "mapper" jar are: * Maven build instead of Ant * Java package is now `com.fasterxml.jackson.databind` (instead of `org.codehaus.jackson.map`) ----- # Get it! ## Maven Functionality of this package is contained in Java package `com.fasterxml.jackson.databind`, and can be used using following Maven dependency: ```xml com.fasterxml.jackson.core jackson-databind 2.2.0 ``` Since package also depends on '''jackson-core''' and '''jackson-databind''' packages, you will need to download these if not using Maven; and you may also want to add them as Maven dependency to ensure that compatible versions are used. If so, also add: ```xml com.fasterxml.jackson.core jackson-annotations 2.2.0 com.fasterxml.jackson.core jackson-core 2.2.0 ``` but note that this is optional, and only necessary if there are conflicts between jackson core dependencies through transitive dependencies. ## Non-Maven For non-Maven use cases, you download jars from [Central Maven repository](http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/) or [Download page](https://github.com/FasterXML/jackson-databind/wiki/JacksonDownload). Databind jar is also a functional OSGi bundle, with proper import/export declarations, so it can be use on OSGi container as is. ----- # Use It! While wiki contains more documentation, here are brief introductionary tutorials, in recommended order of reading. ## 1 minute tutorial: POJOs to JSON and back The most common usage is to take piece of JSON, and construct a Plain Old Java Object ("POJO") out of it. So let's start there. All data binding starts with a `com.fasterxml.jackson.databind.ObjectMapper` instance, so let's construct one: ```java ObjectMapper mapper = new ObjectMapper(); // create once, reuse ``` The default instance is fine for our use -- we will learn later on how to configure mapper instance if necessary. Usage is simple: ```java MyValue value = mapper.readValue(new File("data.json"), MyValue.class); // or: value = mapper.readValue(new URL("http://some.com/api/entry.json"), MyValue.class); // or: value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class); ``` And if we want to write JSON, we do the reverse: ```java mapper.writeValue(new File("result.json"), myResultObject); // or: byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject); // or: String jsonString = mapper.writeValueAsString(myResultObject); ``` So far so good? ## 3 minute tutorial: Generic collections, Tree Model Beyond dealing with simple Bean-style POJOs, you can also handle JDK `List`s, `Map`s: ```java Map scoreByName = mapper.readValue(jsonSource, Map.class); List names = mapper.readValue(jsonSource, List.class); // and can obviously write out as well mapper.writeValue(new File("names.json"), names); ``` as long as JSON structure matches, and types are simple. If you have POJO values, you need to indicate actual type (note: this is NOT needed for POJO properties with `List` etc types): ```java Map results = mapper.readValue(jsonSource, new TypeReference() { } ); // why extra work? Java Type Erasure will prevent type detection otherwise ``` (note: no extra effort needed for serialization, regardless of generic types) But wait! There is more! While dealing with `Map`s, `List`s and other "simple" Object types (Strings, Numbers, Booleans) can be simple, Object traversal can be cumbersome. This is where Jackson's [Tree model](https://github.com/FasterXML/jackson-databind/wiki/JacksonTreeModel) can come in handy: ```java // can be read as generic JsonNode, if it can be Object or Array; or, // if known to be Object, as ObjectNode, if array, ArrayNode etc: ObjectNode root = mapper.readTree("stuff.json"); String name = root.get("name").asText(); int age = root.get("age").asInt(); // can modify as well: this adds child Object as property 'other', set property 'type' root.with("other").put("type", "student"); String json = mapper.writeValueAsString(root); // with above, we end up with something like as 'json' String: // { // "name" : "Bob", "age" : 13, // "other" : { // "type" : "student" // { // } ``` Tree Model can be more convenient than data-binding, especially in cases where structure is highly dynamic, or does not map nicely to Java classes. ## 5 minute tutorial: Streaming parser, generator As convenient as data-binding (to/from POJOs) can be; and as flexible as Tree model can be, there is one more canonical processing model available: incremental (aka "streaming") model. It is the underlying processing model that data-binding and Tree Model both build upon, but it is also exposed to users who want ultimate performance and/or control over parsing or generation details. For in-depth explanation, look at [Jackson Core component](https://github.com/FasterXML/jackson-core). But let's look at a simple teaser to whet your appetite: (TO BE COMPLETED) ## 10 minute tutorial: configuration There are two entry-level configuration mechanisms you are likely to use: [Features](https://github.com/FasterXML/jackson-databind/wiki/JacksonFeatures) and [Annotations](https://github.com/FasterXML/jackson-annotations). ### Commonly used Features Here are examples of configuration features that you are most likely to need to know about. Let's start with higher-level data-binding configuration. ```java // SerializationFeature for changing how JSON is written // to enable standard indentation ("pretty-printing"): mapper.enable(SerializationFeature.INDENT_OUTPUT); // to allow serialization of "empty" POJOs (no properties to serialize) // (without this setting, an exception is thrown in those cases) mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); // to write java.util.Date, Calendar as number (timestamp): mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // DeserializationFeature for changing how JSON is read as POJOs: // to prevent exception when encountering unknown property: mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // to allow coercion of JSON empty String ("") to null Object value: mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); ``` In addition, you may need to change some of low-level JSON parsing, generation details: ```java // JsonParser.Feature for configuring parsing settings: // to allow C/C++ style comments in JSON (non-standard, disabled by default) mapper.enable(JsonParser.Feature.ALLOW_COMMENTS); // to allow (non-standard) unquoted field names in JSON: mapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES); // to allow use of apostrophes (single quotes), non standard mapper.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES); // JsonGenerator.Feature for configuring low-level JSON generation: // to force escaping of non-ASCII characters: mapper.enable(JsonGenerator.Feature.ESCAPE_NON_ASCII); ``` Full set of features are explained on [Jackson Features](https://github.com/FasterXML/jackson-databind/wiki/JacksonFeatures) page. ### Annotations: changing property names The simplest annotation-based approach is to use `@JsonProperty` annotation like so: ```java public class MyBean { private String _name; // without annotation, we'd get "theName", but we want "name": @JsonProperty("name") public String getTheName() { return _name; } // note: it is enough to add annotation on just getter OR setter; // so we can omit it here public void setTheName(String n) { _name = n; } } ``` There are other mechanisms to use for systematic naming changes: see [Custom Naming Convention](https://github.com/FasterXML/jackson-databind/wiki/JacksonCustomNamingConvention) for details. Note, too, that you can use [Mix-in Annotations](https://github.com/FasterXML/jackson-databind/wiki/JacksonMixinAnnotations) to associate all annotations. ### Annotations: Ignoring properties There are two main annotations that can be used to to ignore properties: `@JsonIgnore` for individual properties; and `@JsonIgnoreProperties` for per-class definition ```java // means that if we see "foo" or "bar" in JSON, they will be quietly skipped // regardless of whether POJO has such properties @JsonIgnoreProperties({ "foo", "bar" }) public class MyBean { // will not be written as JSON; nor assigned from JSON: @JsonIgnore public String internal; // no annotation, public field is read/written normally public String external; @JsonIgnore public void setCode(int c) { _code = c; } // note: will also be ignored because setter has annotation! public int getCode() { return _code; } } ``` As with renaming, note that annotations are "shared" between matching fields, getters and setters: if only one has `@JsonIgnore`, it affects others. But it is also possible to use "split" annotations, to for example: ```java public class ReadButDontWriteProps { private String _name; @JsonProperty public void setName(String n) { _name = n; } @JsonIgnore public String getName() { return _name; } } ``` in this case, no "name" property would be written out (since 'getter' is ignored); but if "name" property was found from JSON, it would be assigned to POJO property! For a more complete explanation of all possible ways of ignoring properties when writing out JSON, check ["Filtering properties"](http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html) article. ### Annotations: using custom constructor Unlike many other data-binding packages, Jackson does not require you to define "default constructor" (constructor that does not take arguments). While it will use one if nothing else is available, you can easily define that an argument-taking constructor is used: ```java public class CtorBean { public final String name; public final int age; @JsonCreator // constructor can be public, private, whatever private CtorBean(@JsonProperty("name") String name, @JsonProperty("age") int age) { this.name = name; this.age = age; } } ``` Constructors are especially useful in supporting use of [Immutable objects](http://www.cowtowncoder.com/blog/archives/2010/08/entry_409.html). Alternatively, you can also define "factory methods": ```java public class FactoryBean { // fields etc omitted for brewity @JsonCreator public static FactoryBean create(@JsonProperty("name") String name) { // construct and return an instance } } ``` Note that use of a "creator method" does not preclude use of setters: you can mix and match properties from constructor/factory method with ones that are set via setters or directly using fields. ## Tutorial: fancier stuff, conversions One useful (but not very widely known) feature of Jackson is its ability to do arbitrary POJO-to-POJO conversions. Conceptually you can think of conversions as sequence of 2 steps: first, writing a POJO as JSON, and second, binding that JSON into another kind of POJO. Implementation just skips actual generation of JSON, and uses more efficient intermediate representation. Conversations work between any compatible types, and invocation is as simple as: ```java ResultType result = mapper.convertValue(sourceObject, ResultType.class); ``` and as long as source and result types are compatible -- that is, if to-JSON, from-JSON sequence would succeed -- things will "just work". But here are couple of potentially useful use cases: ```java // Convert from int[] to List List sourceList = ...; int[] ints = mapper.convertValue(sourceList, int[].class); // Convert a POJO into Map! Map propertyMap = mapper.convertValue(pojoValue, Map.class); // ... and back PojoType pojo = mapper.convertValue(propertyMap, PojoType.class); // decode Base64! (default byte[] representation is base64-encoded String) String base64 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"; byte[] binary = mapper.convertValue(base64, byte[].class); ``` Basically, Jackson can work as a replacement for many Apache Commons components, for tasks like base64 encoding/decoding, and handling of "dyna beans" (Maps to/from POJOs). # Contribute! We would love to get your contribution, whether it's in form of bug reports, Requests for Enhancement (RFE), documentation, or code patches. The primary mechanism for all of above is [GitHub Issues system](https://github.com/FasterXML/jackson-databind/issues). ## Basic rules for Code Contributions There is really just one main rule, which is that to accept any code contribution, we need to get a filled Contributor License Agreement (CLA) from the author. One CLA is enough for any number of contributions, but we need one. Or, rather, companies that use our code want it. It keeps their lawyers less unhappy about Open Source usage. ## Limitation on Dependencies by Core Components One additional limitation exists for so-called core components (streaming api, jackson-annotations and jackson-databind): no additional dependendies are allowed beyond: * Core components may rely on any methods included in the supported JDK: currently core components are limited to JDK 1.5 * Jackson-databind (this package) depends on the other two (annotations, streaming). This means that anything that has to rely on additional APIs or libraries needs to be built as an extension, usually a Jackson module. ----- # Further reading * [Documentation](https://github.com/FasterXML/jackson-databind/wiki/Documentation) Related: * [Core annotations](https://github.com/FasterXML/jackson-annotations) package defines annotations commonly used for configuring databinding details * [Core parser/generator](https://github.com/FasterXML/jackson-core) package defines low-level incremental/streaming parsers, generators * [Jackson Project Home](http://wiki.fasterxml.com/JacksonHome) has additional documentation (although much of it for Jackson 1.x) jackson-databind-jackson-databind-2.2.2/backup/000077500000000000000000000000001215056657300213625ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/backup/TypeSerializerWrapper.java000066400000000000000000000111071215056657300265410ustar00rootroot00000000000000package com.fasterxml.jackson.databind.jsontype; import java.io.IOException; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.BeanProperty; /** * Helper class used in cases where we caller has to override source * for type identifier, for example when serializing a value using * a delegate or surrogate value, in which case type id is to be based * on the original value, but serialization done using surrogate. * * @since 2.2 */ public class TypeSerializerWrapper extends TypeSerializer { /** * Actual TypeSerializer to use */ protected final TypeSerializer _delegate; protected final Object _value; public TypeSerializerWrapper(TypeSerializer delegate, Object value) { _delegate = delegate; _value = value; } /* /********************************************************** /* TypeSerializer implementation, metadata /********************************************************** */ @Override public TypeSerializer forProperty(BeanProperty prop) { TypeSerializer d2 = _delegate.forProperty(prop); if (d2 == _delegate) { return this; } return new TypeSerializerWrapper(d2, _value); } @Override public As getTypeInclusion() { return _delegate.getTypeInclusion(); } @Override public String getPropertyName() { return _delegate.getPropertyName(); } @Override public TypeIdResolver getTypeIdResolver() { return _delegate.getTypeIdResolver(); } /* /********************************************************** /* TypeSerializer implementation, actual write methods /********************************************************** */ @Override public void writeTypePrefixForScalar(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { _delegate.writeTypePrefixForScalar(_value, jgen); } @Override public void writeTypePrefixForObject(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { _delegate.writeTypePrefixForObject(_value, jgen); } @Override public void writeTypePrefixForArray(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { _delegate.writeTypePrefixForArray(_value, jgen); } @Override public void writeTypeSuffixForScalar(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { _delegate.writeTypeSuffixForScalar(_value, jgen); } @Override public void writeTypeSuffixForObject(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { _delegate.writeTypeSuffixForObject(_value, jgen); } @Override public void writeTypeSuffixForArray(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { _delegate.writeTypeSuffixForArray(_value, jgen); } @Override public void writeCustomTypePrefixForScalar(Object value, JsonGenerator jgen, String typeId) throws IOException, JsonProcessingException { _delegate.writeCustomTypePrefixForScalar(_value, jgen, typeId); } @Override public void writeCustomTypePrefixForObject(Object value, JsonGenerator jgen, String typeId) throws IOException, JsonProcessingException { _delegate.writeCustomTypePrefixForObject(_value, jgen, typeId); } @Override public void writeCustomTypePrefixForArray(Object value, JsonGenerator jgen, String typeId) throws IOException, JsonProcessingException { _delegate.writeCustomTypePrefixForArray(_value, jgen, typeId); } @Override public void writeCustomTypeSuffixForScalar(Object value, JsonGenerator jgen, String typeId) throws IOException, JsonProcessingException { _delegate.writeCustomTypeSuffixForScalar(_value, jgen, typeId); } @Override public void writeCustomTypeSuffixForObject(Object value, JsonGenerator jgen, String typeId) throws IOException, JsonProcessingException { _delegate.writeCustomTypeSuffixForObject(_value, jgen, typeId); } @Override public void writeCustomTypeSuffixForArray(Object value, JsonGenerator jgen, String typeId) throws IOException, JsonProcessingException { _delegate.writeCustomTypeSuffixForArray(_value, jgen, typeId); } } jackson-databind-jackson-databind-2.2.2/create-test-report.sh000077500000000000000000000000501215056657300242000ustar00rootroot00000000000000#!/bin/sh mvn surefire-report:report jackson-databind-jackson-databind-2.2.2/pom.xml000066400000000000000000000124041215056657300214330ustar00rootroot00000000000000 4.0.0 com.fasterxml oss-parent 10 com.fasterxml.jackson.core jackson-databind 2.2.2 jackson-databind General data-binding functionality for Jackson: works on core streaming API http://wiki.fasterxml.com/JacksonHome scm:git:git@github.com:FasterXML/jackson-databind.git scm:git:git@github.com:FasterXML/jackson-databind.git http://github.com/FasterXML/jackson-databind jackson-databind-2.2.2 com.fasterxml.jackson.databind, com.fasterxml.jackson.databind.annotation, com.fasterxml.jackson.databind.cfg, com.fasterxml.jackson.databind.deser, com.fasterxml.jackson.databind.deser.impl, com.fasterxml.jackson.databind.deser.std, com.fasterxml.jackson.databind.exc, com.fasterxml.jackson.databind.ext, com.fasterxml.jackson.databind.introspect, com.fasterxml.jackson.databind.jsonschema, com.fasterxml.jackson.databind.jsonFormatVisitors, com.fasterxml.jackson.databind.jsontype, com.fasterxml.jackson.databind.jsontype.impl, com.fasterxml.jackson.databind.module, com.fasterxml.jackson.databind.node, com.fasterxml.jackson.databind.ser, com.fasterxml.jackson.databind.ser.impl, com.fasterxml.jackson.databind.ser.std, com.fasterxml.jackson.databind.type, com.fasterxml.jackson.databind.util com.fasterxml.jackson.annotation, com.fasterxml.jackson.core, com.fasterxml.jackson.core.base, com.fasterxml.jackson.core.format, com.fasterxml.jackson.core.json, com.fasterxml.jackson.core.io, com.fasterxml.jackson.core.util, com.fasterxml.jackson.core.type, org.xml.sax,org.w3c.dom, org.w3c.dom.bootstrap, org.w3c.dom.ls, javax.xml.datatype, javax.xml.namespace, javax.xml.parsers com/fasterxml/jackson/databind/cfg com.fasterxml.jackson.databind.cfg com.fasterxml.jackson.core jackson-annotations 2.2.2 com.fasterxml.jackson.core jackson-core 2.2.2 junit junit 4.10 test cglib cglib 2.2.2 test org.codehaus.groovy groovy 1.7.9 test org.hibernate hibernate-cglib-repack 2.1_3 test org.apache.maven.plugins maven-surefire-plugin ${surefire.version} com/fasterxml/jackson/failing/*.java org.apache.maven.plugins maven-javadoc-plugin ${javadoc.version} http://docs.oracle.com/javase/6/docs/api/ http://fasterxml.github.com/jackson-annotations/javadoc/2.1.1/ http://fasterxml.github.com/jackson-core/javadoc/2.1.1/ com.google.code.maven-replacer-plugin replacer process-packageVersion process-sources release true true jackson-databind-jackson-databind-2.2.2/release-notes/000077500000000000000000000000001215056657300226635ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/release-notes/CREDITS000066400000000000000000000052261215056657300237100ustar00rootroot00000000000000Here are people who have contributed to development Jackson JSON processor databind core component, version 2.x (version numbers in brackets indicate release in which the problem was fixed) (note: for older credits, check out release notes for 1.x versions) Tatu Saloranta, tatu.saloranta@iki.fi: author Pascal GŽlinas: * Contributed fixes to 'MappingIterator' handling (Pull#58 and Pull#59) (2.1.0) * Reported #220: ContainerNode missing 'createNumber(BigInteger)' (2.2.2) Joern Huxhorn: * Suggested [JACKSON-636]: Add 'SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS' to allow forced sorting of Maps during serialization (2.0.0) James Roper: * Requested [JACKSON-732]: Allow 'AnnotationIntrospector.findContentDeserializer()' (and similar) to return instance, not just Class for instance (2.0.0) * Suggested [JACKSON-800]: Adding a method for letting modules register DeserializationProblemHandlers (2.0.0) Casey Lucas: * Reported [JACKSON-798]: Problem with external type id, creators (2.0.0) Tammo van Lessen: * Reported [JACKSON-811]: Problems with @JsonIdentityInfo, abstract types (2.0.0) * Reported [JACKSON-814]: Parsing RFC822/RFC1123 dates failes on non-US locales (2.0.0) Raymond Myers: * Suggested [JACKSON-810]: Deserialization Feature: Allow unknown Enum values via 'DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL' (2.0.0) Ryan Gardner: * Contributed [pull-5] -- Add support for maps with java.util.Locale keys to the set of StdKeyDeserializers (2.0.1) Razvan Dragut: * Suggested [JACKSON-850]: Allow use of zero-arg factory methods as "default creator" (2.1.0) Duncan Atkinson: * Reported [JACKSON-851]: State corruption with ObjectWriter, DefaultPrettyPrinter (2.1.0) Mark Wolfe: * Suggested [Issue#45]: Add `@JsonNaming()` for per-class naming strategy overrides (2.1.0) Dmitry Katsubo: * Contributed patch for [Issue#65]: Add getters to `ObjectMapper`, DeserializationContext, DeserializationFactory. (2.1.0) Francis Galiegue: * Reported [Issue#93] (and suggested fix): bug in `ObjectMapper.setAll(...)' implementation (2.1.1) kelaneren@github: * Reported [Issue#157], contributed unit test: NPE when registering same module twice. (2.1.4) Eric Tschetter (cheddar@github): * Reported issues #166, #167, #170 (regressions from 1.9.x to 2.x) (2.1.4) Thierry D (thierryd@github) * Reported #214: Problem with LICENSE, NOTICE, Android packaging (2.2.2) Luke G-H (lukegh@github) * Reported #223: Duplicated nulls with @JsonFormat(shape=Shape.ARRAY) (2.2.2) Karl Moore (karldmoore@github) * Reported #217: JsonProcessingExceptions not all wrapped as expected (2.2.2) jackson-databind-jackson-databind-2.2.2/release-notes/VERSION000066400000000000000000000411431215056657300237360ustar00rootroot00000000000000Project: jackson-databind Version: 2.2.2 (26-May-2013) Changes: #216: Problems with Android, 1.6-only types #217: JsonProcessingExceptions not all wrapped as expected (reported by karldmoore@github) #220: ContainerNode missing 'createNumber(BigInteger)' (reported by Pascal G) #223: Duplicated nulls with @JsonFormat(shape=Shape.ARRAY) (reported by lukegh@github) #226: Field mapping fail on deserialization to common referenced object when @JsonUnwrapped is used (reported by ikvia@github) #232: Converting bound BigDecimal value to tree fails with WRITE_BIGDECIMAL_AS_PLAIN (reported by celkings@github) - Minor fix to handle primitive types for key deserializer lookups - Add convenience method `MappingIterator.getCurrentLocation()` (suggested by Tomdz@github) ------------------------------------------------------------------------ === History: === ------------------------------------------------------------------------ 2.2.1 (03-May-2013) #214: Problem with LICENSE, NOTICE, Android packaging (reported by thierryd@github) 2.2.0 (22-Apr-2013) Fixes: #23: Fixing typing of root-level collections #118: JsonTypeInfo.as.EXTERNAL_PROPERTY not working correctly with missing type id, scalar types #130: TimeZone not set for GregorianCalendar, even if configured #144: MissingNode.isValueNode() should return 'false' (reported by 'fge@github') #146: Creator properties were not being renamed as expected (contributed by Christoper C) #188: Problem with ObjectId serialization, 'alwaysAsId' references Improvements: #116: JavaType implements `java.lang.reflect.Type` (as does `TypeReference`) #147: Defer reporting of problems with missing creator parameters (contributed by Christoper C) #155: Make `ObjectNode` and `ArrayNode` final (other node types already were) (requested by fge@github) #161: Add deserializer for java.util.concurrent.ArrayBlockingQueue #173: Add 'JsonNode.traverse(ObjectCodec)' for convenience #181: Improve error reporting for missing '_valueDeserializer' #194: Add `FloatNode` type in tree model (JsonNode) (requested by msteiger@github) #199: Allow deserializing `Iterable` instances (as basic `Collection`s) (requested by electrum@github) #206: Make 'ObjectMapper.createDeserializationContext()' overridable (requested by noter@github) #207: Add explicit support for `short` datatypes, for tree model (contributed by msteiger@github) New features: #120: Extend BeanDeserializerModifier to work with non-POJO deserializers #121: Extend BeanSerializerModifier to work with non-POJO serializers #124: Add support for serialization converters (@JsonSerializer(converter=...)) #124: Add support for deserialization converters (@JsonDeserializer(converter=...)) #140: Add 'SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN' to allow forcing of non-scientific notation when serializing BigDecimals. (suggested by phedny@github) #148: Add 'DeserializationFeature.FAIL_ON_INVALID_SUBTYPE`, which allows mapping entries with missing or invalid type id into null references (instead of failing). Also allows use of '@JsonTypeInfo.defaultImpl = NoClass.class' as alternative. #159: Add more accessors in 'MappingIterator': getParser(), getParserSchema(), readAll() (suggested by Tom D) #190: Add 'MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS' (default: true) for pruning out final fields (to avoid using as mutators) (requested by Eric T) #195: Add 'MapperFeature.INFER_PROPERTY_MUTATORS' (default: enabled) for finer control of what mutators are auto-detected. (requested by Dain S) #198: Add SPI metadata, handling in ObjectMapper (findModules()), for automatic registration of auto-detected extension modules (suggested by 'beamerblvd@github') #203: Added new features to support advanced date/time handling: - SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS - DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS - DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE Other: #126: Update JDK baseline to 1.6 * API under 'com.fasterxml.jackson.databind.jsonFormatVisitors' changed significantly based on experiences with external JSON Schema generator. * Version information accessed via code-generated access class, instead of reading VERSION.txt * Added 2 methods in Converter interface: getInputType(), getOutputType(), to allow programmatic overrides (needed by JAXB annotation module) 2.1.4 (26-Feb-2013) * [JACKSON-887]: StackOverflow with parameterized sub-class field (reported by Alexander M) * [#130]: TimeZone not set for GregorianCalendar, when deserializing * [#157]: NPE when registering module twice * [#162]: JsonNodeFactory: work around an old bug with BigDecimal and zero (submitted by fge@github) * [#166]: Incorrect optimization for `ObjectMapper.convertValue(Class)` (reported by Eric T) * [#167]: Problems with @JsonValue, polymorphic types (regression from 1.x) (reported by Eric T) * [#170]: Problems deserializing `java.io.File` if creator auto-discovery disabled (reported by Eric T) * [#175]: NPE for JsonMappingException, if no path is specified (reported by bramp@github) 2.1.3 (19-Jan-2013) * [Issue#141]: ACCEPT_EMPTY_STRING_AS_NULL_OBJECT not working for enums * [Issue#142]: Serialization of class containing EnumMap with polymorphic enum fails to generate class type data (reported by kidavis4@github) 2.1.2 (04-Dec-2012) * [Issue#106]: NPE in ObjectArraySerializer.createContextual(...) * [Issue#117]: HandlerInstantiator defaulting not working (reported by Alexander B) * [Issue#118]: Problems with JsonTypeInfo.As.EXTERNAL_PROPERTY, scalar values (reported by Adva11@github) * [Issue#119]: Problems with @JsonValue, JsonTypeInfo.As.EXTERNAL_PROPERTY (reported by Adva11@github) * [Issue#122]: ObjectMapper.copy() was not copying underlying mix-in map (reported by rzlo@github) 2.1.1 (11-Nov-2012) Fixes: * [JACKSON-875]: Enum values not found if Feature.USE_ANNOTATIONS disabled (reported by Laurent P) * [Issue#93]: ObjectNode.setAll() broken; would not add anything for empty ObjectNodes. (reported by Francis G) * Making things implement java.io.Serializable: - Issues: #94, #99, #100, #102 (reported by Sean B) * [Issue#96]: Problem with JsonTypeInfo.As.EXTERNAL_PROPERTY, defaultImpl (reported by Adva11@github) 2.1.0 (08-Oct-2012) New minor version for 2.x series. Major improvements in multiple areas, including: - Dataformat auto-detection - More `@JsonFormat.shape` variant to serialize Collections as JSON Objects, POJOs as JSON Arrays (csv-like). - Much more configuration accessible via ObjectReader, ObjectWriter - New mechanism for JSON Schema generation, other uses (in future) Fixes: * [JACKSON-830]/[Issue#19]: Change OSGi bundle name to be fully-qualified * ]JACKSON-847]: Make @JsonIdentityInfo work with property-based creator * [JACKSON-851]: State corruption with ObjectWriter, DefaultPrettyPrinter (reported by Duncan A) * [Issue#75]: Too aggressive KeySerializer caching * Minor fix wrt [Issue#11], coercion needed extra checks Improvements: * [JACKSON-758]: Remove 'IOException' from throws clauses of "writeValueAsString" and "writeValueAsBytes" of ObjectMapper/ObjectWriter (suggested by G-T Chen) * [JACKSON-839]: Allow "upgrade" of integer number types for UntypedObjectDeserializer, even with default typing enabled. * [JACKSON-850]: Allow use of zero-arg factory methods as "default creator" (suggested by Razvan D) * [Issue#9]: Implement 'required' JSON Schema attribute for bean properties * [Issue#20]: Add new exception type, InvalidFormatException (sub-type of JsonMappingException) to indicate data format problems (suggested by HolySamosa@github) * [Issue#30]: ObjectReader and ObjectWriter now try to pre-fetch root (de)serializer if possible; minor performance improvement (2% for small POJOs). * [Issue#33]: Simplified/clarified definition of 'ObjectReader.readValues()'; minor change in behavior for JSON Array "wrapped" sequences * [Issue#60]: Add 'JsonNode.hasNonNull(...)' method(s) (suggested by Jeff S on mailing list) * [Issue#64]: Add new "standard" PropertyNamingStrategy, PascalCaseStrategy (PropertyNamingStrategy.PASCAL_CASE_TO_CAMEL_CASE) (contributed by Sean B) * [Issue#65]: Add getters to `ObjectMapper`, DeserializationContext/-Factory. (contributed by Dmitry K) * [Issue#69]: Add `PropertyName` abstraction, new methods in AnnotationIntrospector * [Issue#80]: Make `DecimalNode` normalize input, to make "1.0" and "1.00"equal (reported by fge@github) New features: * [Issue#15]: Support data format auto-detection via ObjectReader (added 'withFormatDetection(...)' fluent factories) * [Issue#21]: Add 'ObjectNode.set(...)' method (and related) to improve chaining, semantic consistency of Tree Model API (suggested by fge@Github) * [Issue#22]: Add 'ObjectMapper.setAnnotationIntrospectors()' which allows defining different introspectors for serialization, deserialization * [Issue#24]: Allow serialization of Enums as JSON Objects (suggested by rveloso@github) * [Issue#28]: Add 'ObjectMapper.copy()', to create non-linked copy of mapper, with same configuration settings * [Issue#29]: Allow serializing, deserializing POJOs as JSON Arrays by using `@JsonFormat(shape=Shape.ARRAY)` * [Issue#40]: Allow serialization of Collections as JSON Objects (and deserialization from) (suggested by 'rveloso@github') * [Issue#42]: Allow specifying Base64 variant to use for Base64-encoded data using ObjectReader.with(Base64Variant), ObjectWriter.with(Base64Variant). (suggested by 'mpfau@github') * [Issue#45]: Add '@JsonNaming' annotation to define per-class PropertyNamingStrategy (suggested by Mark W) * [Pull#58]: Make 'MappingIterator' implement 'Closable' (contributed by Pascal G) * [Issue#72]: Add 'MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME' to use wrapper name annotations for renaming properties * [Issue#87]: Add 'StdDelegatingSerializer', 'StdDelegatingDeserializer' to simplify writing of two-step handlers * (issue #4 of jackson-annotations): Add `@JsonIdentityReference(alwaysAsId=true)` to force ALL references to an object written as Object Id, even the first one. * Added 'ObjectReader#withHandler' to allow for reconfiguring deserialization problem handler (suggested by 'electricmonk') Other changes: * New variant of AnnotationIntrospector.getFormat(), to support class annotations * It is now possible to serialize instances of plain old Object, iff 'FAIL_ON_EMPTY_BEANS' is disabled. * Trying to remove reference to "JSON" in datatype conversion errors (since databinding is format-agnostic) INCOMPATIBILITIES: (rats!) * Note that [Issue#33] (see above) is, technically speaking, backwards imcompatible change. It is estimated that it should NOT affect most users, as changes are to edge cases (and undocumented ones at that). However, it can potentially cause problems with upgrade. * Implementation of `JsonFormatVisitable` resulting in 2 new methods being added in `BeanPropertyFilter` interface -- this is unfortunate, but was required to support full traversability. 2.0.4 (26-Jun-2012) * [Issue#6]: element count for PrettyPrinter, endObject wrong (reported by "thebluemountain") * [JACKSON-838]: Utf8StreamParser._reportInvalidToken() skips letters from reported token name (reported by Lóránt Pintér) * [JACKSON-841] Data is doubled in SegmentedStringWriter output (reported by Scott S) * [JACKSON-842] ArrayIndexOutOfBoundsException when skipping C-style comments (reported by Sebastien R) 2.0.3: no version 2.0.3 released -- only used for extension modules 2.0.2 [14-May-2012] Fixes: * [Issue#14]: Annotations were not included from parent classes of mix-in classes (reported by @guillaup) * [JACKSON-824]: Combination of JSON Views, ObjectMapper.readerForUpdating() was not working (reported by Nir S) (and all fixes from 1.9.7) Improvements: * [Issue#11]: Improve ObjectMapper.convertValue()/.treeToValue() to use cast if possible 2.0.1 [23-Apr-2012] Fixes: * [JACKSON-827] Ensure core packages work on JDK 1.5 (reported by Pascal g) * [JACKSON-829] Custom serializers not working for List properties, @JsonSerialize(contentUsing) (reported by James R) Improvements: * [Issue#5]: Add support for maps with java.util.Locale keys to the set of StdKeyDeserializers (contributed by Ryan G) 2.0.0 [25-Mar-2012] Fixes: * [JACKSON-368]: Problems with managed references, abstract types * [JACKSON-711]: Delegating @JsonCreator did not work with Injectable values * [JACKSON-798]: Problem with external type id, creators (reported by Casey L) (and all fixes up until and including 1.9.6) Improvements: * [JACKSON-546]: Indicate end-of-input with JsonMappingException instead of EOFException, when there is no parsing exception * [JACKSON-664]: Reduce overhead of type resolution by adding caching in TypeFactory * [JACKSON-690]: Pass DeserializationContext through ValueInstantiator * [JACKSON-695]: Add 'isEmpty(value)' in JsonSerializer to allow customizing handling of serialization of empty values * [JACKSON-710]: 'ObjectMapper.convertValue()' should ignore root value wrapping/unwrapping settings * [JACKSON-730] Split various features (JsonParser, JsonGenerator, SerializationConfig, DeserializationConfig) into per-factory features (MapperFeature, JsonFactory.Feature) an per instance features (existing ones) * [JACKSON-732]: Allow 'AnnotationIntrospector.findContentDeserializer()' (and similar) to return instance, not just Class for instance (requested by James R) * [JACKSON-736]: Add (more) access to array, container and map serializers * [JACKSON-737]: Allow accessing of "creator properties" for BeanDeserializer * [JACKSON-748]: Add 'registerSubtypes' to 'Module.setupContext' (and SimpleModule) * [JACKSON-749]: Make @JsonValue work for Enum deserialization * [JACKSON-769]: ObjectNode/ArrayNode: change 'put', 'insert', 'add' to return 'this node' (unless already returning something) * [JACKSON-770]: Simplify method naming for JsonNode, drop unnecessary 'get' prefix from methods like 'getTextValue()' (becomes 'textValue()') * [JACKSON-777]: Rename 'SerializationConfig.Feature' as 'SerializationFeature', 'DeserializationConfig.Feature' as 'DeserializationFeature' * [JACKSON-780]: MissingNode, NullNode should return 'defaultValue' from 'asXxx' methods, (not 0 for numbers), as they are not numeric types * [JACKSON-787]: Allow use of @JsonIgnoreProperties for properties (fields, getters, setters) * [JACKSON-795]: @JsonValue was not working for Maps, Collections * [JACKSON-800]: Add 'Module.SetupContext#addDeserializationProblemHandler' (suggested by James R) New features: * [JACKSON-107]: Add support for Object Identity (to handled cycles, shared refs), with @JsonIdentityInfo * [JACKSON-435]: Allow per-property Date formatting using @JsonFormat. * [JACKSON-437]: Allow injecting of type id as POJO property, by setting new '@JsonTypeInfo.visible' property to true. * [JACKSON-469]: Support "Builder pattern" for deserialiation; that is, allow use of separate Builder object for data binding, creating actual value * [JACKSON-608]: Allow use of JSON Views for deserialization * [JACKSON-636]: Add 'SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS' to allow forced sorting of Maps during serialization (suggested by Joern H) * [JACKSON-669]: Allow prefix/suffix for @JsonUnwrapped properties (requested by Aner P) * [JACKSON-707]: Add 'JsonNode.deepCopy()', to create safe deep copies of ObjectNodes, ArrayNodes. * [JACKSON-714]: Add general-purpose @JsonFormat annotation * [JACKSON-718]: Added 'JsonNode.canConvertToInt()', 'JsonNode.canConvertToLong()' * [JACKSON-747]: Allow changing of 'SerializationFeature' for ObjectWriter, 'DeserializationFeature' for ObjectReader. * [JACKSON-752]: Add @JsonInclude (replacement of @JsonSerialize.include) * [JACKSON-754]: Add @JacksonAnnotationsInside for creating "annotation bundles" (also: AnnotationIntrospector.isAnnotationBundle()) * [JACKSON-762]: Allow using @JsonTypeId to specify property to use as type id, instead of using separate type id resolver. * [JACKSON-764]: Allow specifying "root name" to use for root wrapping via ObjectReader, ObjectWriter. * [JACKSON-772]: Add 'JsonNode.withArray()' to use for traversing Array nodes. * [JACKSON-793]: Add support for configurable Locale, TimeZone to use (via SerializationConfig, DeserializationConfig) * [JACKSON-805]: Add 'SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED' to improve interoperability with BadgerFish/Jettison * [JACKSON-810]: Deserialization Feature: Allow unknown Enum values via 'DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL' (suggested by Raymond R) * [JACKSON-813]: Add '@JsonSerializableSchema.id' attribute, to indicate 'id' value to add to generated JSON Schemas. [entries for versions 1.x and earlier not retained; refer to earlier releases) jackson-databind-jackson-databind-2.2.2/src/000077500000000000000000000000001215056657300207045ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/000077500000000000000000000000001215056657300216305ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/000077500000000000000000000000001215056657300225515ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/000077500000000000000000000000001215056657300233275ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/000077500000000000000000000000001215056657300253345ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/000077500000000000000000000000001215056657300267645ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/000077500000000000000000000000001215056657300305325ustar00rootroot00000000000000AbstractTypeResolver.java000066400000000000000000000042241215056657300354470ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; /** * Defines interface for resolvers that can resolve abstract types into concrete * ones; either by using static mappings, or possibly by materializing * implementations dynamically. */ public abstract class AbstractTypeResolver { /** * Try to locate a subtype for given abstract type, to either resolve * to a concrete type, or at least to a more-specific (and hopefully supported) * abstract type, one which may have registered deserializers. * Method is called before trying to locate registered deserializers * (as well as standard abstract type defaulting that core Jackson does), * so it is typically implemented to add custom mappings of common abstract * types (like specify which concrete implementation to use for binding * {@link java.util.List}s). *

* Note that this method does not necessarily have to do full resolution * of bindings; that is, it is legal to return type that could be further * resolved: caller is expected to keep calling this method on registered * resolvers, until a concrete type is located. * * @param config Configuration in use; should always be of type * DeserializationConfig */ public JavaType findTypeMapping(DeserializationConfig config, JavaType type) { return null; } /** * Method called to try to resolve an abstract type into * concrete type (usually for purposes of deserializing), * when no concrete implementation was found. * It will be called after checking all other possibilities, * including defaulting. * * @param config Configuration in use; should always be of type * DeserializationConfig * @param type Type for which materialization maybe needed * * @return Resolved concrete type (which should retain generic * type parameters of input type, if any), if resolution succeeds; * null if resolver does not know how to resolve type */ public JavaType resolveAbstractType(DeserializationConfig config, JavaType type) { return null; } } AnnotationIntrospector.java000066400000000000000000001221121215056657300360430ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.lang.annotation.Annotation; import java.util.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.core.Versioned; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.deser.ValueInstantiator; import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.util.Converter; import com.fasterxml.jackson.databind.util.NameTransformer; /** * Abstract class that defines API used for introspecting annotation-based * configuration for serialization and deserialization. Separated * so that different sets of annotations can be supported, and support * plugged-in dynamically. *

* NOTE: due to rapid addition of new methods (and changes to existing methods), * it is strongly recommended that custom implementations should not directly * extend this class, but rather extend {@link NopAnnotationIntrospector}. * This way added methods will not break backwards compatibility of custom annotation * introspectors. */ @SuppressWarnings("serial") public abstract class AnnotationIntrospector implements Versioned, java.io.Serializable { /* /********************************************************** /* Helper types /********************************************************** */ /** * Value type used with managed and back references; contains type and * logic name, used to link related references */ public static class ReferenceProperty { public enum Type { /** * Reference property that Jackson manages and that is serialized normally (by serializing * reference object), but is used for resolving back references during * deserialization. * Usually this can be defined by using * {@link com.fasterxml.jackson.annotation.JsonManagedReference} */ MANAGED_REFERENCE /** * Reference property that Jackson manages by suppressing it during serialization, * and reconstructing during deserialization. * Usually this can be defined by using * {@link com.fasterxml.jackson.annotation.JsonBackReference} */ ,BACK_REFERENCE ; } private final Type _type; private final String _name; public ReferenceProperty(Type t, String n) { _type = t; _name = n; } public static ReferenceProperty managed(String name) { return new ReferenceProperty(Type.MANAGED_REFERENCE, name); } public static ReferenceProperty back(String name) { return new ReferenceProperty(Type.BACK_REFERENCE, name); } public Type getType() { return _type; } public String getName() { return _name; } public boolean isManagedReference() { return _type == Type.MANAGED_REFERENCE; } public boolean isBackReference() { return _type == Type.BACK_REFERENCE; } } /* /********************************************************** /* Factory methods /********************************************************** */ /** * Factory method for accessing "no operation" implementation * of introspector: instance that will never find any annotation-based * configuration. */ public static AnnotationIntrospector nopInstance() { return NopAnnotationIntrospector.instance; } public static AnnotationIntrospector pair(AnnotationIntrospector a1, AnnotationIntrospector a2) { return new AnnotationIntrospectorPair(a1, a2); } /* /********************************************************** /* Access to possibly chained introspectors (1.7) /********************************************************** */ /** * Method that can be used to collect all "real" introspectors that * this introspector contains, if any; or this introspector * if it is not a container. Used to get access to all container * introspectors in their priority order. *

* Default implementation returns a Singleton list with this introspector * as contents. * This usually works for sub-classes, except for proxy or delegating "container * introspectors" which need to override implementation. */ public Collection allIntrospectors() { return Collections.singletonList(this); } /** * Method that can be used to collect all "real" introspectors that * this introspector contains, if any; or this introspector * if it is not a container. Used to get access to all container * introspectors in their priority order. *

* Default implementation adds this introspector in result; this usually * works for sub-classes, except for proxy or delegating "container * introspectors" which need to override implementation. */ public Collection allIntrospectors(Collection result) { result.add(this); return result; } /* /********************************************************** /* Default Versioned impl /********************************************************** */ @Override public abstract Version version(); /* /********************************************************** /* Meta-annotations (annotations for annotation types) /********************************************************** */ /** * Method called by framework to determine whether given annotation * is handled by this introspector. * * @deprecated Not used since 2.0; deprecated since 2.1 */ @Deprecated public boolean isHandled(Annotation ann) { return false; } /** * Method for checking whether given annotation is considered an * annotation bundle: if so, all meta-annotations it has will * be used instead of annotation ("bundle") itself. * * @since 2.0 */ public boolean isAnnotationBundle(Annotation ann) { return false; } /* /********************************************************** /* General annotations (for classes, properties) /********************************************************** */ /** * Method for checking whether given annotated thing * (type, or accessor) indicates that values * referenced (values of type of annotated class, or * values referenced by annotated property; latter * having precedence) should include Object Identifier, * and if so, specify details of Object Identity used. * * @since 2.0 */ public ObjectIdInfo findObjectIdInfo(Annotated ann) { return null; } /** * Method for figuring out additional properties of an Object Identity reference * * @since 2.1 */ public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo objectIdInfo) { return objectIdInfo; } /* /********************************************************** /* General class annotations /********************************************************** */ /** * Method for locating name used as "root name" (for use by * some serializers when outputting root-level object -- mostly * for XML compatibility purposes) for given class, if one * is defined. Returns null if no declaration found; can return * explicit empty String, which is usually ignored as well as null. *

* NOTE: method signature changed in 2.1, to return {@link PropertyName} * instead of String. */ public PropertyName findRootName(AnnotatedClass ac) { return null; } /** * Method for finding list of properties to ignore for given class * (null is returned if not specified). * List of property names is applied * after other detection mechanisms, to filter out these specific * properties from being serialized and deserialized. */ public String[] findPropertiesToIgnore(Annotated ac) { return null; } /** * Method for checking whether an annotation indicates that all unknown properties */ public Boolean findIgnoreUnknownProperties(AnnotatedClass ac) { return null; } /** * Method for checking whether properties that have specified type * (class, not generics aware) should be completely ignored for * serialization and deserialization purposes. * * @param ac Type to check * * @return Boolean.TRUE if properties of type should be ignored; * Boolean.FALSE if they are not to be ignored, null for default * handling (which is 'do not ignore') */ public Boolean isIgnorableType(AnnotatedClass ac) { return null; } /** * Method for finding if annotated class has associated filter; and if so, * to return id that is used to locate filter. * * @return Id of the filter to use for filtering properties of annotated * class, if any; or null if none found. */ public Object findFilterId(AnnotatedClass ac) { return null; } /** * Method for finding {@link PropertyNamingStrategy} for given * class, if any specified by annotations; and if so, either return * a {@link PropertyNamingStrategy} instance, or Class to use for * creating instance * * @return Sub-class or instance of {@link PropertyNamingStrategy}, if one * is specified for given class; null if not. * * @since 2.1 */ public Object findNamingStrategy(AnnotatedClass ac) { return null; } /* /********************************************************** /* Property auto-detection /********************************************************** */ /** * Method for checking if annotations indicate changes to minimum visibility levels * needed for auto-detecting property elements (fields, methods, constructors). * A baseline checker is given, and introspector is to either return it as is * (if no annotations are found), or build and return a derived instance (using * checker's build methods). */ public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, VisibilityChecker checker) { return checker; } /* /********************************************************** /* Class annotations for Polymorphic type handling (1.5+) /********************************************************** */ /** * Method for checking if given class has annotations that indicate * that specific type resolver is to be used for handling instances. * This includes not only * instantiating resolver builder, but also configuring it based on * relevant annotations (not including ones checked with a call to * {@link #findSubtypes} * * @param config Configuration settings in effect (for serialization or deserialization) * @param ac Annotated class to check for annotations * @param baseType Base java type of value for which resolver is to be found * * @return Type resolver builder for given type, if one found; null if none */ public TypeResolverBuilder findTypeResolver(MapperConfig config, AnnotatedClass ac, JavaType baseType) { return null; } /** * Method for checking if given property entity (field or method) has annotations * that indicate that specific type resolver is to be used for handling instances. * This includes not only * instantiating resolver builder, but also configuring it based on * relevant annotations (not including ones checked with a call to * {@link #findSubtypes} * * @param config Configuration settings in effect (for serialization or deserialization) * @param am Annotated member (field or method) to check for annotations * @param baseType Base java type of property for which resolver is to be found * * @return Type resolver builder for properties of given entity, if one found; * null if none */ public TypeResolverBuilder findPropertyTypeResolver(MapperConfig config, AnnotatedMember am, JavaType baseType) { return null; } /** * Method for checking if given structured property entity (field or method that * has nominal value of Map, Collection or array type) has annotations * that indicate that specific type resolver is to be used for handling type * information of contained values. * This includes not only * instantiating resolver builder, but also configuring it based on * relevant annotations (not including ones checked with a call to * {@link #findSubtypes} * * @param config Configuration settings in effect (for serialization or deserialization) * @param am Annotated member (field or method) to check for annotations * @param containerType Type of property for which resolver is to be found (must be a container type) * * @return Type resolver builder for values contained in properties of given entity, * if one found; null if none */ public TypeResolverBuilder findPropertyContentTypeResolver(MapperConfig config, AnnotatedMember am, JavaType containerType) { return null; } /** * Method for locating annotation-specified subtypes related to annotated * entity (class, method, field). Note that this is only guaranteed to be * a list of directly * declared subtypes, no recursive processing is guarantees (i.e. caller * has to do it if/as necessary) * * @param a Annotated entity (class, field/method) to check for annotations */ public List findSubtypes(Annotated a) { return null; } /** * Method for checking if specified type has explicit name. * * @param ac Class to check for type name annotations */ public String findTypeName(AnnotatedClass ac) { return null; } /* /********************************************************** /* General member (field, method/constructor) annotations /********************************************************** */ /** * Method for checking if given member indicates that it is part * of a reference (parent/child). */ public ReferenceProperty findReferenceType(AnnotatedMember member) { return null; } /** * Method called to check whether given property is marked to be "unwrapped" * when being serialized (and appropriately handled in reverse direction, * i.e. expect unwrapped representation during deserialization). * Return value is the name transformation to use, if wrapping/unwrapping * should be done, or null if not -- note that transformation may simply * be identity transformation (no changes). */ public NameTransformer findUnwrappingNameTransformer(AnnotatedMember member) { return null; } /** * Method called to check whether given property is marked to * be ignored. This is used to determine whether to ignore * properties, on per-property basis, usually combining * annotations from multiple accessors (getters, setters, fields, * constructor parameters). */ public boolean hasIgnoreMarker(AnnotatedMember m) { return false; } /** * Method called to find out whether given member expectes a value * to be injected, and if so, what is the identifier of the value * to use during injection. * Type if identifier needs to be compatible with provider of * values (of type {@link InjectableValues}); often a simple String * id is used. * * @param m Member to check * * @return Identifier of value to inject, if any; null if no injection * indicator is found */ public Object findInjectableValueId(AnnotatedMember m) { return null; } /** * Method that can be called to check whether this member has * an annotation that suggests whether value for matching property * is required or not. * * @since 2.0 */ public Boolean hasRequiredMarker(AnnotatedMember m) { return null; } /** * Method for checking if annotated property (represented by a field or * getter/setter method) has definitions for views it is to be included in. * If null is returned, no view definitions exist and property is always * included (or always excluded as per default view inclusion configuration); * otherwise it will only be included for views included in returned * array. View matches are checked using class inheritance rules (sub-classes * inherit inclusions of super-classes) * * @param a Annotated property (represented by a method, field or ctor parameter) * @return Array of views (represented by classes) that the property is included in; * if null, always included (same as returning array containing Object.class) */ public Class[] findViews(Annotated a) { return null; } /** * Method for finding format annotations for given member. * Return value is typically used by serializers and/or * deserializers to customize presentation aspects of the * serialized value. * * @since 2.0 * * @deprecated Since 2.1, use {@link #findFormat(Annotated)} instead. */ @Deprecated public JsonFormat.Value findFormat(AnnotatedMember member) { return null; } /** * Method for finding format annotations for property or class. * Return value is typically used by serializers and/or * deserializers to customize presentation aspects of the * serialized value. * * @since 2.1 */ public JsonFormat.Value findFormat(Annotated memberOrClass) { if (memberOrClass instanceof AnnotatedMember) { return findFormat((AnnotatedMember) memberOrClass); } return null; } /** * Method for checking whether given accessor claims to represent * type id: if so, its value may be used as an override, * instead of generated type id. * * @since 2.0 */ public Boolean isTypeId(AnnotatedMember member) { return null; } /** * Method used to check if specified property has annotation that indicates * that it should be wrapped in an element; and if so, name to use. * Note that not all serializers and deserializers support use this method: * currently (2.1) it is only used by XML-backed handlers. * * @return Wrapper name to use, if any, or {@link PropertyName#USE_DEFAULT} * to indicate that no wrapper element should be used. * * @since 2.1 */ public PropertyName findWrapperName(Annotated ann) { return null; } /* /********************************************************** /* Serialization: general annotations /********************************************************** */ /** * Method for getting a serializer definition on specified method * or field. Type of definition is either instance (of type * {@link JsonSerializer}) or Class (of type * Class); if value of different * type is returned, a runtime exception may be thrown by caller. */ public Object findSerializer(Annotated am) { return null; } /** * Method for getting a serializer definition for keys of associated Map property. * Type of definition is either instance (of type * {@link JsonSerializer}) or Class (of type * Class); if value of different * type is returned, a runtime exception may be thrown by caller. */ public Object findKeySerializer(Annotated am) { return null; } /** * Method for getting a serializer definition for content (values) of * associated Collection, array or Map property. * Type of definition is either instance (of type * {@link JsonSerializer}) or Class (of type * Class); if value of different * type is returned, a runtime exception may be thrown by caller. */ public Object findContentSerializer(Annotated am) { return null; } /** * Method for checking whether given annotated entity (class, method, * field) defines which Bean/Map properties are to be included in * serialization. * If no annotation is found, method should return given second * argument; otherwise value indicated by the annotation * * @return Enumerated value indicating which properties to include * in serialization */ public JsonInclude.Include findSerializationInclusion(Annotated a, JsonInclude.Include defValue) { return defValue; } /** * Method for accessing annotated type definition that a * method/field can have, to be used as the type for serialization * instead of the runtime type. * Type returned (if any) needs to be widening conversion (super-type). * Declared return type of the method is also considered acceptable. * * @return Class to use instead of runtime type */ public Class findSerializationType(Annotated a) { return null; } /** * Method for finding possible widening type definition that a property * value can have, to define less specific key type to use for serialization. * It should be only be used with {@link java.util.Map} types. * * @return Class specifying more general type to use instead of * declared type, if annotation found; null if not */ public Class findSerializationKeyType(Annotated am, JavaType baseType) { return null; } /** * Method for finding possible widening type definition that a property * value can have, to define less specific key type to use for serialization. * It should be only used with structured types (arrays, collections, maps). * * @return Class specifying more general type to use instead of * declared type, if annotation found; null if not */ public Class findSerializationContentType(Annotated am, JavaType baseType) { return null; } /** * Method for accessing declared typing mode annotated (if any). * This is used for type detection, unless more granular settings * (such as actual exact type; or serializer to use which means * no type information is needed) take precedence. * * @return Typing mode to use, if annotation is found; null otherwise */ public JsonSerialize.Typing findSerializationTyping(Annotated a) { return null; } /** * Method for finding {@link Converter} that annotated entity * (property or class) has indicated to be used as part of * serialization. If not null, either has to be actual * {@link Converter} instance, or class for such converter; * and resulting converter will be used first to convert property * value to converter target type, and then serializer for that * type is used for actual serialization. *

* This feature is typically used to convert internal values into types * that Jackson can convert. *

* Note also that this feature does not necessarily work well with polymorphic * type handling, or object identity handling; if such features are needed * an explicit serializer is usually better way to handle serialization. * * @param a Annotated property (field, method) or class to check for * annotations * * @since 2.2 */ public Object findSerializationConverter(Annotated a) { return null; } /** * Method for finding {@link Converter} that annotated property * has indicated needs to be used for values of container type * (this also means that method should only be called for properties * of container types, List/Map/array properties). *

* If not null, either has to be actual * {@link Converter} instance, or class for such converter; * and resulting converter will be used first to convert property * value to converter target type, and then serializer for that * type is used for actual serialization. *

* Other notes are same as those for {@link #findSerializationConverter} * * @param a Annotated property (field, method) to check. * * @since 2.2 */ public Object findSerializationContentConverter(AnnotatedMember a) { return null; } /* /********************************************************** /* Serialization: class annotations /********************************************************** */ /** * Method for accessing defined property serialization order (which may be * partial). May return null if no ordering is defined. */ public String[] findSerializationPropertyOrder(AnnotatedClass ac) { return null; } /** * Method for checking whether an annotation indicates that serialized properties * for which no explicit is defined should be alphabetically (lexicograpically) * ordered */ public Boolean findSerializationSortAlphabetically(AnnotatedClass ac) { return null; } /* /********************************************************** /* Serialization: property annotations /********************************************************** */ /** * Method for checking whether given property accessors (method, * field) has an annotation that suggests property name to use * for serialization. * Should return null if no annotation * is found; otherwise a non-null name (possibly * {@link PropertyName#USE_DEFAULT}, which means "use default heuristics"). * * @param a Property accessor to check * * @return Name to use if found; null if not. * * @since 2.1 */ public PropertyName findNameForSerialization(Annotated a) { // [Issue#69], need bit of delegation // !!! TODO: in 2.2, remove old methods? String name; if (a instanceof AnnotatedField) { name = findSerializationName((AnnotatedField) a); } else if (a instanceof AnnotatedMethod) { name = findSerializationName((AnnotatedMethod) a); } else { name = null; } if (name != null) { if (name.length() == 0) { // empty String means 'default' return PropertyName.USE_DEFAULT; } return new PropertyName(name); } return null; } /** * Method for checking whether given method has an annotation * that suggests property name associated with method that * may be a "getter". Should return null if no annotation * is found; otherwise a non-null String. * If non-null value is returned, it is used as the property * name, except for empty String ("") which is taken to mean * "use standard bean name detection if applicable; * method name if not". * * @deprecated Since 2.1 should use {@link #findNameForSerialization} instead */ @Deprecated public String findSerializationName(AnnotatedMethod am) { return null; } /** * Method for checking whether given member field represent * a serializable logical property; and if so, returns the * name of that property. * Should return null if no annotation is found (indicating it * is not a serializable field); otherwise a non-null String. * If non-null value is returned, it is used as the property * name, except for empty String ("") which is taken to mean * "use the field name as is". * * @deprecated Since 2.1 should use {@link #findNameForSerialization} instead */ @Deprecated public String findSerializationName(AnnotatedField af) { return null; } /** * Method for checking whether given method has an annotation * that suggests that the return value of annotated method * should be used as "the value" of the object instance; usually * serialized as a primitive value such as String or number. * * @return True if such annotation is found (and is not disabled); * false if no enabled annotation is found */ public boolean hasAsValueAnnotation(AnnotatedMethod am) { return false; } /** * Method for determining the String value to use for serializing * given enumeration entry; used when serializing enumerations * as Strings (the standard method). * * @return Serialized enum value. */ public String findEnumValue(Enum value) { // as per [JACKSON-875], should use default here return value.name(); } /* /********************************************************** /* Deserialization: general annotations /********************************************************** */ /** * Method for getting a deserializer definition on specified method * or field. * Type of definition is either instance (of type * {@link JsonDeserializer}) or Class (of type * Class); if value of different * type is returned, a runtime exception may be thrown by caller. */ public Object findDeserializer(Annotated am) { return null; } /** * Method for getting a deserializer definition for keys of * associated Map property. * Type of definition is either instance (of type * {@link JsonDeserializer}) or Class (of type * Class); if value of different * type is returned, a runtime exception may be thrown by caller. */ public Object findKeyDeserializer(Annotated am) { return null; } /** * Method for getting a deserializer definition for content (values) of * associated Collection, array or * Map property. * Type of definition is either instance (of type * {@link JsonDeserializer}) or Class (of type * Class); if value of different * type is returned, a runtime exception may be thrown by caller. */ public Object findContentDeserializer(Annotated am) { return null; } /** * Method for accessing annotated type definition that a * method can have, to be used as the type for serialization * instead of the runtime type. * Type must be a narrowing conversion * (i.e.subtype of declared type). * Declared return type of the method is also considered acceptable. * * @param baseType Assumed type before considering annotations * * @return Class to use for deserialization instead of declared type */ public Class findDeserializationType(Annotated am, JavaType baseType) { return null; } /** * Method for accessing additional narrowing type definition that a * method can have, to define more specific key type to use. * It should be only be used with {@link java.util.Map} types. * * @param baseKeyType Assumed key type before considering annotations * * @return Class specifying more specific type to use instead of * declared type, if annotation found; null if not */ public Class findDeserializationKeyType(Annotated am, JavaType baseKeyType) { return null; } /** * Method for accessing additional narrowing type definition that a * method can have, to define more specific content type to use; * content refers to Map values and Collection/array elements. * It should be only be used with Map, Collection and array types. * * @param baseContentType Assumed content (value) type before considering annotations * * @return Class specifying more specific type to use instead of * declared type, if annotation found; null if not */ public Class findDeserializationContentType(Annotated am, JavaType baseContentType) { return null; } /** * Method for finding {@link Converter} that annotated entity * (property or class) has indicated to be used as part of * deserialization. * If not null, either has to be actual * {@link Converter} instance, or class for such converter; * and resulting converter will be used after Jackson has deserializer * data into intermediate type (Converter input type), and Converter * needs to convert this into its target type to be set as property value. *

* This feature is typically used to convert intermediate Jackson types * (that default deserializers can produce) into custom type instances. *

* Note also that this feature does not necessarily work well with polymorphic * type handling, or object identity handling; if such features are needed * an explicit deserializer is usually better way to handle deserialization. * * @param a Annotated property (field, method) or class to check for * annotations * * @since 2.2 */ public Object findDeserializationConverter(Annotated a) { return null; } /** * Method for finding {@link Converter} that annotated property * has indicated needs to be used for values of container type * (this also means that method should only be called for properties * of container types, List/Map/array properties). *

* If not null, either has to be actual * {@link Converter} instance, or class for such converter; * and resulting converter will be used after Jackson has deserializer * data into intermediate type (Converter input type), and Converter * needs to convert this into its target type to be set as property value. *

* Other notes are same as those for {@link #findDeserializationConverter} * * @param a Annotated property (field, method) to check. * * @since 2.2 */ public Object findDeserializationContentConverter(AnnotatedMember a) { return null; } /* /********************************************************** /* Deserialization: class annotations /********************************************************** */ /** * Method getting {@link ValueInstantiator} to use for given * type (class): return value can either be an instance of * instantiator, or class of instantiator to create. */ public Object findValueInstantiator(AnnotatedClass ac) { return null; } /** * Method for finding Builder object to use for constructing * value instance and binding data (sort of combining value * instantiators that can construct, and deserializers * that can bind data). *

* Note that unlike accessors for some helper Objects, this * method does not allow returning instances: the reason is * that builders have state, and a separate instance needs * to be created for each deserialization call. * * @since 2.0 */ public Class findPOJOBuilder(AnnotatedClass ac) { return null; } /** * @since 2.0 */ public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) { return null; } /* /********************************************************** /* Deserialization: property annotations /********************************************************** */ /** * Method for checking whether given property accessors (method, * field) has an annotation that suggests property name to use * for deserialization (reading JSON into POJOs). * Should return null if no annotation * is found; otherwise a non-null name (possibly * {@link PropertyName#USE_DEFAULT}, which means "use default heuristics"). * * @param a Property accessor to check * * @return Name to use if found; null if not. * * @since 2.1 */ public PropertyName findNameForDeserialization(Annotated a) { // [Issue#69], need bit of delegation // !!! TODO: in 2.2, remove old methods? String name; if (a instanceof AnnotatedField) { name = findDeserializationName((AnnotatedField) a); } else if (a instanceof AnnotatedMethod) { name = findDeserializationName((AnnotatedMethod) a); } else if (a instanceof AnnotatedParameter) { name = findDeserializationName((AnnotatedParameter) a); } else { name = null; } if (name != null) { if (name.length() == 0) { // empty String means 'default' return PropertyName.USE_DEFAULT; } return new PropertyName(name); } return null; } /** * Method for checking whether given method has an annotation * that suggests property name associated with method that * may be a "setter". Should return null if no annotation * is found; otherwise a non-null String. * If non-null value is returned, it is used as the property * name, except for empty String ("") which is taken to mean * "use standard bean name detection if applicable; * method name if not". * * @deprecated Since 2.1 should use {@link #findNameForDeserialization} instead */ @Deprecated public String findDeserializationName(AnnotatedMethod am) { return null; } /** * Method for checking whether given member field represent * a deserializable logical property; and if so, returns the * name of that property. * Should return null if no annotation is found (indicating it * is not a deserializable field); otherwise a non-null String. * If non-null value is returned, it is used as the property * name, except for empty String ("") which is taken to mean * "use the field name as is". * * @deprecated Since 2.1 should use {@link #findNameForDeserialization} instead */ @Deprecated public String findDeserializationName(AnnotatedField af) { return null; } /** * Method for checking whether given set of annotations indicates * property name for associated parameter. * No actual parameter object can be passed since JDK offers no * representation; just annotations. * * @deprecated Since 2.1 should use {@link #findNameForDeserialization} instead */ @Deprecated public String findDeserializationName(AnnotatedParameter param) { return null; } /** * Method for checking whether given method has an annotation * that suggests that the method is to serve as "any setter"; * method to be used for setting values of any properties for * which no dedicated setter method is found. * * @return True if such annotation is found (and is not disabled), * false otherwise */ public boolean hasAnySetterAnnotation(AnnotatedMethod am) { return false; } /** * Method for checking whether given method has an annotation * that suggests that the method is to serve as "any setter"; * method to be used for accessing set of miscellaneous "extra" * properties, often bound with matching "any setter" method. * * @return True if such annotation is found (and is not disabled), * false otherwise */ public boolean hasAnyGetterAnnotation(AnnotatedMethod am) { return false; } /** * Method for checking whether given annotated item (method, constructor) * has an annotation * that suggests that the method is a "creator" (aka factory) * method to be used for construct new instances of deserialized * values. * * @return True if such annotation is found (and is not disabled), * false otherwise */ public boolean hasCreatorAnnotation(Annotated a) { return false; } /* /********************************************************** /* Helper classes /********************************************************** */ /** * Old version of {@link AnnotationIntrospectorPair}. * * @deprecated Starting with 2.1, use {@link AnnotationIntrospectorPair} instead. */ @Deprecated public static class Pair extends AnnotationIntrospectorPair { private static final long serialVersionUID = 1L; @Deprecated public Pair(AnnotationIntrospector p, AnnotationIntrospector s) { super(p, s); } } } BeanDescription.java000066400000000000000000000206001215056657300343650ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.type.TypeBindings; import com.fasterxml.jackson.databind.util.Annotations; import com.fasterxml.jackson.databind.util.Converter; /** * Basic container for information gathered by {@link ClassIntrospector} to * help in constructing serializers and deserializers. * Note that the main implementation type is * {@link com.fasterxml.jackson.databind.introspect.BasicBeanDescription}, * meaning that it is safe to upcast to this type. */ public abstract class BeanDescription { /* /********************************************************** /* Configuration /********************************************************** */ /** * Bean type information, including raw class and possible * * generics information */ protected final JavaType _type; /* /********************************************************** /* Life-cycle /********************************************************** */ protected BeanDescription(JavaType type) { _type = type; } /* /********************************************************** /* Simple accesors /********************************************************** */ /** * Method for accessing declared type of bean being introspected, * including full generic type information (from declaration) */ public JavaType getType() { return _type; } public Class getBeanClass() { return _type.getRawClass(); } /** * Method for accessing low-level information about Class this * item describes. */ public abstract AnnotatedClass getClassInfo(); /** * Accessor for getting information about Object Id expected to * be used for this POJO type, if any. */ public abstract ObjectIdInfo getObjectIdInfo(); /** * Method for checking whether class being described has any * annotations recognized by registered annotation introspector. */ public abstract boolean hasKnownClassAnnotations(); /** * Accessor for type bindings that may be needed to fully resolve * types of member object, such as return and argument types of * methods and constructors, and types of fields. */ public abstract TypeBindings bindingsForBeanType(); /** * Method for resolving given JDK type, using this bean as the * generic type resolution context. */ public abstract JavaType resolveType(java.lang.reflect.Type jdkType); /** * Method for accessing collection of annotations the bean * class has. */ public abstract Annotations getClassAnnotations(); /* /********************************************************** /* Basic API for finding properties /********************************************************** */ /** * @return Ordered Map with logical property name as key, and * matching getter method as value. */ public abstract List findProperties(); /** * Method for locating all back-reference properties (setters, fields) bean has */ public abstract Map findBackReferenceProperties(); public abstract Set getIgnoredPropertyNames(); /* /********************************************************** /* Basic API for finding creator members /********************************************************** */ public abstract List getConstructors(); public abstract List getFactoryMethods(); /** * Method that will locate the no-arg constructor for this class, * if it has one, and that constructor has not been marked as * ignorable. */ public abstract AnnotatedConstructor findDefaultConstructor(); /** * Method that can be called to locate a single-arg constructor that * takes specified exact type (will not accept supertype constructors) * * @param argTypes Type(s) of the argument that we are looking for */ public abstract Constructor findSingleArgConstructor(Class... argTypes); /** * Method that can be called to find if introspected class declares * a static "valueOf" factory method that returns an instance of * introspected type, given one of acceptable types. * * @param expArgTypes Types that the matching single argument factory * method can take: will also accept super types of these types * (ie. arg just has to be assignable from expArgType) */ public abstract Method findFactoryMethod(Class... expArgTypes); /* /********************************************************** /* Basic API for finding property accessors /********************************************************** */ public abstract AnnotatedMember findAnyGetter(); /** * Method used to locate the method of introspected class that * implements {@link com.fasterxml.jackson.annotation.JsonAnySetter}. If no such method exists * null is returned. If more than one are found, an exception * is thrown. * Additional checks are also made to see that method signature * is acceptable: needs to take 2 arguments, first one String or * Object; second any can be any type. */ public abstract AnnotatedMethod findAnySetter(); /** * Method for locating the getter method that is annotated with * {@link com.fasterxml.jackson.annotation.JsonValue} annotation, * if any. If multiple ones are found, * an error is reported by throwing {@link IllegalArgumentException} */ public abstract AnnotatedMethod findJsonValueMethod(); public abstract AnnotatedMethod findMethod(String name, Class[] paramTypes); /* /********************************************************** /* Basic API, class configuration /********************************************************** */ public abstract JsonInclude.Include findSerializationInclusion(JsonInclude.Include defValue); /** * Method for checking what is the expected format for POJO, as * defined by defaults and possible annotations. * Note that this may be further refined by per-property annotations. * * @since 2.1 */ public abstract JsonFormat.Value findExpectedFormat(JsonFormat.Value defValue); /** * Method for finding {@link Converter} used for serializing instances * of this class. * * @since 2.2 */ public abstract Converter findSerializationConverter(); /** * Method for finding {@link Converter} used for serializing instances * of this class. * * @since 2.2 */ public abstract Converter findDeserializationConverter(); /* /********************************************************** /* Basic API, other /********************************************************** */ public abstract Map findInjectables(); /** * Method for checking if the POJO type has annotations to * indicate that a builder is to be used for instantiating * instances and handling data binding, instead of standard * bean deserializer. */ public abstract Class findPOJOBuilder(); /** * Method for finding configuration for POJO Builder class. */ public abstract JsonPOJOBuilder.Value findPOJOBuilderConfig(); /** * Method called to create a "default instance" of the bean, currently * only needed for obtaining default field values which may be used for * suppressing serialization of fields that have "not changed". * * @param fixAccess If true, method is allowed to fix access to the * default constructor (to be able to call non-public constructor); * if false, has to use constructor as is. * * @return Instance of class represented by this descriptor, if * suitable default constructor was found; null otherwise. */ public abstract Object instantiateBean(boolean fixAccess); } BeanProperty.java000066400000000000000000000140641215056657300337350ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.lang.annotation.Annotation; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor; import com.fasterxml.jackson.databind.util.Annotations; import com.fasterxml.jackson.databind.util.Named; /** * Bean properties are logical entities that represent data * that Java objects (POJOs (Plain Old Java Objects), sometimes also called "beans") * contain; and that are accessed using accessors (methods like getters * and setters, fields, contstructor parametrers). * Instances allow access to annotations directly associated * to property (via field or method), as well as contextual * annotations (annotations for class that contains properties). *

* Instances are not typically passed when constructing serializers * and deserializers, but rather only passed when context * is known when * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer} and * {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer} * resolution occurs (createContextual(...) method is called). * References may (need to) be retained by serializers and deserializers, * especially when further resolving dependant handlers like value * serializers/deserializers or structured types. */ public interface BeanProperty extends Named { /** * Method to get logical name of the property */ @Override public String getName(); /** * Method to get declared type of the property. */ public JavaType getType(); /** * If property is indicated to be wrapped, name of * wrapper element to use. * * @since 2.2 */ public PropertyName getWrapperName(); /** * Whether value for property is marked as required using * annotations or associated schema. * * @since 2.2 */ public boolean isRequired(); /** * Method for finding annotation associated with this property; * meaning annotation associated with one of entities used to * access property. */ public A getAnnotation(Class acls); /** * Method for finding annotation associated with context of * this property; usually class in which member is declared * (or its subtype if processing subtype). */ public A getContextAnnotation(Class acls); /** * Method for accessing primary physical entity that represents the property; * annotated field, method or constructor property. */ public AnnotatedMember getMember(); /** * Method that can be called to visit the type structure that this * property is part of. * Note that not all implementations support traversal with this * method; those that do not should throw * {@link UnsupportedOperationException}. * * @param objectVisitor Visitor to used as the callback handler * * @since 2.2 */ public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor) throws JsonMappingException; /* /********************************************************** /* Helper classes /********************************************************** */ /** * Simple stand-alone implementation, useful as a placeholder * or base class for more complex implementations. */ public static class Std implements BeanProperty { protected final String _name; protected final JavaType _type; protected final PropertyName _wrapperName; protected final boolean _isRequired; /** * Physical entity (field, method or constructor argument) that * is used to access value of property (or in case of constructor * property, just placeholder) */ protected final AnnotatedMember _member; /** * Annotations defined in the context class (if any); may be null * if no annotations were found */ protected final Annotations _contextAnnotations; public Std(String name, JavaType type, PropertyName wrapperName, Annotations contextAnnotations, AnnotatedMember member, boolean isRequired) { _name = name; _type = type; _wrapperName = wrapperName; _isRequired = isRequired; _member = member; _contextAnnotations = contextAnnotations; } public Std withType(JavaType type) { return new Std(_name, type, _wrapperName, _contextAnnotations, _member, _isRequired); } @Override public A getAnnotation(Class acls) { return (_member == null) ? null : _member.getAnnotation(acls); } @Override public A getContextAnnotation(Class acls) { return (_contextAnnotations == null) ? null : _contextAnnotations.get(acls); } @Override public String getName() { return _name; } @Override public JavaType getType() { return _type; } @Override public PropertyName getWrapperName() { return _wrapperName; } @Override public boolean isRequired() { return _isRequired; } @Override public AnnotatedMember getMember() { return _member; } /** * Implementation of this method throws * {@link UnsupportedOperationException}, since instances of this * implementation should not be used as part of actual structure * visited. Rather, other implementations should handle it. */ @Override public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor) { throw new UnsupportedOperationException("Instances of "+getClass().getName() +" should not get visited"); } } } DatabindContext.java000066400000000000000000000135701215056657300343770ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.lang.reflect.Type; import com.fasterxml.jackson.annotation.ObjectIdGenerator; import com.fasterxml.jackson.databind.annotation.NoClass; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.introspect.ObjectIdInfo; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.Converter; /** * Shared base class for {@link DeserializationContext} and * {@link SerializerProvider}, context objects passed through data-binding * process. Designed so that some of implementations can rely on shared * aspects like access to secondary contextual objects like type factories * or handler instantiators. * * @since 2.2 */ public abstract class DatabindContext { /* /********************************************************** /* Generic config access /********************************************************** */ /** * Accessor to currently active configuration (both per-request configs * and per-mapper config). */ public abstract MapperConfig getConfig(); /** * Convenience method for accessing serialization view in use (if any); equivalent to: *

     *   getConfig().getAnnotationIntrospector();
     *
*/ public abstract AnnotationIntrospector getAnnotationIntrospector(); /* /********************************************************** /* Access to specific config settings /********************************************************** */ /** * Convenience method for checking whether specified serialization * feature is enabled or not. * Shortcut for: *
     *  getConfig().isEnabled(feature);
     *
*/ public final boolean isEnabled(MapperFeature feature) { return getConfig().isEnabled(feature); } /** * Convenience method for accessing serialization view in use (if any); equivalent to: *
     *   getConfig().canOverrideAccessModifiers();
     *
*/ public final boolean canOverrideAccessModifiers() { return getConfig().canOverrideAccessModifiers(); } /** * Accessor for locating currently active view, if any; * returns null if no view has been set. */ public abstract Class getActiveView(); /* /********************************************************** /* Type instantiation/resolution /********************************************************** */ /** * Convenience method for constructing {@link JavaType} for given JDK * type (usually {@link java.lang.Class}) */ public JavaType constructType(Type type) { return getTypeFactory().constructType(type); } /** * Convenience method for constructing subtypes, retaining generic * type parameter (if any) */ public JavaType constructSpecializedType(JavaType baseType, Class subclass) { return getConfig().constructSpecializedType(baseType, subclass); } public abstract TypeFactory getTypeFactory(); /* /********************************************************** /* Helper object construction /********************************************************** */ public ObjectIdGenerator objectIdGeneratorInstance(Annotated annotated, ObjectIdInfo objectIdInfo) throws JsonMappingException { Class implClass = objectIdInfo.getGeneratorType(); final MapperConfig config = getConfig(); HandlerInstantiator hi = config.getHandlerInstantiator(); ObjectIdGenerator gen = (hi == null) ? null : hi.objectIdGeneratorInstance(config, annotated, implClass); if (gen == null) { gen = (ObjectIdGenerator) ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers()); } return gen.forScope(objectIdInfo.getScope()); } /** * Helper method to use to construct a {@link Converter}, given a definition * that may be either actual converter instance, or Class for instantiating one. * * @since 2.2 */ @SuppressWarnings("unchecked") public Converter converterInstance(Annotated annotated, Object converterDef) throws JsonMappingException { if (converterDef == null) { return null; } if (converterDef instanceof Converter) { return (Converter) converterDef; } if (!(converterDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type " +converterDef.getClass().getName()+"; expected type Converter or Class instead"); } Class converterClass = (Class)converterDef; // there are some known "no class" markers to consider too: if (converterClass == Converter.None.class || converterClass == NoClass.class) { return null; } if (!Converter.class.isAssignableFrom(converterClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class " +converterClass.getName()+"; expected Class"); } final MapperConfig config = getConfig(); HandlerInstantiator hi = config.getHandlerInstantiator(); Converter conv = (hi == null) ? null : hi.converterInstance(config, annotated, converterClass); if (conv == null) { conv = (Converter) ClassUtil.createInstance(converterClass, config.canOverrideAccessModifiers()); } return (Converter) conv; } } DeserializationConfig.java000066400000000000000000000434541215056657300356040ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.text.DateFormat; import java.util.*; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.cfg.BaseSettings; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfigBase; import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; import com.fasterxml.jackson.databind.introspect.ClassIntrospector; import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector; import com.fasterxml.jackson.databind.introspect.VisibilityChecker; import com.fasterxml.jackson.databind.jsontype.SubtypeResolver; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.type.ClassKey; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.LinkedNode; /** * Object that contains baseline configuration for deserialization * process. An instance is owned by {@link ObjectMapper}, which * passes an immutable instance to be used for deserialization process. *

* Note that instances are considered immutable and as such no copies * should need to be created for sharing; all copying is done with * "fluent factory" methods. * Note also that unlike with Jackson 1, these instances can not be * assigned to {@link ObjectMapper}; in fact, application code should * rarely interact directly with these instance (unlike core Jackson code) */ public final class DeserializationConfig extends MapperConfigBase implements java.io.Serializable // since 2.1 { // for 2.1.0 private static final long serialVersionUID = -4227480407273773599L; /** * Set of features enabled; actual type (kind of features) * depends on sub-classes. */ protected final int _deserFeatures; /** * Linked list that contains all registered problem handlers. * Implementation as front-added linked list allows for sharing * of the list (tail) without copying the list. */ protected final LinkedNode _problemHandlers; /** * Factory used for constructing {@link com.fasterxml.jackson.databind.JsonNode} instances. */ protected final JsonNodeFactory _nodeFactory; /* /********************************************************** /* Life-cycle, constructors /********************************************************** */ /** * Constructor used by ObjectMapper to create default configuration object instance. */ public DeserializationConfig(BaseSettings base, SubtypeResolver str, Map> mixins) { super(base, str, mixins); _deserFeatures = collectFeatureDefaults(DeserializationFeature.class); _nodeFactory = JsonNodeFactory.instance; _problemHandlers = null; } /** * Copy constructor used to create a non-shared instance with given mix-in * annotation definitions and subtype resolver. */ private DeserializationConfig(DeserializationConfig src, SubtypeResolver str) { super(src, str); _deserFeatures = src._deserFeatures; _nodeFactory = src._nodeFactory; _problemHandlers = src._problemHandlers; } private DeserializationConfig(DeserializationConfig src, int mapperFeatures, int deserFeatures) { super(src, mapperFeatures); _deserFeatures = deserFeatures; _nodeFactory = src._nodeFactory; _problemHandlers = src._problemHandlers; } private DeserializationConfig(DeserializationConfig src, BaseSettings base) { super(src, base); _deserFeatures = src._deserFeatures; _nodeFactory = src._nodeFactory; _problemHandlers = src._problemHandlers; } private DeserializationConfig(DeserializationConfig src, JsonNodeFactory f) { super(src); _deserFeatures = src._deserFeatures; _problemHandlers = src._problemHandlers; _nodeFactory = f; } private DeserializationConfig(DeserializationConfig src, LinkedNode problemHandlers) { super(src); _deserFeatures = src._deserFeatures; _problemHandlers = problemHandlers; _nodeFactory = src._nodeFactory; } private DeserializationConfig(DeserializationConfig src, String rootName) { super(src, rootName); _deserFeatures = src._deserFeatures; _problemHandlers = src._problemHandlers; _nodeFactory = src._nodeFactory; } private DeserializationConfig(DeserializationConfig src, Class view) { super(src, view); _deserFeatures = src._deserFeatures; _problemHandlers = src._problemHandlers; _nodeFactory = src._nodeFactory; } /** * @since 2.1 */ protected DeserializationConfig(DeserializationConfig src, Map> mixins) { super(src, mixins); _deserFeatures = src._deserFeatures; _problemHandlers = src._problemHandlers; _nodeFactory = src._nodeFactory; } // for unit tests only: protected BaseSettings getBaseSettings() { return _base; } /* /********************************************************** /* Life-cycle, factory methods from MapperConfig /********************************************************** */ @Override public DeserializationConfig with(MapperFeature... features) { int newMapperFlags = _mapperFeatures; for (MapperFeature f : features) { newMapperFlags |= f.getMask(); } return (newMapperFlags == _mapperFeatures) ? this : new DeserializationConfig(this, newMapperFlags, _deserFeatures); } @Override public DeserializationConfig without(MapperFeature... features) { int newMapperFlags = _mapperFeatures; for (MapperFeature f : features) { newMapperFlags &= ~f.getMask(); } return (newMapperFlags == _mapperFeatures) ? this : new DeserializationConfig(this, newMapperFlags, _deserFeatures); } @Override public DeserializationConfig with(ClassIntrospector ci) { return _withBase(_base.withClassIntrospector(ci)); } @Override public DeserializationConfig with(AnnotationIntrospector ai) { return _withBase(_base.withAnnotationIntrospector(ai)); } @Override public DeserializationConfig with(VisibilityChecker vc) { return _withBase(_base.withVisibilityChecker(vc)); } @Override public DeserializationConfig withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { return _withBase( _base.withVisibility(forMethod, visibility)); } @Override public DeserializationConfig with(TypeResolverBuilder trb) { return _withBase(_base.withTypeResolverBuilder(trb)); } @Override public DeserializationConfig with(SubtypeResolver str) { return (_subtypeResolver == str) ? this : new DeserializationConfig(this, str); } @Override public DeserializationConfig with(PropertyNamingStrategy pns) { return _withBase(_base.withPropertyNamingStrategy(pns)); } @Override public DeserializationConfig withRootName(String rootName) { if (rootName == null) { if (_rootName == null) { return this; } } else if (rootName.equals(_rootName)) { return this; } return new DeserializationConfig(this, rootName); } @Override public DeserializationConfig with(TypeFactory tf) { return _withBase( _base.withTypeFactory(tf)); } @Override public DeserializationConfig with(DateFormat df) { return _withBase(_base.withDateFormat(df)); } @Override public DeserializationConfig with(HandlerInstantiator hi) { return _withBase(_base.withHandlerInstantiator(hi)); } @Override public DeserializationConfig withInsertedAnnotationIntrospector(AnnotationIntrospector ai) { return _withBase(_base.withInsertedAnnotationIntrospector(ai)); } @Override public DeserializationConfig withAppendedAnnotationIntrospector(AnnotationIntrospector ai) { return _withBase(_base.withAppendedAnnotationIntrospector(ai)); } @Override public DeserializationConfig withView(Class view) { return (_view == view) ? this : new DeserializationConfig(this, view); } @Override public DeserializationConfig with(Locale l) { return _withBase(_base.with(l)); } @Override public DeserializationConfig with(TimeZone tz) { return _withBase(_base.with(tz)); } @Override public DeserializationConfig with(Base64Variant base64) { return _withBase(_base.with(base64)); } private final DeserializationConfig _withBase(BaseSettings newBase) { return (_base == newBase) ? this : new DeserializationConfig(this, newBase); } /* /********************************************************** /* Life-cycle, deserialization-specific factory methods /********************************************************** */ /** * Fluent factory method that will construct a new instance with * specified {@link JsonNodeFactory} */ public DeserializationConfig with(JsonNodeFactory f) { if (_nodeFactory == f) { return this; } return new DeserializationConfig(this, f); } /** * Method that can be used to add a handler that can (try to) * resolve non-fatal deserialization problems. */ public DeserializationConfig withHandler(DeserializationProblemHandler h) { // Sanity check: let's prevent adding same handler multiple times if (LinkedNode.contains(_problemHandlers, h)) { return this; } return new DeserializationConfig(this, new LinkedNode(h, _problemHandlers)); } /** * Method for removing all configured problem handlers; usually done to replace * existing handler(s) with different one(s) */ public DeserializationConfig withNoProblemHandlers() { if (_problemHandlers == null) { return this; } return new DeserializationConfig(this, (LinkedNode) null); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features enabled. */ public DeserializationConfig with(DeserializationFeature feature) { int newDeserFeatures = (_deserFeatures | feature.getMask()); return (newDeserFeatures == _deserFeatures) ? this : new DeserializationConfig(this, _mapperFeatures, newDeserFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features enabled. */ public DeserializationConfig with(DeserializationFeature first, DeserializationFeature... features) { int newDeserFeatures = _deserFeatures | first.getMask(); for (DeserializationFeature f : features) { newDeserFeatures |= f.getMask(); } return (newDeserFeatures == _deserFeatures) ? this : new DeserializationConfig(this, _mapperFeatures, newDeserFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features enabled. */ public DeserializationConfig withFeatures(DeserializationFeature... features) { int newDeserFeatures = _deserFeatures; for (DeserializationFeature f : features) { newDeserFeatures |= f.getMask(); } return (newDeserFeatures == _deserFeatures) ? this : new DeserializationConfig(this, _mapperFeatures, newDeserFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified feature disabled. */ public DeserializationConfig without(DeserializationFeature feature) { int newDeserFeatures = _deserFeatures & ~feature.getMask(); return (newDeserFeatures == _deserFeatures) ? this : new DeserializationConfig(this, _mapperFeatures, newDeserFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features disabled. */ public DeserializationConfig without(DeserializationFeature first, DeserializationFeature... features) { int newDeserFeatures = _deserFeatures & ~first.getMask(); for (DeserializationFeature f : features) { newDeserFeatures &= ~f.getMask(); } return (newDeserFeatures == _deserFeatures) ? this : new DeserializationConfig(this, _mapperFeatures, newDeserFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features disabled. */ public DeserializationConfig withoutFeatures(DeserializationFeature... features) { int newDeserFeatures = _deserFeatures; for (DeserializationFeature f : features) { newDeserFeatures &= ~f.getMask(); } return (newDeserFeatures == _deserFeatures) ? this : new DeserializationConfig(this, _mapperFeatures, newDeserFeatures); } /* /********************************************************** /* MapperConfig implementation /********************************************************** */ /** * Method for getting {@link AnnotationIntrospector} configured * to introspect annotation values used for configuration. */ @Override public AnnotationIntrospector getAnnotationIntrospector() { /* 29-Jul-2009, tatu: it's now possible to disable use of * annotations; can be done using "no-op" introspector */ if (isEnabled(MapperFeature.USE_ANNOTATIONS)) { return super.getAnnotationIntrospector(); } return NopAnnotationIntrospector.instance; } @Override public boolean useRootWrapping() { if (_rootName != null) { // empty String disables wrapping; non-empty enables return (_rootName.length() > 0); } return isEnabled(DeserializationFeature.UNWRAP_ROOT_VALUE); } /** * Accessor for getting bean description that only contains class * annotations: useful if no getter/setter/creator information is needed. */ @Override public BeanDescription introspectClassAnnotations(JavaType type) { return getClassIntrospector().forClassAnnotations(this, type, this); } /** * Accessor for getting bean description that only contains immediate class * annotations: ones from the class, and its direct mix-in, if any, but * not from super types. */ @Override public BeanDescription introspectDirectClassAnnotations(JavaType type) { return getClassIntrospector().forDirectClassAnnotations(this, type, this); } @Override public VisibilityChecker getDefaultVisibilityChecker() { VisibilityChecker vchecker = super.getDefaultVisibilityChecker(); if (!isEnabled(MapperFeature.AUTO_DETECT_SETTERS)) { vchecker = vchecker.withSetterVisibility(Visibility.NONE); } if (!isEnabled(MapperFeature.AUTO_DETECT_CREATORS)) { vchecker = vchecker.withCreatorVisibility(Visibility.NONE); } if (!isEnabled(MapperFeature.AUTO_DETECT_FIELDS)) { vchecker = vchecker.withFieldVisibility(Visibility.NONE); } return vchecker; } public final boolean isEnabled(DeserializationFeature f) { return (_deserFeatures & f.getMask()) != 0; } /* /********************************************************** /* Other configuration /********************************************************** */ public final int getDeserializationFeatures() { return _deserFeatures; } /** * Method for getting head of the problem handler chain. May be null, * if no handlers have been added. */ public LinkedNode getProblemHandlers() { return _problemHandlers; } public final JsonNodeFactory getNodeFactory() { return _nodeFactory; } /* /********************************************************** /* Introspection methods /********************************************************** */ /** * Method that will introspect full bean properties for the purpose * of building a bean deserializer * * @param type Type of class to be introspected */ @SuppressWarnings("unchecked") public T introspect(JavaType type) { return (T) getClassIntrospector().forDeserialization(this, type, this); } /** * Method that will introspect subset of bean properties needed to * construct bean instance. */ @SuppressWarnings("unchecked") public T introspectForCreation(JavaType type) { return (T) getClassIntrospector().forCreation(this, type, this); } /** * @since 2.0 */ @SuppressWarnings("unchecked") public T introspectForBuilder(JavaType type) { return (T) getClassIntrospector().forDeserializationWithBuilder(this, type, this); } } DeserializationContext.java000066400000000000000000000615101215056657300360140ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.util.*; import com.fasterxml.jackson.annotation.ObjectIdGenerator; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.deser.*; import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId; import com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer; import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.*; /** * Context for the process of deserialization a single root-level value. * Used to allow passing in configuration settings and reusable temporary * objects (scrap arrays, containers). *

* Instance life-cycle is such that an partially configured "blueprint" object * is registered with {@link ObjectMapper} (and {@link ObjectReader}, * and when an actual instance is needed for deserialization, * a fully configured instance will * be created using a method in excented API of sub-class * ({@link com.fasterxml.jackson.databind.deser.DefaultDeserializationContext#createInstance}). * Each instance is guaranteed to only be used from single-threaded context; * instances may be reused iff no configuration has changed. *

* Defined as abstract class so that implementations must define methods * for reconfiguring blueprints and creating instances. */ public abstract class DeserializationContext extends DatabindContext implements java.io.Serializable { private static final long serialVersionUID = -7727373309391091315L; /** * Let's limit length of error messages, for cases where underlying data * may be very large -- no point in spamming logs with megs of meaningless * data. */ private final static int MAX_ERROR_STR_LEN = 500; /* /********************************************************** /* Configuration, immutable /********************************************************** */ /** * Object that handle details of {@link JsonDeserializer} caching. */ protected final DeserializerCache _cache; /* /********************************************************** /* Configuration, changeable via fluent factories /********************************************************** */ /** * Read-only factory instance; exposed to let * owners (ObjectMapper, ObjectReader) * access it. */ protected final DeserializerFactory _factory; /* /********************************************************** /* Configuration that gets set for instances (not blueprints) /* (partly denormalized for performance) /********************************************************** */ /** * Generic deserialization processing configuration */ protected final DeserializationConfig _config; /** * Bitmap of {@link DeserializationFeature}s that are enabled */ protected final int _featureFlags; /** * Currently active view, if any. */ protected final Class _view; /** * Currently active parser used for deserialization. * May be different from the outermost parser * when content is buffered. */ protected transient JsonParser _parser; /** * Object used for resolving references to injectable * values. */ protected final InjectableValues _injectableValues; /* /********************************************************** /* Per-operation reusable helper objects (not for blueprints) /********************************************************** */ protected transient ArrayBuilders _arrayBuilders; protected transient ObjectBuffer _objectBuffer; protected transient DateFormat _dateFormat; /* /********************************************************** /* Life-cycle /********************************************************** */ protected DeserializationContext(DeserializerFactory df) { this(df, null); } protected DeserializationContext(DeserializerFactory df, DeserializerCache cache) { if (df == null) { throw new IllegalArgumentException("Can not pass null DeserializerFactory"); } _factory = df; _cache = (cache == null) ? new DeserializerCache() : cache; _featureFlags = 0; _config = null; _injectableValues = null; _view = null; } protected DeserializationContext(DeserializationContext src, DeserializerFactory factory) { _cache = src._cache; _factory = factory; _config = src._config; _featureFlags = src._featureFlags; _view = src._view; _parser = src._parser; _injectableValues = src._injectableValues; } protected DeserializationContext(DeserializationContext src, DeserializationConfig config, JsonParser jp, InjectableValues injectableValues) { _cache = src._cache; _factory = src._factory; _config = config; _featureFlags = config.getDeserializationFeatures(); _view = config.getActiveView(); _parser = jp; _injectableValues = injectableValues; } /* /********************************************************** /* DatabindContext implementation /********************************************************** */ @Override public DeserializationConfig getConfig() { return _config; } @Override public final Class getActiveView() { return _view; } @Override public final AnnotationIntrospector getAnnotationIntrospector() { return _config.getAnnotationIntrospector(); } @Override public final TypeFactory getTypeFactory() { return _config.getTypeFactory(); } /* /********************************************************** /* Public API, accessors /********************************************************** */ /** * Method for getting current {@link DeserializerFactory}. */ public DeserializerFactory getFactory() { return _factory; } /** * Convenience method for checking whether specified on/off * feature is enabled */ public final boolean isEnabled(DeserializationFeature feat) { /* 03-Dec-2010, tatu: minor shortcut; since this is called quite often, * let's use a local copy of feature settings: */ return (_featureFlags & feat.getMask()) != 0; } /** * Method for accessing the currently active parser. * May be different from the outermost parser * when content is buffered. *

* Use of this method is discouraged: if code has direct access * to the active parser, that should be used instead. */ public final JsonParser getParser() { return _parser; } public final Object findInjectableValue(Object valueId, BeanProperty forProperty, Object beanInstance) { if (_injectableValues == null) { throw new IllegalStateException("No 'injectableValues' configured, can not inject value with id ["+valueId+"]"); } return _injectableValues.findInjectableValue(valueId, this, forProperty, beanInstance); } /** * Convenience method for accessing the default Base64 encoding * used for decoding base64 encoded binary content. * Same as calling: *

     *  getConfig().getBase64Variant();
     *
*/ public final Base64Variant getBase64Variant() { return _config.getBase64Variant(); } /** * Convenience method, functionally equivalent to: *
     *  getConfig().getNodeFactory();
     * 
*/ public final JsonNodeFactory getNodeFactory() { return _config.getNodeFactory(); } /** * Method for accessing default Locale to use: convenience method for *
     *   getConfig().getLocale();
     *
*/ public Locale getLocale() { return _config.getLocale(); } /** * Method for accessing default TimeZone to use: convenience method for *
     *   getConfig().getTimeZone();
     *
*/ public TimeZone getTimeZone() { return _config.getTimeZone(); } /* /********************************************************** /* Public API, pass-through to DeserializerCache /********************************************************** */ /** * Method for checking whether we could find a deserializer * for given type. */ public boolean hasValueDeserializerFor(JavaType type) { return _cache.hasValueDeserializerFor(this, _factory, type); } /** * Method for finding a value deserializer, and creating a contextual * version if necessary, for value reached via specified property. */ @SuppressWarnings("unchecked") public final JsonDeserializer findContextualValueDeserializer(JavaType type, BeanProperty property) throws JsonMappingException { JsonDeserializer deser = _cache.findValueDeserializer(this, _factory, type); if (deser != null) { if (deser instanceof ContextualDeserializer) { deser = (JsonDeserializer)((ContextualDeserializer) deser).createContextual(this, property); } } return deser; } /** * Method for finding a deserializer for root-level value. */ @SuppressWarnings("unchecked") public final JsonDeserializer findRootValueDeserializer(JavaType type) throws JsonMappingException { JsonDeserializer deser = _cache.findValueDeserializer(this, _factory, type); if (deser == null) { // can this occur? return null; } if (deser instanceof ContextualDeserializer) { deser = (JsonDeserializer)((ContextualDeserializer) deser).createContextual(this, null); } TypeDeserializer typeDeser = _factory.findTypeDeserializer(_config, type); if (typeDeser != null) { // important: contextualize to indicate this is for root value typeDeser = typeDeser.forProperty(null); return new TypeWrappedDeserializer(typeDeser, deser); } return deser; } /** * Convenience method, functionally same as: *
     *  getDeserializerProvider().findKeyDeserializer(getConfig(), propertyType, property);
     *
*/ public final KeyDeserializer findKeyDeserializer(JavaType keyType, BeanProperty property) throws JsonMappingException { KeyDeserializer kd = _cache.findKeyDeserializer(this, _factory, keyType); // Second: contextualize? if (kd instanceof ContextualKeyDeserializer) { kd = ((ContextualKeyDeserializer) kd).createContextual(this, property); } return kd; } /* /********************************************************** /* Public API, ObjectId handling /********************************************************** */ /** * Method called to find and return entry corresponding to given * Object Id: will add an entry if necessary, and never returns null */ public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator generator); /* /********************************************************** /* Public API, type handling /********************************************************** */ /** * Convenience method, functionally equivalent to: *
     *  getConfig().constructType(cls);
     * 
*/ public final JavaType constructType(Class cls) { return _config.constructType(cls); } /** * Helper method to use for locating Class for given name. Should be used * instead of basic Class.forName(className); as it can * try using contextual class loader, or use platform-specific workarounds * (like on Android, GAE). */ public Class findClass(String className) throws ClassNotFoundException { // By default, delegate to ClassUtil: can be overridden with custom handling return ClassUtil.findClass(className); } /* /********************************************************** /* Extended API: handler instantiation /********************************************************** */ public abstract JsonDeserializer deserializerInstance(Annotated annotated, Object deserDef) throws JsonMappingException; public abstract KeyDeserializer keyDeserializerInstance(Annotated annotated, Object deserDef) throws JsonMappingException; /* /********************************************************** /* Public API, helper object recycling /********************************************************** */ /** * Method that can be used to get access to a reusable ObjectBuffer, * useful for efficiently constructing Object arrays and Lists. * Note that leased buffers should be returned once deserializer * is done, to allow for reuse during same round of deserialization. */ public final ObjectBuffer leaseObjectBuffer() { ObjectBuffer buf = _objectBuffer; if (buf == null) { buf = new ObjectBuffer(); } else { _objectBuffer = null; } return buf; } /** * Method to call to return object buffer previously leased with * {@link #leaseObjectBuffer}. * * @param buf Returned object buffer */ public final void returnObjectBuffer(ObjectBuffer buf) { /* Already have a reusable buffer? Let's retain bigger one * (or if equal, favor newer one, shorter life-cycle) */ if (_objectBuffer == null || buf.initialCapacity() >= _objectBuffer.initialCapacity()) { _objectBuffer = buf; } } /** * Method for accessing object useful for building arrays of * primitive types (such as int[]). */ public final ArrayBuilders getArrayBuilders() { if (_arrayBuilders == null) { _arrayBuilders = new ArrayBuilders(); } return _arrayBuilders; } /* /********************************************************** /* Parsing methods that may use reusable/-cyclable objects /********************************************************** */ /** * Convenience method for parsing a Date from given String, using * currently configured date format (accessed using * {@link DeserializationConfig#getDateFormat()}). *

* Implementation will handle thread-safety issues related to * date formats such that first time this method is called, * date format is cloned, and cloned instance will be retained * for use during this deserialization round. */ public Date parseDate(String dateStr) throws IllegalArgumentException { try { return getDateFormat().parse(dateStr); } catch (ParseException e) { throw new IllegalArgumentException("Failed to parse Date value '"+dateStr+"': "+e.getMessage()); } } /** * Convenience method for constructing Calendar instance set * to specified time, to be modified and used by caller. */ public Calendar constructCalendar(Date d) { /* 08-Jan-2008, tatu: not optimal, but should work for the * most part; let's revise as needed. */ Calendar c = Calendar.getInstance(getTimeZone()); c.setTime(d); return c; } /* /********************************************************** /* Methods for problem handling, reporting /********************************************************** */ /** * Method deserializers can call to inform configured {@link DeserializationProblemHandler}s * of an unrecognized property. * * @return True if there was a configured problem handler that was able to handle the * problem */ /** * Method deserializers can call to inform configured {@link DeserializationProblemHandler}s * of an unrecognized property. */ public boolean handleUnknownProperty(JsonParser jp, JsonDeserializer deser, Object instanceOrClass, String propName) throws IOException, JsonProcessingException { LinkedNode h = _config.getProblemHandlers(); if (h != null) { while (h != null) { // Can bail out if it's handled if (h.value().handleUnknownProperty(this, jp, deser, instanceOrClass, propName)) { return true; } h = h.next(); } } return false; } /** * Helper method for reporting a problem with unhandled unknown exception * * @param instanceOrClass Either value being populated (if one has been * instantiated), or Class that indicates type that would be (or * have been) instantiated * @param deser Deserializer that had the problem, if called by deserializer * (or on behalf of one) */ public void reportUnknownProperty(Object instanceOrClass, String fieldName, JsonDeserializer deser) throws JsonMappingException { if (!isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) { return; } // Do we know properties that are expected instead? Collection propIds = (deser == null) ? null : deser.getKnownPropertyNames(); throw UnrecognizedPropertyException.from(_parser, instanceOrClass, fieldName, propIds); } /* /********************************************************** /* Methods for constructing exceptions /********************************************************** */ /** * Helper method for constructing generic mapping exception for specified type */ public JsonMappingException mappingException(Class targetClass) { return mappingException(targetClass, _parser.getCurrentToken()); } public JsonMappingException mappingException(Class targetClass, JsonToken token) { String clsName = _calcName(targetClass); return JsonMappingException.from(_parser, "Can not deserialize instance of "+clsName+" out of "+token+" token"); } /** * Helper method for constructing generic mapping exception with specified * message and current location information */ public JsonMappingException mappingException(String message) { return JsonMappingException.from(getParser(), message); } /** * Helper method for constructing instantiation exception for specified type, * to indicate problem with physically constructing instance of * specified class (missing constructor, exception from constructor) */ public JsonMappingException instantiationException(Class instClass, Throwable t) { return JsonMappingException.from(_parser, "Can not construct instance of "+instClass.getName()+", problem: "+t.getMessage(), t); } public JsonMappingException instantiationException(Class instClass, String msg) { return JsonMappingException.from(_parser, "Can not construct instance of "+instClass.getName()+", problem: "+msg); } /** * Method that will construct an exception suitable for throwing when * some String values are acceptable, but the one encountered is not. * * * @deprecated Since 2.1 should use variant that takes value */ @Deprecated public JsonMappingException weirdStringException(Class instClass, String msg) { return weirdStringException(null, instClass, msg); } /** * Method that will construct an exception suitable for throwing when * some String values are acceptable, but the one encountered is not. * * @param value String value from input being deserialized * @param instClass Type that String should be deserialized into * @param msg Message that describes specific problem * * @since 2.1 */ public JsonMappingException weirdStringException(String value, Class instClass, String msg) { return InvalidFormatException.from(_parser, "Can not construct instance of "+instClass.getName()+" from String value '"+_valueDesc()+"': "+msg, value, instClass); } /** * Helper method for constructing exception to indicate that input JSON * Number was not suitable for deserializing into given type. */ @Deprecated public JsonMappingException weirdNumberException(Class instClass, String msg) { return weirdStringException(null, instClass, msg); } /** * Helper method for constructing exception to indicate that input JSON * Number was not suitable for deserializing into given target type. */ public JsonMappingException weirdNumberException(Number value, Class instClass, String msg) { return InvalidFormatException.from(_parser, "Can not construct instance of "+instClass.getName()+" from number value ("+_valueDesc()+"): "+msg, null, instClass); } /** * Helper method for constructing exception to indicate that given JSON * Object field name was not in format to be able to deserialize specified * key type. */ public JsonMappingException weirdKeyException(Class keyClass, String keyValue, String msg) { return InvalidFormatException.from(_parser, "Can not construct Map key of type "+keyClass.getName()+" from String \""+_desc(keyValue)+"\": "+msg, keyValue, keyClass); } /** * Helper method for indicating that the current token was expected to be another * token. */ public JsonMappingException wrongTokenException(JsonParser jp, JsonToken expToken, String msg) { return JsonMappingException.from(jp, "Unexpected token ("+jp.getCurrentToken()+"), expected "+expToken+": "+msg); } /** * Helper method for constructing exception to indicate that given * type id (parsed from JSON) could not be converted to a Java type. */ public JsonMappingException unknownTypeException(JavaType type, String id) { return JsonMappingException.from(_parser, "Could not resolve type id '"+id+"' into a subtype of "+type); } public JsonMappingException endOfInputException(Class instClass) { return JsonMappingException.from(_parser, "Unexpected end-of-input when trying to deserialize a " +instClass.getName()); } /* /********************************************************** /* Overridable internal methods /********************************************************** */ protected DateFormat getDateFormat() { if (_dateFormat != null) { return _dateFormat; } /* 24-Feb-2012, tatu: At this point, all timezone configuration * should have occured, with respect to default dateformat * and timezone configuration. But we still better clone * an instance as formatters may be stateful. */ DateFormat df = _config.getDateFormat(); _dateFormat = df = (DateFormat) df.clone(); return df; } protected String determineClassName(Object instance) { return ClassUtil.getClassDescription(instance); } /* /********************************************************** /* Other internal methods /********************************************************** */ protected String _calcName(Class cls) { if (cls.isArray()) { return _calcName(cls.getComponentType())+"[]"; } return cls.getName(); } protected String _valueDesc() { try { return _desc(_parser.getText()); } catch (Exception e) { return "[N/A]"; } } protected String _desc(String desc) { // !!! should we quote it? (in case there are control chars, linefeeds) if (desc.length() > MAX_ERROR_STR_LEN) { desc = desc.substring(0, MAX_ERROR_STR_LEN) + "]...[" + desc.substring(desc.length() - MAX_ERROR_STR_LEN); } return desc; } } DeserializationFeature.java000066400000000000000000000267221215056657300357710ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import com.fasterxml.jackson.databind.cfg.ConfigFeature; /** * Enumeration that defines simple on/off features that affect * the way Java objects are deserialized from JSON *

* Note that features can be set both through * {@link ObjectMapper} (as sort of defaults) and through * {@link ObjectReader}. * In first case these defaults must follow "config-then-use" patterns * (i.e. defined once, not changed afterwards); all per-call * changes must be done using {@link ObjectReader}. */ public enum DeserializationFeature implements ConfigFeature { /* /****************************************************** /* Type conversion features /****************************************************** */ /** * Feature that determines whether JSON floating point numbers * are to be deserialized into {@link java.math.BigDecimal}s * if only generic type description (either {@link Object} or * {@link Number}, or within untyped {@link java.util.Map} * or {@link java.util.Collection} context) is available. * If enabled such values will be deserialized as {@link java.math.BigDecimal}s; * if disabled, will be deserialized as {@link Double}s. *

* Feature is disabled by default, meaning that "untyped" floating * point numbers will by default be deserialized as {@link Double}s * (choice is for performance reason -- BigDecimals are slower than * Doubles). */ USE_BIG_DECIMAL_FOR_FLOATS(false), /** * Feature that determines whether JSON integral (non-floating-point) * numbers are to be deserialized into {@link java.math.BigInteger}s * if only generic type description (either {@link Object} or * {@link Number}, or within untyped {@link java.util.Map} * or {@link java.util.Collection} context) is available. * If enabled such values will be deserialized as * {@link java.math.BigInteger}s; * if disabled, will be deserialized as "smallest" available type, * which is either {@link Integer}, {@link Long} or * {@link java.math.BigInteger}, depending on number of digits. *

* Feature is disabled by default, meaning that "untyped" floating * point numbers will by default be deserialized using whatever * is the most compact integral type, to optimize efficiency. */ USE_BIG_INTEGER_FOR_INTS(false), // [JACKSON-652] /** * Feature that determines whether JSON Array is mapped to * Object[] or List<Object> when binding * "untyped" objects (ones with nominal type of java.lang.Object). * If true, binds as Object[]; if false, as List<Object>. *

* Feature is disabled by default, meaning that JSON arrays are bound as * {@link java.util.List}s. */ USE_JAVA_ARRAY_FOR_JSON_ARRAY(false), /** * Feature that determines standard deserialization mechanism used for * Enum values: if enabled, Enums are assumed to have been serialized using * return value of Enum.toString(); * if disabled, return value of Enum.name() is assumed to have been used. *

* Note: this feature should usually have same value * as {@link SerializationFeature#WRITE_ENUMS_USING_TO_STRING}. *

* Feature is disabled by default. */ READ_ENUMS_USING_TO_STRING(false), /* /****************************************************** * Error handling features /****************************************************** */ /** * Feature that determines whether encountering of unknown * properties (ones that do not map to a property, and there is * no "any setter" or handler that can handle it) * should result in a failure (by throwing a * {@link JsonMappingException}) or not. * This setting only takes effect after all other handling * methods for unknown properties have been tried, and * property remains unhandled. *

* Feature is enabled by default (meaning that a * {@link JsonMappingException} will be thrown if an unknown property * is encountered). */ FAIL_ON_UNKNOWN_PROPERTIES(true), /** * Feature that determines whether encountering of JSON null * is an error when deserializing into Java primitive types * (like 'int' or 'double'). If it is, a JsonProcessingException * is thrown to indicate this; if not, default value is used * (0 for 'int', 0.0 for double, same defaulting as what JVM uses). *

* Feature is disabled by default. */ FAIL_ON_NULL_FOR_PRIMITIVES(false), /** * Feature that determines whether JSON integer numbers are valid * values to be used for deserializing Java enum values. * If set to 'false' numbers are acceptable and are used to map to * ordinal() of matching enumeration value; if 'true', numbers are * not allowed and a {@link JsonMappingException} will be thrown. * Latter behavior makes sense if there is concern that accidental * mapping from integer values to enums might happen (and when enums * are always serialized as JSON Strings) *

* Feature is disabled by default. */ FAIL_ON_NUMBERS_FOR_ENUMS(false), /** * Feature that determines what happens when type of a polymorphic * value (indicated for example by {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) * can not be found (missing) or resolved (invalid class name, unmappable id); * if enabled, an exception ir thrown; if false, null value is used instead. *

* Feature is enabled by default so that exception is thrown for missing or invalid * type information. * * @since 2.2 */ FAIL_ON_INVALID_SUBTYPE(true), /** * Feature that determines whether Jackson code should catch * and wrap {@link Exception}s (but never {@link Error}s!) * to add additional information about * location (within input) of problem or not. If enabled, * most exceptions will be caught and re-thrown (exception * specifically being that {@link java.io.IOException}s may be passed * as is, since they are declared as throwable); this can be * convenient both in that all exceptions will be checked and * declared, and so there is more contextual information. * However, sometimes calling application may just want "raw" * unchecked exceptions passed as is. *

* Feature is enabled by default. */ WRAP_EXCEPTIONS(true), /* /****************************************************** /* Structural conversion features /****************************************************** */ /** * Feature that determines whether it is acceptable to coerce non-array * (in JSON) values to work with Java collection (arrays, java.util.Collection) * types. If enabled, collection deserializers will try to handle non-array * values as if they had "implicit" surrounding JSON array. * This feature is meant to be used for compatibility/interoperability reasons, * to work with packages (such as XML-to-JSON converters) that leave out JSON * array in cases where there is just a single element in array. *

* Feature is disabled by default. */ ACCEPT_SINGLE_VALUE_AS_ARRAY(false), /** * Feature to allow "unwrapping" root-level JSON value, to match setting of * {@link SerializationFeature#WRAP_ROOT_VALUE} used for serialization. * Will verify that the root JSON value is a JSON Object, and that it has * a single property with expected root name. If not, a * {@link JsonMappingException} is thrown; otherwise value of the wrapped property * will be deserialized as if it was the root value. *

* Feature is disabled by default. */ UNWRAP_ROOT_VALUE(false), /* /****************************************************** /* Value conversion features /****************************************************** */ /** * Feature that can be enabled to allow JSON empty String * value ("") to be bound to POJOs as null. * If disabled, standard POJOs can only be bound from JSON null or * JSON Object (standard meaning that no custom deserializers or * constructors are defined; both of which can add support for other * kinds of JSON values); if enable, empty JSON String can be taken * to be equivalent of JSON null. *

* Feature is enabled by default. */ ACCEPT_EMPTY_STRING_AS_NULL_OBJECT(false), /** * Feature that allows unknown Enum values to be parsed as null values. * If disabled, unknown Enum values will throw exceptions. *

* Note that in some cases this will basically ignore unknown Enum values; * this is the keys for keys of {@link java.util.EnumMap} and values * of {@link java.util.EnumSet} (because nulls are not accepted in these * cases). *

* Feature is disabled by default. * * @since 2.0 */ READ_UNKNOWN_ENUM_VALUES_AS_NULL(false), /** * Feature that controls whether numeric timestamp values are expected * to be written using nanosecond timestamps (enabled) or not (disabled), * if and only if datatype supports such resolution. * Only newer datatypes (such as Java8 Date/Time) support such resolution -- * older types (pre-Java8 java.util.Date etc) and Joda do not -- * and this setting has no effect on such types. *

* If disabled, standard millisecond timestamps are assumed. * This is the counterpart to {@link SerializationFeature#WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS}. *

* Feature is enabled by default, to support most accurate time values possible. * * @since 2.2 */ READ_DATE_TIMESTAMPS_AS_NANOSECONDS(true), /** * Feature that specifies whether context provided {@link java.util.TimeZone} * ({@link DeserializationContext#getTimeZone()} should be used to adjust Date/Time * values on deserialization, even if value itself contains timezone information. * If enabled, contextual TimeZone will essentially override any other * TimeZone information; if disabled, it will only be used if value itself does not * contain any TimeZone information. * * @since 2.2 */ ADJUST_DATES_TO_CONTEXT_TIME_ZONE(true), /* /****************************************************** /* Other /****************************************************** */ /** * Feature that determines whether {@link ObjectReader} should * try to eagerly fetch necessary {@link JsonDeserializer} when * possible. This improves performance in cases where similarly * configured {@link ObjectReader} instance is used multiple * times; and should not significantly affect single-use cases. *

* Note that there should not be any need to normally disable this * feature: only consider that if there are actual perceived problems. *

* Feature is enabled by default. * * @since 2.1 */ EAGER_DESERIALIZER_FETCH(true) ; private final boolean _defaultState; private DeserializationFeature(boolean defaultState) { _defaultState = defaultState; } @Override public boolean enabledByDefault() { return _defaultState; } @Override public int getMask() { return (1 << ordinal()); } }InjectableValues.java000066400000000000000000000057641215056657300345520ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.util.*; /** * Abstract class that defines API for objects that provide value to * "inject" during deserialization. An instance of this object */ public abstract class InjectableValues { /** * Method called to find value identified by id valueId to * inject as value of specified property during deserialization, passing * POJO instance in which value will be injected if it is available * (will be available when injected via field or setter; not available * when injected via constructor or factory method argument). * * @param valueId Object that identifies value to inject; may be a simple * name or more complex identifier object, whatever provider needs * @param ctxt Deserialization context * @param forProperty Bean property in which value is to be injected * @param beanInstance Bean instance that contains property to inject, * if available; null if bean has not yet been constructed. */ public abstract Object findInjectableValue(Object valueId, DeserializationContext ctxt, BeanProperty forProperty, Object beanInstance); /* /********************************************************** /* Standard implementation /********************************************************** */ /** * Simple standard implementation which uses a simple Map to * store values to inject, identified by simple String keys. */ public static class Std extends InjectableValues implements java.io.Serializable { private static final long serialVersionUID = 1L; protected final Map _values; public Std() { this(new HashMap()); } public Std(Map values) { _values = values; } public Std addValue(String key, Object value) { _values.put(key, value); return this; } public Std addValue(Class classKey, Object value) { _values.put(classKey.getName(), value); return this; } @Override public Object findInjectableValue(Object valueId, DeserializationContext ctxt, BeanProperty forProperty, Object beanInstance) { if (!(valueId instanceof String)) { String type = (valueId == null) ? "[null]" : valueId.getClass().getName(); throw new IllegalArgumentException("Unrecognized inject value id type ("+type+"), expecting String"); } String key = (String) valueId; Object ob = _values.get(key); if (ob == null && !_values.containsKey(key)) { throw new IllegalArgumentException("No injectable id with value '"+key+"' found (for property '" +forProperty.getName()+"')"); } return ob; } } } jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/JavaType.java000066400000000000000000000342761215056657300331340ustar00rootroot00000000000000package com.fasterxml.jackson.databind; import java.lang.reflect.Modifier; import com.fasterxml.jackson.core.type.ResolvedType; /** * Base class for type token classes used both to contain information * and as keys for deserializers. *

* Instances can (only) be constructed by * com.fasterxml.jackson.databind.TypeFactory. *

* Since 2.2 this implements {@link java.lang.reflect.Type} to allow * it to be pushed through interfaces that only expose that type. */ public abstract class JavaType extends ResolvedType implements java.io.Serializable, // 2.1 java.lang.reflect.Type // 2.2 { private static final long serialVersionUID = 6774285981275451126L; /** * This is the nominal type-erased Class that would be close to the * type represented (but not exactly type, due to type erasure: type * instance may have more information on this). * May be an interface or abstract class, so instantiation * may not be possible. */ protected final Class _class; protected final int _hashCode; /** * Optional handler (codec) that can be attached to indicate * what to use for handling (serializing, deserializing) values of * this specific type. *

* Note: untyped (i.e. caller has to cast) because it is used for * different kinds of handlers, with unrelated types. */ protected final Object _valueHandler; /** * Optional handler that can be attached to indicate how to handle * additional type metadata associated with this type. *

* Note: untyped (i.e. caller has to cast) because it is used for * different kinds of handlers, with unrelated types. */ protected final Object _typeHandler; /** * Whether entities defined with this type should be handled using * static typing (as opposed to dynamic runtime type) or not. * * @since 2.2 */ protected final boolean _asStatic; /* /********************************************************** /* Life-cycle /********************************************************** */ /** * @param raw "Raw" (type-erased) class for this type * @param additionalHash Additional hash code to use, in addition * to hash code of the class name */ protected JavaType(Class raw, int additionalHash, Object valueHandler, Object typeHandler, boolean asStatic) { _class = raw; _hashCode = raw.getName().hashCode() + additionalHash; _valueHandler = valueHandler; _typeHandler = typeHandler; _asStatic = asStatic; } /** * "Copy method" that will construct a new instance that is identical to * this instance, except that it will have specified type handler assigned. * * @return Newly created type instance */ public abstract JavaType withTypeHandler(Object h); /** * "Copy method" that will construct a new instance that is identical to * this instance, except that its content type will have specified * type handler assigned. * * @return Newly created type instance */ public abstract JavaType withContentTypeHandler(Object h); /** * "Copy method" that will construct a new instance that is identical to * this instance, except that it will have specified value handler assigned. * * @return Newly created type instance */ public abstract JavaType withValueHandler(Object h); /** * "Copy method" that will construct a new instance that is identical to * this instance, except that it will have specified content value handler assigned. * * @return Newly created type instance */ public abstract JavaType withContentValueHandler(Object h); /** * Method that can be called to get a type instance that indicates * that values of the type should be handled using "static typing" for purposes * of serialization (as opposed to "dynamic" aka runtime typing): * meaning that no runtime information is needed for determining serializers to use. * The main use case is to allow forcing of specific root value serialization type, * and specifically in resolving serializers for contained types (element types * for arrays, Collections and Maps). * * @since 2.2 */ public abstract JavaType withStaticTyping(); /* /********************************************************** /* Type coercion fluent factory methods /********************************************************** */ /** * Method that can be called to do a "narrowing" conversions; that is, * to return a type with a raw class that is assignable to the raw * class of this type. If this is not possible, an * {@link IllegalArgumentException} is thrown. * If class is same as the current raw class, instance itself is * returned. */ public JavaType narrowBy(Class subclass) { // First: if same raw class, just return this instance if (subclass == _class) { return this; } // Otherwise, ensure compatibility _assertSubclass(subclass, _class); JavaType result = _narrow(subclass); // TODO: these checks should NOT actually be needed; above should suffice: if (_valueHandler != result.getValueHandler()) { result = result.withValueHandler(_valueHandler); } if (_typeHandler != result.getTypeHandler()) { result = result.withTypeHandler(_typeHandler); } return result; } /** * More efficient version of {@link #narrowBy}, called by * internal framework in cases where compatibility checks * are to be skipped. */ public JavaType forcedNarrowBy(Class subclass) { if (subclass == _class) { // can still optimize for simple case return this; } JavaType result = _narrow(subclass); // TODO: these checks should NOT actually be needed; above should suffice: if (_valueHandler != result.getValueHandler()) { result = result.withValueHandler(_valueHandler); } if (_typeHandler != result.getTypeHandler()) { result = result.withTypeHandler(_typeHandler); } return result; } /** * Method that can be called to do a "widening" conversions; that is, * to return a type with a raw class that could be assigned from this * type. * If such conversion is not possible, an * {@link IllegalArgumentException} is thrown. * If class is same as the current raw class, instance itself is * returned. */ public JavaType widenBy(Class superclass) { // First: if same raw class, just return this instance if (superclass == _class) { return this; } // Otherwise, ensure compatibility _assertSubclass(_class, superclass); return _widen(superclass); } protected abstract JavaType _narrow(Class subclass); /** *

* Default implementation is just to call {@link #_narrow}, since * underlying type construction is usually identical */ protected JavaType _widen(Class superclass) { return _narrow(superclass); } public abstract JavaType narrowContentsBy(Class contentClass); public abstract JavaType widenContentsBy(Class contentClass); /* /********************************************************** /* Implementation of ResolvedType API /********************************************************** */ @Override public final Class getRawClass() { return _class; } /** * Method that can be used to check whether this type has * specified Class as its type erasure. Put another way, returns * true if instantiation of this Type is given (type-erased) Class. */ @Override public final boolean hasRawClass(Class clz) { return _class == clz; } @Override public boolean isAbstract() { return Modifier.isAbstract(_class.getModifiers()); } /** * Convenience method for checking whether underlying Java type * is a concrete class or not: abstract classes and interfaces * are not. */ @Override public boolean isConcrete() { int mod = _class.getModifiers(); if ((mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0) { return true; } /* 19-Feb-2010, tatus: Holy mackarel; primitive types * have 'abstract' flag set... */ if (_class.isPrimitive()) { return true; } return false; } @Override public boolean isThrowable() { return Throwable.class.isAssignableFrom(_class); } @Override public boolean isArrayType() { return false; } @Override public final boolean isEnumType() { return _class.isEnum(); } @Override public final boolean isInterface() { return _class.isInterface(); } @Override public final boolean isPrimitive() { return _class.isPrimitive(); } @Override public final boolean isFinal() { return Modifier.isFinal(_class.getModifiers()); } /** * @return True if type represented is a container type; this includes * array, Map and Collection types. */ @Override public abstract boolean isContainerType(); /** * @return True if type is either true {@link java.util.Collection} type, * or something similar (meaning it has at least one type parameter, * which describes type of contents) */ @Override public boolean isCollectionLikeType() { return false; } /** * @return True if type is either true {@link java.util.Map} type, * or something similar (meaning it has at least two type parameter; * first one describing key type, second value type) */ @Override public boolean isMapLikeType() { return false; } /** * Accessor for checking whether handlers for dealing with values of * this type should use static typing (as opposed to dynamic typing). * Note that while value of 'true' does mean that static typing is to * be used, value of 'false' may still be overridden by other settings. * * @since 2.2 */ public final boolean useStaticType() { return _asStatic; } /* /********************************************************** /* Public API, type parameter access; pass-through /********************************************************** */ @Override public boolean hasGenericTypes() { return containedTypeCount() > 0; } @Override public JavaType getKeyType() { return null; } @Override public JavaType getContentType() { return null; } @Override public int containedTypeCount() { return 0; } @Override public JavaType containedType(int index) { return null; } @Override public String containedTypeName(int index) { return null; } /* /********************************************************** /* Semi-public API, accessing handlers /********************************************************** */ /** * Method for accessing value handler associated with this type, if any */ @SuppressWarnings("unchecked") public T getValueHandler() { return (T) _valueHandler; } /** * Method for accessing type handler associated with this type, if any */ @SuppressWarnings("unchecked") public T getTypeHandler() { return (T) _typeHandler; } /* /********************************************************** /* Support for producing signatures /********************************************************** */ //public abstract String toCanonical(); /** * Method for accessing signature that contains generic * type information, in form compatible with JVM 1.5 * as per JLS. It is a superset of {@link #getErasedSignature}, * in that generic information can be automatically removed * if necessary (just remove outermost * angle brackets along with content inside) */ public String getGenericSignature() { StringBuilder sb = new StringBuilder(40); getGenericSignature(sb); return sb.toString(); } /** * * @param sb StringBuilder to append signature to * * @return StringBuilder that was passed in; returned to allow * call chaining */ public abstract StringBuilder getGenericSignature(StringBuilder sb); /** * Method for accessing signature without generic * type information, in form compatible with all versions * of JVM, and specifically used for type descriptions * when generating byte code. */ public String getErasedSignature() { StringBuilder sb = new StringBuilder(40); getErasedSignature(sb); return sb.toString(); } /** * Method for accessing signature without generic * type information, in form compatible with all versions * of JVM, and specifically used for type descriptions * when generating byte code. * * @param sb StringBuilder to append signature to * * @return StringBuilder that was passed in; returned to allow * call chaining */ public abstract StringBuilder getErasedSignature(StringBuilder sb); /* /********************************************************** /* Helper methods /********************************************************** */ protected void _assertSubclass(Class subclass, Class superClass) { if (!_class.isAssignableFrom(subclass)) { throw new IllegalArgumentException("Class "+subclass.getName()+" is not assignable to "+_class.getName()); } } /* /********************************************************** /* Standard methods; let's make them abstract to force override /********************************************************** */ @Override public abstract String toString(); @Override public abstract boolean equals(Object o); @Override public final int hashCode() { return _hashCode; } } JsonDeserializer.java000066400000000000000000000263421215056657300346010ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.IOException; import java.util.Collection; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.util.NameTransformer; /** * Abstract class that defines API used by {@link ObjectMapper} (and * other chained {@link JsonDeserializer}s too) to deserialize Objects of * arbitrary types from JSON, using provided {@link JsonParser}. *

* Custom deserializers should usually not directly extend this class, * but instead extend {@link com.fasterxml.jackson.databind.deser.std.StdDeserializer} * (or its subtypes like {@link com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer}). *

* If deserializer is an aggregate one -- meaning it delegates handling of some * of its contents by using other deserializer(s) -- it typically also needs * to implement {@link com.fasterxml.jackson.databind.deser.ResolvableDeserializer}, * which can locate dependant deserializers. This is important to allow dynamic * overrides of deserializers; separate call interface is needed to separate * resolution of dependant deserializers (which may have cyclic link back * to deserializer itself, directly or indirectly). *

* In addition, to support per-property annotations (to configure aspects * of deserialization on per-property basis), deserializers may want * to implement * {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer}, * which allows specialization of deserializers: call to * {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer#createContextual} * is passed information on property, and can create a newly configured * deserializer for handling that particular property. *

* If both * {@link com.fasterxml.jackson.databind.deser.ResolvableDeserializer} and * {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer} * are implemented, resolution of deserializers occurs before * contextualization. */ public abstract class JsonDeserializer { /* /********************************************************** /* Main deserialization methods /********************************************************** */ /** * Method that can be called to ask implementation to deserialize * JSON content into the value type this serializer handles. * Returned instance is to be constructed by method itself. *

* Pre-condition for this method is that the parser points to the * first event that is part of value to deserializer (and which * is never JSON 'null' literal, more on this below): for simple * types it may be the only value; and for structured types the * Object start marker. * Post-condition is that the parser will point to the last * event that is part of deserialized value (or in case deserialization * fails, event that was not recognized or usable, which may be * the same event as the one it pointed to upon call). *

* Note that this method is never called for JSON null literal, * and thus deserializers need (and should) not check for it. * * @param jp Parsed used for reading JSON content * @param ctxt Context that can be used to access information about * this deserialization activity. * * @return Deserializer value */ public abstract T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException; /** * Alternate deserialization method (compared to the most commonly * used, {@link #deserialize(JsonParser, DeserializationContext)}), * which takes in initialized value instance, to be * configured and/or populated by deserializer. * Method is not necessarily used for all supported types; most commonly * it is used * for Collections and Maps. *

* Default implementation just throws * {@link UnsupportedOperationException}, to indicate that types * that do not explicitly add support do not necessarily support * update-existing-value operation (esp. immutable types) */ public T deserialize(JsonParser jp, DeserializationContext ctxt, T intoValue) throws IOException, JsonProcessingException { throw new UnsupportedOperationException("Can not update object of type " +intoValue.getClass().getName()+" (by deserializer of type "+getClass().getName()+")"); } /** * Deserialization called when type being deserialized is defined to * contain additional type identifier, to allow for correctly * instantiating correct subtype. This can be due to annotation on * type (or its supertype), or due to global settings without * annotations. *

* Default implementation may work for some types, but ideally subclasses * should not rely on current default implementation. * Implementation is mostly provided to avoid compilation errors with older * code. * * @param typeDeserializer Deserializer to use for handling type information */ public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException, JsonProcessingException { // We could try calling return typeDeserializer.deserializeTypedFromAny(jp, ctxt); } /* /********************************************************** /* Fluent factory methods for constructing decorated versions /********************************************************** */ /** * Method that will return deserializer instance that is able * to handle "unwrapped" value instances * If no unwrapped instance can be constructed, will simply * return this object as-is. *

* Default implementation just returns 'this' * indicating that no unwrapped variant exists */ public JsonDeserializer unwrappingDeserializer(NameTransformer unwrapper) { return this; } /** * Method that can be called to try to replace deserializer this deserializer * delegates calls to. If not supported (either this deserializer does not * delegate anything; or it does not want any changes), should either * throw {@link UnsupportedOperationException} (if operation does not * make sense or is not allowed); or return this deserializer as is. * * @since 2.1 */ public JsonDeserializer replaceDelegatee(JsonDeserializer delegatee) { throw new UnsupportedOperationException(); } /* /********************************************************** /* Other accessors /********************************************************** */ /** * Method that can be called to determine value to be used for * representing null values (values deserialized when JSON token * is {@link JsonToken#VALUE_NULL}). Usually this is simply * Java null, but for some types (especially primitives) it may be * necessary to use non-null values. *

* Note that deserializers are allowed to call this just once and * then reuse returned value; that is, method is not guaranteed to * be called once for each conversion. *

* Default implementation simply returns null. */ public T getNullValue() { return null; } /** * Method called to determine value to be used for "empty" values * (most commonly when deserializing from empty JSON Strings). * Usually this is same as {@link #getNullValue} (which in turn * is usually simply Java null), but it can be overridden * for types. Or, if type should never be converted from empty * String, method can also throw an exception. *

* Default implementation simple calls {@link #getNullValue} and * returns value. */ public T getEmptyValue() { return getNullValue(); } /** * Method that will * either return null to indicate that type being deserializers * has no concept of properties; or a collection of identifiers * for which toString will give external property * name. * This is only to be used for error reporting and diagnostics * purposes (most commonly, to accompany "unknown property" * exception). * * @since 2.0 */ public Collection getKnownPropertyNames() { return null; } /** * Method called to see if deserializer instance is cachable and * usable for other properties of same type (type for which instance * was created). *

* Note that cached instances are still resolved on per-property basis, * if instance implements {@link com.fasterxml.jackson.databind.deser.ResolvableDeserializer}: * cached instance is just as the base. This means that in most cases it is safe to * cache instances; however, it only makes sense to cache instances * if instantiation is expensive, or if instances are heavy-weight. *

* Default implementation returns false, to indicate that no caching * is done. */ public boolean isCachable() { return false; } /** * Accessor that can be used to check whether this deserializer * is expecting to possibly get an Object Identifier value instead of full value * serialization, and if so, should be able to resolve it to actual * Object instance to return as deserialized value. *

* Default implementation returns null, as support can not be implemented * generically. Some standard deserializers (most notably * {@link com.fasterxml.jackson.databind.deser.BeanDeserializer}) * do implement this feature, and may return reader instance, depending on exact * configuration of instance (which is based on type, and referring property). * * @return ObjectIdReader used for resolving possible Object Identifier * value, instead of full value serialization, if deserializer can do that; * null if no Object Id is expected. * * @since 2.0 */ public ObjectIdReader getObjectIdReader() { return null; } /** * Accessor that can be used to determine if this deserializer uses * another deserializer for actual deserialization, by delegating * calls. If so, will return immediate delegate (which itself may * delegate to further deserializers); otherwise will return null. * * @return Deserializer this deserializer delegates calls to, if null; * null otherwise. * * @since 2.1 */ public JsonDeserializer getDelegatee() { return null; } /* /********************************************************** /* Helper classes /********************************************************** */ /** * This marker class is only to be used with annotations, to * indicate that no deserializer is configured. *

* Specifically, this class is to be used as the marker for * annotation {@link com.fasterxml.jackson.databind.annotation.JsonDeserialize} */ public abstract static class None extends JsonDeserializer { private None() { } // not to be instantiated } } JsonMappingException.java000066400000000000000000000264211215056657300354270ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.IOException; import java.io.Serializable; import java.util.*; import com.fasterxml.jackson.core.*; /** * Checked exception used to signal fatal problems with mapping of * content. *

* One additional feature is the ability to denote relevant path * of references (during serialization/deserialization) to help in * troubleshooting. */ public class JsonMappingException extends JsonProcessingException { private static final long serialVersionUID = 1L; /** * Let's limit length of reference chain, to limit damage in cases * of infinite recursion. */ final static int MAX_REFS_TO_LIST = 1000; /* /********************************************************** /* Helper classes /********************************************************** */ /** * Simple bean class used to contain references. References * can be added to indicate execution/reference path that * lead to the problem that caused this exception to be * thrown. */ public static class Reference implements Serializable { private static final long serialVersionUID = 1L; /** * Object through which reference was resolved. Can be either * actual instance (usually the case for serialization), or * Class (usually the case for deserialization). */ protected Object _from; /** * Name of field (for beans) or key (for Maps) that is part * of the reference. May be null for Collection types (which * generally have {@link #_index} defined), or when resolving * Map classes without (yet) having an instance to operate on. */ protected String _fieldName; /** * Index within a {@link Collection} instance that contained * the reference; used if index is relevant and available. * If either not applicable, or not available, -1 is used to * denote "not known". */ protected int _index = -1; /** * Default constructor for deserialization/sub-classing purposes */ protected Reference() { } public Reference(Object from) { _from = from; } public Reference(Object from, String fieldName) { _from = from; if (fieldName == null) { throw new NullPointerException("Can not pass null fieldName"); } _fieldName = fieldName; } public Reference(Object from, int index) { _from = from; _index = index; } public void setFrom(Object o) { _from = o; } public void setFieldName(String n) { _fieldName = n; } public void setIndex(int ix) { _index = ix; } public Object getFrom() { return _from; } public String getFieldName() { return _fieldName; } public int getIndex() { return _index; } @Override public String toString() { StringBuilder sb = new StringBuilder(); Class cls = (_from instanceof Class) ? ((Class)_from) : _from.getClass(); /* Hmmh. Although Class.getName() is mostly ok, it does look * butt-ugly for arrays. So let's use getSimpleName() instead; * but have to prepend package name too. */ Package pkg = cls.getPackage(); if (pkg != null) { sb.append(pkg.getName()); sb.append('.'); } sb.append(cls.getSimpleName()); sb.append('['); if (_fieldName != null) { sb.append('"'); sb.append(_fieldName); sb.append('"'); } else if (_index >= 0) { sb.append(_index); } else { sb.append('?'); } sb.append(']'); return sb.toString(); } } /* /********************************************************** /* State/configuration /********************************************************** */ /** * Path through which problem that triggering throwing of * this exception was reached. */ protected LinkedList _path; /* /********************************************************** /* Life-cycle /********************************************************** */ public JsonMappingException(String msg) { super(msg); } public JsonMappingException(String msg, Throwable rootCause) { super(msg, rootCause); } public JsonMappingException(String msg, JsonLocation loc) { super(msg, loc); } public JsonMappingException(String msg, JsonLocation loc, Throwable rootCause) { super(msg, loc, rootCause); } public static JsonMappingException from(JsonParser jp, String msg) { return new JsonMappingException(msg, ((jp == null) ? null : jp.getTokenLocation())); } public static JsonMappingException from(JsonParser jp, String msg, Throwable problem) { return new JsonMappingException(msg, ((jp == null) ? null : jp.getTokenLocation()), problem); } /** * Factory method used when "upgrading" an {@link IOException} into * {@link JsonMappingException}: usually only needed to comply with * a signature. * * @since 2.1 */ public static JsonMappingException fromUnexpectedIOE(IOException src) { return new JsonMappingException("Unexpected IOException (of type " +src.getClass().getName()+"): "+src.getMessage(), (JsonLocation)null, src); } /** * Method that can be called to either create a new JsonMappingException * (if underlying exception is not a JsonMappingException), or augment * given exception with given path/reference information. * * This version of method is called when the reference is through a * non-indexed object, such as a Map or POJO/bean. */ public static JsonMappingException wrapWithPath(Throwable src, Object refFrom, String refFieldName) { return wrapWithPath(src, new Reference(refFrom, refFieldName)); } /** * Method that can be called to either create a new JsonMappingException * (if underlying exception is not a JsonMappingException), or augment * given exception with given path/reference information. * * This version of method is called when the reference is through an * index, which happens with arrays and Collections. */ public static JsonMappingException wrapWithPath(Throwable src, Object refFrom, int index) { return wrapWithPath(src, new Reference(refFrom, index)); } /** * Method that can be called to either create a new JsonMappingException * (if underlying exception is not a JsonMappingException), or augment * given exception with given path/reference information. */ public static JsonMappingException wrapWithPath(Throwable src, Reference ref) { JsonMappingException jme; if (src instanceof JsonMappingException) { jme = (JsonMappingException) src; } else { String msg = src.getMessage(); /* Related to [JACKSON-62], let's use a more meaningful placeholder * if all we have is null */ if (msg == null || msg.length() == 0) { msg = "(was "+src.getClass().getName()+")"; } jme = new JsonMappingException(msg, null, src); } jme.prependPath(ref); return jme; } /* /********************************************************** /* Accessors/mutators /********************************************************** */ /** * Method for accessing full structural path within type hierarchy * down to problematic property. */ public List getPath() { if (_path == null) { return Collections.emptyList(); } return Collections.unmodifiableList(_path); } /** * Method for accesing description of path that lead to the * problem that triggered this exception */ public String getPathReference() { return getPathReference(new StringBuilder()).toString(); } public StringBuilder getPathReference(StringBuilder sb) { _appendPathDesc(sb); return sb; } /** * Method called to prepend a reference information in front of * current path */ public void prependPath(Object referrer, String fieldName) { Reference ref = new Reference(referrer, fieldName); prependPath(ref); } /** * Method called to prepend a reference information in front of * current path */ public void prependPath(Object referrer, int index) { Reference ref = new Reference(referrer, index); prependPath(ref); } public void prependPath(Reference r) { if (_path == null) { _path = new LinkedList(); } /* Also: let's not increase without bounds. Could choose either * head or tail; tail is easier (no need to ever remove), as * well as potentially more useful so let's use it: */ if (_path.size() < MAX_REFS_TO_LIST) { _path.addFirst(r); } } /* /********************************************************** /* Overridden methods /********************************************************** */ @Override public String getLocalizedMessage() { return _buildMessage(); } /** * Method is overridden so that we can properly inject description * of problem path, if such is defined. */ @Override public String getMessage() { return _buildMessage(); } protected String _buildMessage() { /* First: if we have no path info, let's just use parent's * definition as is */ String msg = super.getMessage(); if (_path == null) { return msg; } StringBuilder sb = (msg == null) ? new StringBuilder() : new StringBuilder(msg); /* 18-Feb-2009, tatu: initially there was a linefeed between * message and path reference; but unfortunately many systems * (loggers, junit) seem to assume linefeeds are only added to * separate stack trace. */ sb.append(" (through reference chain: "); sb = getPathReference(sb); sb.append(')'); return sb.toString(); } @Override public String toString() { return getClass().getName()+": "+getMessage(); } /* /********************************************************** /* Internal methods /********************************************************** */ protected void _appendPathDesc(StringBuilder sb) { if (_path == null) { return; } Iterator it = _path.iterator(); while (it.hasNext()) { sb.append(it.next().toString()); if (it.hasNext()) { sb.append("->"); } } } } jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/JsonNode.java000066400000000000000000000726171215056657300331310ustar00rootroot00000000000000package com.fasterxml.jackson.databind; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.*; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.node.JsonNodeType; import com.fasterxml.jackson.databind.util.EmptyIterator; /** * Base class for all JSON nodes, which form the basis of JSON * Tree Model that Jackson implements. * One way to think of these nodes is to consider them * similar to DOM nodes in XML DOM trees. *

* As a general design rule, most accessors ("getters") are included * in this base class, to allow for traversing structure without * type casts. Most mutators, however, need to be accessed through * specific sub-classes (such as ObjectNode * and ArrayNode). * This seems sensible because proper type * information is generally available when building or modifying * trees, but less often when reading a tree (newly built from * parsed JSON content). *

* Actual concrete sub-classes can be found from package * {@link com.fasterxml.jackson.databind.node}. */ public abstract class JsonNode implements TreeNode, Iterable { /* /********************************************************** /* Construction, related /********************************************************** */ protected JsonNode() { } /** * Method that can be called to get a node that is guaranteed * not to allow changing of this node through mutators on * this node or any of its children. * This means it can either make a copy of this node (and all * mutable children and grand children nodes), or node itself * if it is immutable. *

* Note: return type is guaranteed to have same type as the * node method is called on; which is why method is declared * with local generic type. * * @since 2.0 * * @return Node that is either a copy of this node (and all non-leaf * children); or, for immutable leaf nodes, node itself. */ public abstract T deepCopy(); /* /********************************************************** /* TreeNode implementation /********************************************************** */ // public abstract JsonToken asToken(); // public abstract JsonParser.NumberType numberType(); // public abstract JsonParser traverse(); @Override public int size() { return 0; } @Override public final boolean isValueNode() { switch (getNodeType()) { case ARRAY: case OBJECT: case MISSING: return false; default: return true; } } @Override public final boolean isContainerNode() { final JsonNodeType type = getNodeType(); return type == JsonNodeType.OBJECT || type == JsonNodeType.ARRAY; } @Override public final boolean isMissingNode() { return getNodeType() == JsonNodeType.MISSING; } @Override public final boolean isArray() { return getNodeType() == JsonNodeType.ARRAY; } @Override public final boolean isObject() { return getNodeType() == JsonNodeType.OBJECT; } /** * Method for accessing value of the specified element of * an array node. For other nodes, null is always returned. *

* For array nodes, index specifies * exact location within array and allows for efficient iteration * over child elements (underlying storage is guaranteed to * be efficiently indexable, i.e. has random-access to elements). * If index is less than 0, or equal-or-greater than * node.size(), null is returned; no exception is * thrown for any index. *

* NOTE: if the element value has been explicitly set as null * (which is different from removal!), * a {@link com.fasterxml.jackson.databind.node.NullNode} will be returned, * not null. * * @return Node that represent value of the specified element, * if this node is an array and has specified element. * Null otherwise. */ @Override public abstract JsonNode get(int index); /** * Method for accessing value of the specified field of * an object node. If this node is not an object (or it * does not have a value for specified field name), or * if there is no field with such name, null is returned. *

* NOTE: if the property value has been explicitly set as null * (which is different from removal!), * a {@link com.fasterxml.jackson.databind.node.NullNode} will be returned, * not null. * * @return Node that represent value of the specified field, * if this node is an object and has value for the specified * field. Null otherwise. */ @Override public JsonNode get(String fieldName) { return null; } /** * This method is similar to {@link #get(String)}, except * that instead of returning null if no such value exists (due * to this node not being an object, or object not having value * for the specified field), * a "missing node" (node that returns true for * {@link #isMissingNode}) will be returned. This allows for * convenient and safe chained access via path calls. */ @Override public abstract JsonNode path(String fieldName); /** * This method is similar to {@link #get(int)}, except * that instead of returning null if no such element exists (due * to index being out of range, or this node not being an array), * a "missing node" (node that returns true for * {@link #isMissingNode}) will be returned. This allows for * convenient and safe chained access via path calls. */ @Override public abstract JsonNode path(int index); @Override public Iterator fieldNames() { return EmptyIterator.instance(); } /* /********************************************************** /* Public API, type introspection /********************************************************** */ // // First high-level division between values, containers and "missing" /** * Return the type of this node * * @return the node type as a {@link JsonNodeType} enum value * * @since 2.2 */ public abstract JsonNodeType getNodeType(); /** * Method that can be used to check if the node is a wrapper * for a POJO ("Plain Old Java Object" aka "bean". * Returns true only for * instances of POJONode. * * @return True if this node wraps a POJO */ public final boolean isPojo() { return getNodeType() == JsonNodeType.POJO; } /** * @return True if this node represents a numeric JSON value */ public final boolean isNumber() { return getNodeType() == JsonNodeType.NUMBER; } /** * * @return True if this node represents an integral (integer) * numeric JSON value */ public boolean isIntegralNumber() { return false; } /** * @return True if this node represents a non-integral * numeric JSON value */ public boolean isFloatingPointNumber() { return false; } /** * Method that can be used to check whether contained value * is a number represented as Java short. * Note, however, that even if this method returns false, it * is possible that conversion would be possible from other numeric * types -- to check if this is possible, use * {@link #canConvertToInt()} instead. * * @return True if the value contained by this node is stored as Java short */ public boolean isShort() { return false; } /** * Method that can be used to check whether contained value * is a number represented as Java int. * Note, however, that even if this method returns false, it * is possible that conversion would be possible from other numeric * types -- to check if this is possible, use * {@link #canConvertToInt()} instead. * * @return True if the value contained by this node is stored as Java int */ public boolean isInt() { return false; } /** * Method that can be used to check whether contained value * is a number represented as Java long. * Note, however, that even if this method returns false, it * is possible that conversion would be possible from other numeric * types -- to check if this is possible, use * {@link #canConvertToInt()} instead. * * @return True if the value contained by this node is stored as Java long */ public boolean isLong() { return false; } /** * @since 2.2 */ public boolean isFloat() { return false; } public boolean isDouble() { return false; } public boolean isBigDecimal() { return false; } public boolean isBigInteger() { return false; } /** * Method that checks whether this node represents basic JSON String * value. */ public final boolean isTextual() { return getNodeType() == JsonNodeType.STRING; } /** * Method that can be used to check if this node was created from * JSON boolean value (literals "true" and "false"). */ public final boolean isBoolean() { return getNodeType() == JsonNodeType.BOOLEAN; } /** * Method that can be used to check if this node was created from * JSON literal null value. */ public final boolean isNull() { return getNodeType() == JsonNodeType.NULL; } /** * Method that can be used to check if this node represents * binary data (Base64 encoded). Although this will be externally * written as JSON String value, {@link #isTextual} will * return false if this method returns true. * * @return True if this node represents base64 encoded binary data */ public final boolean isBinary() { return getNodeType() == JsonNodeType.BINARY; } /** * Method that can be used to check whether this node is a numeric * node ({@link #isNumber} would return true) AND its value fits * within Java's 32-bit signed integer type, int. * Note that floating-point numbers are convertible if the integral * part fits without overflow (as per standard Java coercion rules) * * @since 2.0 */ public boolean canConvertToInt() { return false; } /** * Method that can be used to check whether this node is a numeric * node ({@link #isNumber} would return true) AND its value fits * within Java's 64-bit signed integer type, long. * Note that floating-point numbers are convertible if the integral * part fits without overflow (as per standard Java coercion rules) * * @since 2.0 */ public boolean canConvertToLong() { return false; } /* /********************************************************** /* Public API, straight value access /********************************************************** */ /** * Method to use for accessing String values. * Does NOT do any conversions for non-String value nodes; * for non-String values (ones for which {@link #isTextual} returns * false) null will be returned. * For String values, null is never returned (but empty Strings may be) * * @return Textual value this node contains, iff it is a textual * JSON node (comes from JSON String value entry) */ public String textValue() { return null; } /** * Method to use for accessing binary content of binary nodes (nodes * for which {@link #isBinary} returns true); or for Text Nodes * (ones for which {@link #textValue} returns non-null value), * to read decoded base64 data. * For other types of nodes, returns null. * * @return Binary data this node contains, iff it is a binary * node; null otherwise */ public byte[] binaryValue() throws IOException { return null; } /** * Method to use for accessing JSON boolean values (value * literals 'true' and 'false'). * For other types, always returns false. * * @return Textual value this node contains, iff it is a textual * json node (comes from JSON String value entry) */ public boolean booleanValue() { return false; } /** * Returns numeric value for this node, if and only if * this node is numeric ({@link #isNumber} returns true); otherwise * returns null * * @return Number value this node contains, if any (null for non-number * nodes). */ public Number numberValue() { return null; } /** * Returns 16-bit short value for this node, if and only if * this node is numeric ({@link #isNumber} returns true). For other * types returns 0. * For floating-point numbers, value is truncated using default * Java coercion, similar to how cast from double to short operates. * * @return Short value this node contains, if any; 0 for non-number * nodes. */ public short shortValue() { return 0; } /** * Returns integer value for this node, if and only if * this node is numeric ({@link #isNumber} returns true). For other * types returns 0. * For floating-point numbers, value is truncated using default * Java coercion, similar to how cast from double to int operates. * * @return Integer value this node contains, if any; 0 for non-number * nodes. */ public int intValue() { return 0; } /** * Returns 64-bit long value for this node, if and only if * this node is numeric ({@link #isNumber} returns true). For other * types returns 0. * For floating-point numbers, value is truncated using default * Java coercion, similar to how cast from double to long operates. * * @return Long value this node contains, if any; 0 for non-number * nodes. */ public long longValue() { return 0L; } /** * Returns 32-bit floating value for this node, if and only if * this node is numeric ({@link #isNumber} returns true). For other * types returns 0.0. * For integer values, conversion is done using coercion; this means * that an overflow is possible for `long` values * * @return 32-bit float value this node contains, if any; 0.0 for non-number nodes. * * @since 2.2 */ public float floatValue() { return 0.0f; } /** * Returns 64-bit floating point (double) value for this node, if and only if * this node is numeric ({@link #isNumber} returns true). For other * types returns 0.0. * For integer values, conversion is done using coercion; this may result * in overflows with {@link BigInteger} values. * * @return 64-bit double value this node contains, if any; 0.0 for non-number nodes. * * @since 2.2 */ public double doubleValue() { return 0.0; } public BigDecimal decimalValue() { return BigDecimal.ZERO; } public BigInteger bigIntegerValue() { return BigInteger.ZERO; } /* /********************************************************** /* Public API, value access with conversion(s)/coercion(s) /********************************************************** */ /** * Method that will return a valid String representation of * the container value, if the node is a value node * (method {@link #isValueNode} returns true), * otherwise empty String. */ public abstract String asText(); /** * Method that will try to convert value of this node to a Java int. * Numbers are coerced using default Java rules; booleans convert to 0 (false) * and 1 (true), and Strings are parsed using default Java language integer * parsing rules. *

* If representation can not be converted to an int (including structured types * like Objects and Arrays), * default value of 0 will be returned; no exceptions are thrown. */ public int asInt() { return asInt(0); } /** * Method that will try to convert value of this node to a Java int. * Numbers are coerced using default Java rules; booleans convert to 0 (false) * and 1 (true), and Strings are parsed using default Java language integer * parsing rules. *

* If representation can not be converted to an int (including structured types * like Objects and Arrays), * specified defaultValue will be returned; no exceptions are thrown. */ public int asInt(int defaultValue) { return defaultValue; } /** * Method that will try to convert value of this node to a Java long. * Numbers are coerced using default Java rules; booleans convert to 0 (false) * and 1 (true), and Strings are parsed using default Java language integer * parsing rules. *

* If representation can not be converted to an long (including structured types * like Objects and Arrays), * default value of 0 will be returned; no exceptions are thrown. */ public long asLong() { return asLong(0L); } /** * Method that will try to convert value of this node to a Java long. * Numbers are coerced using default Java rules; booleans convert to 0 (false) * and 1 (true), and Strings are parsed using default Java language integer * parsing rules. *

* If representation can not be converted to an long (including structured types * like Objects and Arrays), * specified defaultValue will be returned; no exceptions are thrown. */ public long asLong(long defaultValue) { return defaultValue; } /** * Method that will try to convert value of this node to a Java double. * Numbers are coerced using default Java rules; booleans convert to 0.0 (false) * and 1.0 (true), and Strings are parsed using default Java language integer * parsing rules. *

* If representation can not be converted to an int (including structured types * like Objects and Arrays), * default value of 0.0 will be returned; no exceptions are thrown. */ public double asDouble() { return asDouble(0.0); } /** * Method that will try to convert value of this node to a Java double. * Numbers are coerced using default Java rules; booleans convert to 0.0 (false) * and 1.0 (true), and Strings are parsed using default Java language integer * parsing rules. *

* If representation can not be converted to an int (including structured types * like Objects and Arrays), * specified defaultValue will be returned; no exceptions are thrown. */ public double asDouble(double defaultValue) { return defaultValue; } /** * Method that will try to convert value of this node to a Java boolean. * JSON booleans map naturally; integer numbers other than 0 map to true, and * 0 maps to false * and Strings 'true' and 'false' map to corresponding values. *

* If representation can not be converted to a boolean value (including structured types * like Objects and Arrays), * default value of false will be returned; no exceptions are thrown. */ public boolean asBoolean() { return asBoolean(false); } /** * Method that will try to convert value of this node to a Java boolean. * JSON booleans map naturally; integer numbers other than 0 map to true, and * 0 maps to false * and Strings 'true' and 'false' map to corresponding values. *

* If representation can not be converted to a boolean value (including structured types * like Objects and Arrays), * specified defaultValue will be returned; no exceptions are thrown. */ public boolean asBoolean(boolean defaultValue) { return defaultValue; } /* /********************************************************** /* Public API, value find / existence check methods /********************************************************** */ /** * Method that allows checking whether this node is JSON Object node * and contains value for specified property. If this is the case * (including properties with explicit null values), returns true; * otherwise returns false. *

* This method is equivalent to: *

     *   node.get(fieldName) != null
     *
* (since return value of get() is node, not value node contains) *

* NOTE: when explicit null values are added, this * method will return true for such properties. * * @param fieldName Name of element to check * * @return True if this node is a JSON Object node, and has a property * entry with specified name (with any value, including null value) */ public boolean has(String fieldName) { return get(fieldName) != null; } /** * Method that allows checking whether this node is JSON Array node * and contains a value for specified index * If this is the case * (including case of specified indexing having null as value), returns true; * otherwise returns false. *

* Note: array element indexes are 0-based. *

* This method is equivalent to: *

     *   node.get(index) != null
     *
*

* NOTE: this method will return true for explicitly added * null values. * * @param index Index to check * * @return True if this node is a JSON Object node, and has a property * entry with specified name (with any value, including null value) */ public boolean has(int index) { return get(index) != null; } /** * Method that is similar to {@link #has(String)}, but that will * return false for explicitly added nulls. *

* This method is functionally equivalent to: *

     *   node.get(fieldName) != null && !node.get(fieldName).isNull()
     *
* * @since 2.1 */ public boolean hasNonNull(String fieldName) { JsonNode n = get(fieldName); return (n != null) && !n.isNull(); } /** * Method that is similar to {@link #has(int)}, but that will * return false for explicitly added nulls. *

* This method is equivalent to: *

     *   node.get(index) != null && !node.get(index).isNull()
     *
* * @since 2.1 */ public boolean hasNonNull(int index) { JsonNode n = get(index); return (n != null) && !n.isNull(); } /* /********************************************************** /* Public API, container access /********************************************************** */ /** * Same as calling {@link #elements}; implemented so that * convenience "for-each" loop can be used for looping over elements * of JSON Array constructs. */ @Override public final Iterator iterator() { return elements(); } /** * Method for accessing all value nodes of this Node, iff * this node is a JSON Array or Object node. In case of Object node, * field names (keys) are not included, only values. * For other types of nodes, returns empty iterator. */ public Iterator elements() { return EmptyIterator.instance(); } /** * @return Iterator that can be used to traverse all key/value pairs for * object nodes; empty iterator (no contents) for other types */ public Iterator> fields() { return EmptyIterator.instance(); } /* /********************************************************** /* Public API, find methods /********************************************************** */ /** * Method for finding a JSON Object field with specified name in this * node or its child nodes, and returning value it has. * If no matching field is found in this node or its descendants, returns null. * * @param fieldName Name of field to look for * * @return Value of first matching node found, if any; null if none */ public abstract JsonNode findValue(String fieldName); /** * Method for finding JSON Object fields with specified name, and returning * found ones as a List. Note that sub-tree search ends if a field is found, * so possible children of result nodes are not included. * If no matching fields are found in this node or its descendants, returns * an empty List. * * @param fieldName Name of field to look for */ public final List findValues(String fieldName) { List result = findValues(fieldName, null); if (result == null) { return Collections.emptyList(); } return result; } /** * Similar to {@link #findValues}, but will additionally convert * values into Strings, calling {@link #asText}. */ public final List findValuesAsText(String fieldName) { List result = findValuesAsText(fieldName, null); if (result == null) { return Collections.emptyList(); } return result; } /** * Method similar to {@link #findValue}, but that will return a * "missing node" instead of null if no field is found. Missing node * is a specific kind of node for which {@link #isMissingNode} * returns true; and all value access methods return empty or * missing value. * * @param fieldName Name of field to look for * * @return Value of first matching node found; or if not found, a * "missing node" (non-null instance that has no value) */ public abstract JsonNode findPath(String fieldName); /** * Method for finding a JSON Object that contains specified field, * within this node or its descendants. * If no matching field is found in this node or its descendants, returns null. * * @param fieldName Name of field to look for * * @return Value of first matching node found, if any; null if none */ public abstract JsonNode findParent(String fieldName); /** * Method for finding a JSON Object that contains specified field, * within this node or its descendants. * If no matching field is found in this node or its descendants, returns null. * * @param fieldName Name of field to look for * * @return Value of first matching node found, if any; null if none */ public final List findParents(String fieldName) { List result = findParents(fieldName, null); if (result == null) { return Collections.emptyList(); } return result; } public abstract List findValues(String fieldName, List foundSoFar); public abstract List findValuesAsText(String fieldName, List foundSoFar); public abstract List findParents(String fieldName, List foundSoFar); /* /********************************************************** /* Public API, path handling /********************************************************** */ /** * Method that can be called on Object nodes, to access a property * that has Object value; or if no such property exists, to create, * add and return such Object node. * If the node method is called on is not Object node, * or if property exists and has value that is not Object node, * {@link UnsupportedOperationException} is thrown */ public JsonNode with(String propertyName) { throw new UnsupportedOperationException("JsonNode not of type ObjectNode (but " +getClass().getName()+"), can not call with() on it"); } /** * Method that can be called on Object nodes, to access a property * that has Array value; or if no such property exists, to create, * add and return such Array node. * If the node method is called on is not Object node, * or if property exists and has value that is not Array node, * {@link UnsupportedOperationException} is thrown */ public JsonNode withArray(String propertyName) { throw new UnsupportedOperationException("JsonNode not of type ObjectNode (but " +getClass().getName()+"), can not call withArray() on it"); } /* /********************************************************** /* Overridden standard methods /********************************************************** */ /** *

* Note: marked as abstract to ensure all implementation * classes define it properly. */ @Override public abstract String toString(); /** * Equality for node objects is defined as full (deep) value * equality. This means that it is possible to compare complete * JSON trees for equality by comparing equality of root nodes. *

* Note: marked as abstract to ensure all implementation * classes define it properly and not rely on definition * from {@link java.lang.Object}. */ @Override public abstract boolean equals(Object o); } JsonSerializable.java000066400000000000000000000040501215056657300345550ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.IOException; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; /** * Interface that can be implemented by objects that know how to * serialize themselves to JSON, using {@link JsonGenerator} * (and {@link SerializerProvider} if necessary). *

* Note that implementing this interface binds implementing object * closely to Jackson API, and that it is often not necessary to do * so -- if class is a bean, it can be serialized without * implementing this interface. *

* NOTE: Jackson 2.0 added another method (from former "JsonSerializableWithType"), * which is required for proper handling of case where additional type information * is needed. */ public interface JsonSerializable { /** * Serialization method called when no additional type information is * to be included in serialization. */ public void serialize(JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException; /** * Serialization method called when additional type information is * expected to be included in serialization, for deserialization to use. *

* Usually implementation consists of a call to one of methods * in {@link TypeSerializer} (such as {@link TypeSerializer#writeTypePrefixForObject(Object, JsonGenerator)}) * followed by serialization of contents, * followed by another call to {@link TypeSerializer} * (such as {@link TypeSerializer#writeTypeSuffixForObject(Object, JsonGenerator)}). * Exact methods to call in {@link TypeSerializer} depend on shape of JSON Object used * (Array, Object or scalar like String/Number/Boolean). *

* Note that some types (most notably, "natural" types: String, Integer, * Double and Boolean) never include type information. */ public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException; } JsonSerializer.java000066400000000000000000000227131215056657300342660ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.IOException; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.util.NameTransformer; /** * Abstract class that defines API used by {@link ObjectMapper} (and * other chained {@link JsonSerializer}s too) to serialize Objects of * arbitrary types into JSON, using provided {@link JsonGenerator}. * {@link com.fasterxml.jackson.databind.ser.std.StdSerializer} instead * of this class, since it will implement many of optional * methods of this class. *

* NOTE: various serialize methods are never (to be) called * with null values -- caller must handle null values, usually * by calling {@link SerializerProvider#findNullValueSerializer} to obtain * serializer to use. * This also means that custom serializers can not be directly used to change * the output to produce when serializing null values. *

* If serializer is an aggregate one -- meaning it delegates handling of some * of its contents by using other serializer(s) -- it typically also needs * to implement {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer}, * which can locate secondary serializers needed. This is important to allow dynamic * overrides of serializers; separate call interface is needed to separate * resolution of secondary serializers (which may have cyclic link back * to serializer itself, directly or indirectly). *

* In addition, to support per-property annotations (to configure aspects * of serialization on per-property basis), serializers may want * to implement * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}, * which allows specialization of serializers: call to * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer#createContextual} * is passed information on property, and can create a newly configured * serializer for handling that particular property. *

* If both * {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer} and * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer} * are implemented, resolution of serializers occurs before * contextualization. */ public abstract class JsonSerializer implements JsonFormatVisitable // since 2.1 { /* /********************************************************** /* Fluent factory methods for constructing decorated versions /********************************************************** */ /** * Method that will return serializer instance that produces * "unwrapped" serialization, if applicable for type being * serialized (which is the case for some serializers * that produce JSON Objects as output). * If no unwrapped serializer can be constructed, will simply * return serializer as-is. *

* Default implementation just returns serializer as-is, * indicating that no unwrapped variant exists * * @param unwrapper Name transformation to use to convert between names * of unwrapper properties */ public JsonSerializer unwrappingSerializer(NameTransformer unwrapper) { return this; } /** * Method that can be called to try to replace serializer this serializer * delegates calls to. If not supported (either this serializer does not * delegate anything; or it does not want any changes), should either * throw {@link UnsupportedOperationException} (if operation does not * make sense or is not allowed); or return this serializer as is. * * @since 2.1 */ public JsonSerializer replaceDelegatee(JsonSerializer delegatee) { throw new UnsupportedOperationException(); } /* /********************************************************** /* Serialization methods /********************************************************** */ /** * Method that can be called to ask implementation to serialize * values of type this serializer handles. * * @param value Value to serialize; can not be null. * @param jgen Generator used to output resulting Json content * @param provider Provider that can be used to get serializers for * serializing Objects value contains, if any. */ public abstract void serialize(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException; /** * Method that can be called to ask implementation to serialize * values of type this serializer handles, using specified type serializer * for embedding necessary type information. *

* Default implementation will throw {@link UnsupportedOperationException} * to indicate that proper type handling needs to be implemented. *

* For simple datatypes written as a single scalar value (JSON String, Number, Boolean), * implementation would look like: *

     *  // note: method to call depends on whether this type is serialized as JSON scalar, object or Array!
     *  typeSer.writeTypePrefixForScalar(value, jgen);
     *  serialize(value, jgen, provider);
     *  typeSer.writeTypeSuffixForScalar(value, jgen);
     *
* and implementations for type serialized as JSON Arrays or Objects would differ slightly, * as START-ARRAY>/END-ARRAY and * START-OBJECT>/END-OBJECT pairs * need to be properly handled with respect to serializing of contents. * * @param value Value to serialize; can not be null. * @param jgen Generator used to output resulting Json content * @param provider Provider that can be used to get serializers for * serializing Objects value contains, if any. * @param typeSer Type serializer to use for including type information */ public void serializeWithType(T value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException { Class clz = handledType(); if (clz == null) { clz = value.getClass(); } throw new UnsupportedOperationException("Type id handling not implemented for type "+clz.getName()); } /* /********************************************************** /* Other accessors /********************************************************** */ /** * Method for accessing type of Objects this serializer can handle. * Note that this information is not guaranteed to be exact -- it * may be a more generic (super-type) -- but it should not be * incorrect (return a non-related type). *

* Default implementation will return null, which essentially means * same as returning Object.class would; that is, that * nothing is known about handled type. *

*/ public Class handledType() { return null; } /** * Method called to check whether given serializable value is * considered "empty" value (for purposes of suppressing serialization * of empty values). *

* Default implementation will consider only null values to be empty. * * @since 2.0 */ public boolean isEmpty(T value) { return (value == null); } /** * Method that can be called to see whether this serializer instance * will use Object Id to handle cyclic references. */ public boolean usesObjectId() { return false; } /** * Accessor for checking whether this serializer is an * "unwrapping" serializer; this is necessary to know since * it may also require caller to suppress writing of the * leading property name. */ public boolean isUnwrappingSerializer() { return false; } /** * Accessor that can be used to determine if this serializer uses * another serializer for actual serialization, by delegating * calls. If so, will return immediate delegate (which itself may * delegate to further serializers); otherwise will return null. * * @return Serializer this serializer delegates calls to, if null; * null otherwise. * * @since 2.1 */ public JsonSerializer getDelegatee() { return null; } /* /********************************************************** /* Default JsonFormatVisitable implementation /********************************************************** */ /** * Default implementation simply calls {@link JsonFormatVisitorWrapper#expectAnyFormat(JavaType)}. * * @since 2.1 */ @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException { if (visitor != null) visitor.expectAnyFormat(type); } /* /********************************************************** /* Helper class(es) /********************************************************** */ /** * This marker class is only to be used with annotations, to * indicate that no serializer is configured. *

* Specifically, this class is to be used as the marker for * annotation {@link com.fasterxml.jackson.databind.annotation.JsonSerialize}. */ public abstract static class None extends JsonSerializer { } } KeyDeserializer.java000066400000000000000000000017341215056657300344160ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.IOException; import com.fasterxml.jackson.core.*; /** * Abstract class that defines API used for deserializing JSON content * field names into Java Map keys. These deserializers are only used * if the Map key class is not String or Object. */ public abstract class KeyDeserializer { /** * Method called to deserialize a {@link java.util.Map} key from JSON property name. */ public abstract Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException; /** * This marker class is only to be used with annotations, to * indicate that no deserializer is configured. *

* Specifically, this class is to be used as the marker for * annotation {@link com.fasterxml.jackson.databind.annotation.JsonDeserialize}. */ public abstract static class None extends KeyDeserializer { } } MapperFeature.java000066400000000000000000000253461215056657300340700ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.cfg.ConfigFeature; /** * Enumeration that defines simple on/off features to set * for {@link ObjectMapper}, and accessible (but not changeable) * via {@link ObjectReader} and {@link ObjectWriter} (as well as * through various convenience methods through context objects). *

* Note that in addition to being only mutable via {@link ObjectMapper}, * changes only take effect when done before any serialization or * deserialization calls -- that is, caller must follow * "configure-then-use" pattern. */ public enum MapperFeature implements ConfigFeature { /* /****************************************************** /* Introspection features /****************************************************** */ /** * Feature that determines whether annotation introspection * is used for configuration; if enabled, configured * {@link AnnotationIntrospector} will be used: if disabled, * no annotations are considered. *

* Feature is enabled by default. */ USE_ANNOTATIONS(true), /** * Feature that determines whether "creator" methods are * automatically detected by consider public constructors, * and static single argument methods with name "valueOf". * If disabled, only methods explicitly annotated are considered * creator methods (except for the no-arg default constructor which * is always considered a factory method). *

* Note that this feature has lower precedence than per-class * annotations, and is only used if there isn't more granular * configuration available. *

* Feature is enabled by default. */ AUTO_DETECT_CREATORS(true), /** * Feature that determines whether non-static fields are recognized as * properties. * If yes, then all public member fields * are considered as properties. If disabled, only fields explicitly * annotated are considered property fields. *

* Note that this feature has lower precedence than per-class * annotations, and is only used if there isn't more granular * configuration available. *

* Feature is enabled by default. */ AUTO_DETECT_FIELDS(true), /** * Feature that determines whether regualr "getter" methods are * automatically detected based on standard Bean naming convention * or not. If yes, then all public zero-argument methods that * start with prefix "get" * are considered as getters. * If disabled, only methods explicitly annotated are considered getters. *

* Note that since version 1.3, this does NOT include * "is getters" (see {@link #AUTO_DETECT_IS_GETTERS} for details) *

* Note that this feature has lower precedence than per-class * annotations, and is only used if there isn't more granular * configuration available. *

* Feature is enabled by default. */ AUTO_DETECT_GETTERS(true), /** * Feature that determines whether "is getter" methods are * automatically detected based on standard Bean naming convention * or not. If yes, then all public zero-argument methods that * start with prefix "is", and whose return type is boolean * are considered as "is getters". * If disabled, only methods explicitly annotated are considered getters. *

* Note that this feature has lower precedence than per-class * annotations, and is only used if there isn't more granular * configuration available. *

* Feature is enabled by default. */ AUTO_DETECT_IS_GETTERS(true), /** * Feature that determines whether "setter" methods are * automatically detected based on standard Bean naming convention * or not. If yes, then all public one-argument methods that * start with prefix "set" * are considered setters. If disabled, only methods explicitly * annotated are considered setters. *

* Note that this feature has lower precedence than per-class * annotations, and is only used if there isn't more granular * configuration available. *

* Feature is enabled by default. */ AUTO_DETECT_SETTERS(true), /** * Feature that determines whether getters (getter methods) * can be auto-detected if there is no matching mutator (setter, * constructor parameter or field) or not: if set to true, * only getters that match a mutator are auto-discovered; if * false, all auto-detectable getters can be discovered. *

* Feature is disabled by default. */ REQUIRE_SETTERS_FOR_GETTERS(false), /** * Feature that determines whether otherwise regular "getter" * methods (but only ones that handle Collections and Maps, * not getters of other type) * can be used for purpose of getting a reference to a Collection * and Map to modify the property, without requiring a setter * method. * This is similar to how JAXB framework sets Collections and * Maps: no setter is involved, just setter. *

* Note that such getters-as-setters methods have lower * precedence than setters, so they are only used if no * setter is found for the Map/Collection property. *

* Feature is enabled by default. */ USE_GETTERS_AS_SETTERS(true), /** * Feature that determines whether method and field access * modifier settings can be overridden when accessing * properties. If enabled, method * {@link java.lang.reflect.AccessibleObject#setAccessible} * may be called to enable access to otherwise unaccessible * objects. *

* Feature is enabled by default. */ CAN_OVERRIDE_ACCESS_MODIFIERS(true), /** * Feature that determines whether member mutators (fields and * setters) may be "pulled in" even if they are not visible, * as long as there is a visible accessor (getter or field) with same name. * For example: field "value" may be inferred as mutator, * if there is visible or explicitly marked getter "getValue()". * If enabled, inferring is enabled; otherwise (disabled) only visible and * explicitly annotated accessors are ever used. *

* Note that 'getters' are never inferred and need to be either visible (including * bean-style naming) or explicitly annotated. *

* Feature is enabled by default. * * @since 2.2 */ INFER_PROPERTY_MUTATORS(true), /** * Feature that determines whether member fields declared as 'final' may * be auto-detected to be used mutators (used to change value of the logical * property) or not. If enabled, 'final' access modifier has no effect, and * such fields may be detected according to usual visibility and inference * rules; if disabled, such fields are NOT used as mutators except if * explicitly annotated for such use. *

* Feature is enabled by default, for backwards compatibility reasons. */ ALLOW_FINAL_FIELDS_AS_MUTATORS(true), /* /****************************************************** /* Type-handling features /****************************************************** */ /** * Feature that determines whether the type detection for * serialization should be using actual dynamic runtime type, * or declared static type. * Note that deserialization always uses declared static types * since no runtime types are available (as we are creating * instances after using type information). *

* This global default value can be overridden at class, method * or field level by using {@link JsonSerialize#typing} annotation * property. *

* Feature is disabled by default which means that dynamic runtime types * are used (instead of declared static types) for serialization. */ USE_STATIC_TYPING(false), /* /****************************************************** /* View-related features /****************************************************** */ /** * Feature that determines whether properties that have no view * annotations are included in JSON serialization views (see * {@link com.fasterxml.jackson.annotation.JsonView} for more * details on JSON Views). * If enabled, non-annotated properties will be included; * when disabled, they will be excluded. So this feature * changes between "opt-in" (feature disabled) and * "opt-out" (feature enabled) modes. *

* Default value is enabled, meaning that non-annotated * properties are included in all views if there is no * {@link com.fasterxml.jackson.annotation.JsonView} annotation. *

* Feature is enabled by default. */ DEFAULT_VIEW_INCLUSION(true), /* /****************************************************** /* Generic output features /****************************************************** */ /** * Feature that defines default property serialization order used * for POJO fields (note: does not apply to {@link java.util.Map} * serialization!): * if enabled, default ordering is alphabetic (similar to * how {@link com.fasterxml.jackson.annotation.JsonPropertyOrder#alphabetic()} * works); if disabled, order is unspecified (based on what JDK gives * us, which may be declaration order, but is not guaranteed). *

* Note that this is just the default behavior, and can be overridden by * explicit overrides in classes. *

* Feature is disabled by default. */ SORT_PROPERTIES_ALPHABETICALLY(false), /* /****************************************************** /* Name-related features /****************************************************** */ /** * Feature that can be enabled to make property names be * overridden by wrapper name (usually detected with annotations * as defined by {@link AnnotationIntrospector#findWrapperName}. * If enabled, all properties that have associated non-empty Wrapper * name will use that wrapper name instead of property name. * If disabled, wrapper name is only used for wrapping (if anything). *

* Feature is disabled by default. * * @since 2.1 */ USE_WRAPPER_NAME_AS_PROPERTY_NAME(false) ; private final boolean _defaultState; private MapperFeature(boolean defaultState) { _defaultState = defaultState; } @Override public boolean enabledByDefault() { return _defaultState; } @Override public int getMask() { return (1 << ordinal()); } }MappingIterator.java000066400000000000000000000175001215056657300344260ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.Closeable; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.core.*; /** * Iterator exposed by {@link ObjectMapper} when binding sequence of * objects. Extension is done to allow more convenient exposing of * {@link IOException} (which basic {@link Iterator} does not expose) */ public class MappingIterator implements Iterator, Closeable { protected final static MappingIterator EMPTY_ITERATOR = new MappingIterator(null, null, null, null, false, null); protected final JavaType _type; protected final DeserializationContext _context; protected final JsonDeserializer _deserializer; protected JsonParser _parser; /** * Flag that indicates whether input {@link JsonParser} should be closed * when we are done or not; generally only called when caller did not * pass JsonParser. */ protected final boolean _closeParser; /** * Flag that is set when we have determined what {@link #hasNextValue()} * should value; reset when {@link #nextValue} is called */ protected boolean _hasNextChecked; /** * If not null, "value to update" instead of creating a new instance * for each call. */ protected final T _updatedValue; /** * @deprecated Since 2.1, to be removed */ @Deprecated protected MappingIterator(JavaType type, JsonParser jp, DeserializationContext ctxt, JsonDeserializer deser) { this(type, jp, ctxt, deser, true, null); } /** * @param managedParser Whether we "own" the {@link JsonParser} passed or not: * if true, it was created by {@link ObjectReader} and code here needs to * close it; if false, it was passed by calling code and should not be * closed by iterator. */ @SuppressWarnings("unchecked") protected MappingIterator(JavaType type, JsonParser jp, DeserializationContext ctxt, JsonDeserializer deser, boolean managedParser, Object valueToUpdate) { _type = type; _parser = jp; _context = ctxt; _deserializer = (JsonDeserializer) deser; _closeParser = managedParser; if (valueToUpdate == null) { _updatedValue = null; } else { _updatedValue = (T) valueToUpdate; } /* Ok: one more thing; we may have to skip START_ARRAY, assuming * "wrapped" sequence; but this is ONLY done for 'managed' parsers * and never if JsonParser was directly passed by caller (if it * was, caller must have either positioned it over first token of * the first element, or cleared the START_ARRAY token explicitly). * Note, however, that we do not try to guess whether this could be * an unwrapped sequence of arrays/Lists: we just assume it is wrapped; * and if not, caller needs to hand us JsonParser instead, pointing to * the first token of the first element. */ if (managedParser && jp != null && jp.getCurrentToken() == JsonToken.START_ARRAY) { jp.clearCurrentToken(); } } @SuppressWarnings("unchecked") protected static MappingIterator emptyIterator() { return (MappingIterator) EMPTY_ITERATOR; } /* /********************************************************** /* Basic iterator impl /********************************************************** */ @Override public boolean hasNext() { try { return hasNextValue(); } catch (JsonMappingException e) { throw new RuntimeJsonMappingException(e.getMessage(), e); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } } @Override public T next() { try { return nextValue(); } catch (JsonMappingException e) { throw new RuntimeJsonMappingException(e.getMessage(), e); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public void close() throws IOException{ if(_parser != null) { _parser.close(); } } /* /********************************************************** /* Extended API, iteration /********************************************************** */ /** * Equivalent of {@link #next} but one that may throw checked * exceptions from Jackson due to invalid input. */ public boolean hasNextValue() throws IOException { if (_parser == null) { return false; } if (!_hasNextChecked) { JsonToken t = _parser.getCurrentToken(); _hasNextChecked = true; if (t == null) { // un-initialized or cleared; find next t = _parser.nextToken(); // If EOF, no more, or if we hit END_ARRAY (although we don't clear the token). if (t == null || t == JsonToken.END_ARRAY) { JsonParser jp = _parser; _parser = null; if (_closeParser) { jp.close(); } return false; } } } return true; } public T nextValue() throws IOException { // caller should always call 'hasNext[Value]' first; but let's ensure: if (!_hasNextChecked) { if (!hasNextValue()) { throw new NoSuchElementException(); } } if (_parser == null) { throw new NoSuchElementException(); } _hasNextChecked = false; T result; if (_updatedValue == null) { result = _deserializer.deserialize(_parser, _context); } else{ _deserializer.deserialize(_parser, _context, _updatedValue); result = _updatedValue; } // Need to consume the token too _parser.clearCurrentToken(); return result; } /** * Convenience method for reading all entries accessible via * this iterator * * @return List of entries read * * @since 2.2 */ public List readAll() throws IOException { return readAll(new ArrayList()); } /** * Convenience method for reading all entries accessible via * this iterator * * @return List of entries read (same as passed-in argument) * * @since 2.2 */ public List readAll(List resultList) throws IOException { while (hasNextValue()) { resultList.add(nextValue()); } return resultList; } /* /********************************************************** /* Extended API, accessors /********************************************************** */ /** * Accessor for getting underlying parser this iterator uses. * * @since 2.2 */ public JsonParser getParser() { return _parser; } /** * Accessor for accessing {@link FormatSchema} that the underlying parser * (as per {@link #getParser}) is using, if any; only parser of schema-aware * formats use schemas. * * @since 2.2 */ public FormatSchema getParserSchema() { return _parser.getSchema(); } /** * Convenience method, functionally equivalent to: * * iterator.getParser().getCurrentLocation() * * * @return Location of the input stream of the underlying parser * * @since 2.2.1 */ public JsonLocation getCurrentLocation() { return _parser.getCurrentLocation(); } } MappingJsonFactory.java000066400000000000000000000053641215056657300351030ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/* Jackson JSON-processor. * * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi * * Licensed under the License specified in file LICENSE, included with * the source code and binary code bundles. * You may not use this file except in compliance with the License. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fasterxml.jackson.databind; import java.io.IOException; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.format.InputAccessor; import com.fasterxml.jackson.core.format.MatchStrength; /** * Sub-class of {@link JsonFactory} that will create a proper * {@link ObjectCodec} to allow seam-less conversions between * JSON content and Java objects (POJOs). * The only addition to regular {@link JsonFactory} currently * is that {@link ObjectMapper} is constructed and passed as * the codec to use. */ public class MappingJsonFactory extends JsonFactory { // generated for Jackson 2.1.0 private static final long serialVersionUID = -6744103724013275513L; public MappingJsonFactory() { this(null); } public MappingJsonFactory(ObjectMapper mapper) { super(mapper); if (mapper == null) { setCodec(new ObjectMapper(this)); } } /** * We'll override the method to return more specific type; co-variance * helps here */ @Override public final ObjectMapper getCodec() { return (ObjectMapper) _objectCodec; } // @since 2.1 @Override public JsonFactory copy() { _checkInvalidCopy(MappingJsonFactory.class); // note: as with base class, must NOT copy mapper reference return new MappingJsonFactory(null); } /* /********************************************************** /* Format detection functionality (since 1.8) /********************************************************** */ /** * Sub-classes need to override this method (as of 1.8) */ @Override public String getFormatName() { /* since non-JSON factories typically should not extend this class, * let's just always return JSON as name. */ return FORMAT_NAME_JSON; } /** * Sub-classes need to override this method (as of 1.8) */ @Override public MatchStrength hasFormat(InputAccessor acc) throws IOException { if (getClass() == MappingJsonFactory.class) { return hasJSONFormat(acc); } return null; } } jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/Module.java000066400000000000000000000265231215056657300326320ustar00rootroot00000000000000package com.fasterxml.jackson.databind; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; import com.fasterxml.jackson.databind.deser.Deserializers; import com.fasterxml.jackson.databind.deser.KeyDeserializers; import com.fasterxml.jackson.databind.deser.ValueInstantiators; import com.fasterxml.jackson.databind.introspect.ClassIntrospector; import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; import com.fasterxml.jackson.databind.ser.Serializers; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.type.TypeModifier; /** * Simple interface for extensions that can be registered with {@link ObjectMapper} * to provide a well-defined set of extensions to default functionality; such as * support for new data types. */ public abstract class Module implements Versioned { /* /********************************************************** /* Simple accessors /********************************************************** */ /** * Method that returns identifier for module; this can be used by Jackson * for informational purposes, as well as in associating extensions with * module that provides them. */ public abstract String getModuleName(); /** * Method that returns version of this module. Can be used by Jackson for * informational purposes. */ @Override public abstract Version version(); /* /********************************************************** /* Life-cycle: registration /********************************************************** */ /** * Method called by {@link ObjectMapper} when module is registered. * It is called to let module register functionality it provides, * using callback methods passed-in context object exposes. */ public abstract void setupModule(SetupContext context); /* /********************************************************** /* Helper types /********************************************************** */ /** * Interface Jackson exposes to modules for purpose of registering * extended functionality. * Usually implemented by {@link ObjectMapper}, but modules should * NOT rely on this -- if they do require access to mapper instance, * they need to call {@link SetupContext#getOwner} method. */ public static interface SetupContext { /* /********************************************************** /* Simple accessors /********************************************************** */ /** * Method that returns version information about {@link ObjectMapper} * that implements this context. Modules can use this to choose * different settings or initialization order; or even decide to fail * set up completely if version is compatible with module. */ public Version getMapperVersion(); /** * Fallback access method that allows modules to refer to the * {@link ObjectMapper} that provided this context. * It should NOT be needed by most modules; and ideally should * not be used -- however, there may be cases where this may * be necessary due to various design constraints. *

* NOTE: use of this method is discouraged, as it allows access to * things Modules typically should not modify. It is included, however, * to allow access to new features in cases where Module API * has not yet been extended, or there are oversights. *

* Return value is chosen to not leak dependency to {@link ObjectMapper}; * however, instance will always be of that type. * This is why return value is declared generic, to allow caller to * specify context to often avoid casting. * * @since 2.0 */ public C getOwner(); /** * Accessor for finding {@link TypeFactory} that is currently configured * by the context. *

* NOTE: since it is possible that other modules might change or replace * TypeFactory, use of this method adds order-dependency for registrations. * * @since 2.0 */ public TypeFactory getTypeFactory(); public boolean isEnabled(MapperFeature f); public boolean isEnabled(DeserializationFeature f); public boolean isEnabled(SerializationFeature f); public boolean isEnabled(JsonFactory.Feature f); public boolean isEnabled(JsonParser.Feature f); public boolean isEnabled(JsonGenerator.Feature f); /* /********************************************************** /* Handler registration; serializers/deserializers /********************************************************** */ /** * Method that module can use to register additional deserializers to use for * handling types. * * @param d Object that can be called to find deserializer for types supported * by module (null returned for non-supported types) */ public void addDeserializers(Deserializers d); /** * Method that module can use to register additional deserializers to use for * handling Map key values (which are separate from value deserializers because * they are always serialized from String values) */ public void addKeyDeserializers(KeyDeserializers s); /** * Method that module can use to register additional serializers to use for * handling types. * * @param s Object that can be called to find serializer for types supported * by module (null returned for non-supported types) */ public void addSerializers(Serializers s); /** * Method that module can use to register additional serializers to use for * handling Map key values (which are separate from value serializers because * they must write JsonToken.FIELD_NAME instead of String value). */ public void addKeySerializers(Serializers s); /* /********************************************************** /* Handler registration; other /********************************************************** */ /** * Method that module can use to register additional modifier objects to * customize configuration and construction of bean deserializers. * * @param mod Modifier to register */ public void addBeanDeserializerModifier(BeanDeserializerModifier mod); /** * Method that module can use to register additional modifier objects to * customize configuration and construction of bean serializers. * * @param mod Modifier to register */ public void addBeanSerializerModifier(BeanSerializerModifier mod); /** * Method that module can use to register additional * {@link AbstractTypeResolver} instance, to handle resolution of * abstract to concrete types (either by defaulting, or by materializing). * * @param resolver Resolver to add. */ public void addAbstractTypeResolver(AbstractTypeResolver resolver); /** * Method that module can use to register additional * {@link TypeModifier} instance, which can augment {@link com.fasterxml.jackson.databind.JavaType} * instances constructed by {@link com.fasterxml.jackson.databind.type.TypeFactory}. * * @param modifier to add */ public void addTypeModifier(TypeModifier modifier); /** * Method that module can use to register additional {@link com.fasterxml.jackson.databind.deser.ValueInstantiator}s, * by adding {@link ValueInstantiators} object that gets called when * instantatiator is needed by a deserializer. * * @param instantiators Object that can provide {@link com.fasterxml.jackson.databind.deser.ValueInstantiator}s for * constructing POJO values during deserialization */ public void addValueInstantiators(ValueInstantiators instantiators); /** * Method for replacing the default class introspector with a derived class that * overrides specific behavior. * * @param ci Derived class of ClassIntrospector with overriden behavior * * @since 2.2 */ public void setClassIntrospector(ClassIntrospector ci); /** * Method for registering specified {@link AnnotationIntrospector} as the highest * priority introspector (will be chained with existing introspector(s) which * will be used as fallbacks for cases this introspector does not handle) * * @param ai Annotation introspector to register. */ public void insertAnnotationIntrospector(AnnotationIntrospector ai); /** * Method for registering specified {@link AnnotationIntrospector} as the lowest * priority introspector, chained with existing introspector(s) and called * as fallback for cases not otherwise handled. * * @param ai Annotation introspector to register. */ public void appendAnnotationIntrospector(AnnotationIntrospector ai); /** * Method for registering specified classes as subtypes (of supertype(s) * they have) */ public void registerSubtypes(Class... subtypes); /** * Method for registering specified classes as subtypes (of supertype(s) * they have), using specified type names. */ public void registerSubtypes(NamedType... subtypes); /** * Method used for defining mix-in annotations to use for augmenting * specified class or interface. * All annotations from * mixinSource are taken to override annotations * that target (or its supertypes) has. *

* Note: mix-ins are registered both for serialization and deserialization * (which can be different internally). *

* Note: currently only one set of mix-in annotations can be defined for * a single class; so if multiple modules register mix-ins, highest * priority one (last one registered) will have priority over other modules. * * @param target Class (or interface) whose annotations to effectively override * @param mixinSource Class (or interface) whose annotations are to * be "added" to target's annotations, overriding as necessary */ public void setMixInAnnotations(Class target, Class mixinSource); /** * Add a deserialization problem handler * * @param handler The deserialization problem handler */ public void addDeserializationProblemHandler(DeserializationProblemHandler handler); } } ObjectMapper.java000066400000000000000000003370531215056657300337040ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.*; import java.lang.reflect.Type; import java.net.URL; import java.text.DateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.io.SegmentedStringWriter; import com.fasterxml.jackson.core.io.SerializedString; import com.fasterxml.jackson.core.type.ResolvedType; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.util.*; import com.fasterxml.jackson.databind.cfg.BaseSettings; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.deser.*; import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.jsontype.*; import com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver; import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder; import com.fasterxml.jackson.databind.node.*; import com.fasterxml.jackson.databind.ser.*; import com.fasterxml.jackson.databind.type.*; import com.fasterxml.jackson.databind.util.RootNameLookup; import com.fasterxml.jackson.databind.util.StdDateFormat; import com.fasterxml.jackson.databind.util.TokenBuffer; /** * This mapper (or, data binder, or codec) provides functionality for * converting between Java objects (instances of JDK provided core classes, * beans), and matching JSON constructs. * It will use instances of {@link JsonParser} and {@link JsonGenerator} * for implementing actual reading/writing of JSON. *

* The main conversion API is defined in {@link ObjectCodec}, so that * implementation details of this class need not be exposed to * streaming parser and generator classes. *

* Note on caching: root-level deserializers are always cached, and accessed * using full (generics-aware) type information. This is different from * caching of referenced types, which is more limited and is done only * for a subset of all deserializer types. The main reason for difference * is that at root-level there is no incoming reference (and hence no * referencing property, no referral information or annotations to * produce differing deserializers), and that the performance impact * greatest at root level (since it'll essentially cache the full * graph of deserializers involved). */ public class ObjectMapper extends ObjectCodec implements Versioned, java.io.Serializable // as of 2.1 { private static final long serialVersionUID = 1L; /* /********************************************************** /* Helper classes, enums /********************************************************** */ /** * Enumeration used with {@link ObjectMapper#enableDefaultTyping()} * to specify what kind of types (classes) default typing should * be used for. It will only be used if no explicit type information * is found, but this enumeration further limits subset of those types. */ public enum DefaultTyping { /** * This value means that only properties that have * {@link java.lang.Object} as declared type (including * generic types without explicit type) will use default * typing. */ JAVA_LANG_OBJECT, /** * Value that means that default typing will be used for * properties with declared type of {@link java.lang.Object} * or an abstract type (abstract class or interface). * Note that this does not include array types. */ OBJECT_AND_NON_CONCRETE, /** * Value that means that default typing will be used for * all types covered by {@link #OBJECT_AND_NON_CONCRETE} * plus all array types for them. */ NON_CONCRETE_AND_ARRAYS, /** * Value that means that default typing will be used for * all non-final types, with exception of small number of * "natural" types (String, Boolean, Integer, Double), which * can be correctly inferred from JSON; as well as for * all arrays of non-final types. */ NON_FINAL } /** * Customized {@link TypeResolverBuilder} that provides type resolver builders * used with so-called "default typing" * (see {@link ObjectMapper#enableDefaultTyping()} for details). *

* Type resolver construction is based on configuration: implementation takes care * of only providing builders in cases where type information should be applied. * This is important since build calls may be sent for any and all types, and * type information should NOT be applied to all of them. */ public static class DefaultTypeResolverBuilder extends StdTypeResolverBuilder implements java.io.Serializable { private static final long serialVersionUID = 1L; /** * Definition of what types is this default typer valid for. */ protected final DefaultTyping _appliesFor; public DefaultTypeResolverBuilder(DefaultTyping t) { _appliesFor = t; } @Override public TypeDeserializer buildTypeDeserializer(DeserializationConfig config, JavaType baseType, Collection subtypes) { return useForType(baseType) ? super.buildTypeDeserializer(config, baseType, subtypes) : null; } @Override public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType, Collection subtypes) { return useForType(baseType) ? super.buildTypeSerializer(config, baseType, subtypes) : null; } /** * Method called to check if the default type handler should be * used for given type. * Note: "natural types" (String, Boolean, Integer, Double) will never * use typing; that is both due to them being concrete and final, * and since actual serializers and deserializers will also ignore any * attempts to enforce typing. */ public boolean useForType(JavaType t) { switch (_appliesFor) { case NON_CONCRETE_AND_ARRAYS: while (t.isArrayType()) { t = t.getContentType(); } // fall through case OBJECT_AND_NON_CONCRETE: return (t.getRawClass() == Object.class) || !t.isConcrete(); case NON_FINAL: while (t.isArrayType()) { t = t.getContentType(); } return !t.isFinal(); // includes Object.class default: //case JAVA_LANG_OBJECT: return (t.getRawClass() == Object.class); } } } /* /********************************************************** /* Internal constants, singletons /********************************************************** */ // Quick little shortcut, to avoid having to use global TypeFactory instance... private final static JavaType JSON_NODE_TYPE = SimpleType.constructUnsafe(JsonNode.class); /* !!! 03-Apr-2009, tatu: Should try to avoid direct reference... but not * sure what'd be simple and elegant way. So until then: */ protected final static ClassIntrospector DEFAULT_INTROSPECTOR = BasicClassIntrospector.instance; // 16-May-2009, tatu: Ditto ^^^ protected final static AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR = new JacksonAnnotationIntrospector(); protected final static VisibilityChecker STD_VISIBILITY_CHECKER = VisibilityChecker.Std.defaultInstance(); protected final static PrettyPrinter _defaultPrettyPrinter = new DefaultPrettyPrinter(); /** * Base settings contain defaults used for all {@link ObjectMapper} * instances. */ protected final static BaseSettings DEFAULT_BASE = new BaseSettings(DEFAULT_INTROSPECTOR, DEFAULT_ANNOTATION_INTROSPECTOR, STD_VISIBILITY_CHECKER, null, TypeFactory.defaultInstance(), null, StdDateFormat.instance, null, Locale.getDefault(), // TimeZone.getDefault() TimeZone.getTimeZone("GMT"), Base64Variants.getDefaultVariant() // 2.1 ); /* /********************************************************** /* Configuration settings, shared /********************************************************** */ /** * Factory used to create {@link JsonParser} and {@link JsonGenerator} * instances as necessary. */ protected final JsonFactory _jsonFactory; /** * Specific factory used for creating {@link JavaType} instances; * needed to allow modules to add more custom type handling * (mostly to support types of non-Java JVM languages) */ protected TypeFactory _typeFactory; /** * Provider for values to inject in deserialized POJOs. */ protected InjectableValues _injectableValues; /** * Thing used for registering sub-types, resolving them to * super/sub-types as needed. */ protected SubtypeResolver _subtypeResolver; /** * Cache for root names used when root-wrapping is enabled. */ protected final RootNameLookup _rootNames; /* /********************************************************** /* Configuration settings: mix-in annotations /********************************************************** */ /** * Mapping that defines how to apply mix-in annotations: key is * the type to received additional annotations, and value is the * type that has annotations to "mix in". *

* Annotations associated with the value classes will be used to * override annotations of the key class, associated with the * same field or method. They can be further masked by sub-classes: * you can think of it as injecting annotations between the target * class and its sub-classes (or interfaces) */ protected final HashMap> _mixInAnnotations = new HashMap>(); /* /********************************************************** /* Configuration settings, serialization /********************************************************** */ /** * Configuration object that defines basic global * settings for the serialization process */ protected SerializationConfig _serializationConfig; /** * Object that manages access to serializers used for serialization, * including caching. * It is configured with {@link #_serializerFactory} to allow * for constructing custom serializers. *

* Note: while serializers are only exposed {@link SerializerProvider}, * mappers and readers need to access additional API defined by * {@link DefaultSerializerProvider} */ protected DefaultSerializerProvider _serializerProvider; /** * Serializer factory used for constructing serializers. */ protected SerializerFactory _serializerFactory; /* /********************************************************** /* Configuration settings, deserialization /********************************************************** */ /** * Configuration object that defines basic global * settings for the serialization process */ protected DeserializationConfig _deserializationConfig; /** * Blueprint context object; stored here to allow custom * sub-classes. Contains references to objects needed for * deserialization construction (cache, factory). */ protected DefaultDeserializationContext _deserializationContext; /* /********************************************************** /* Caching /********************************************************** */ /* Note: handling of serializers and deserializers is not symmetric; * and as a result, only root-level deserializers can be cached here. * This is mostly because typing and resolution for deserializers is * fully static; whereas it is quite dynamic for serialization. */ /** * We will use a separate main-level Map for keeping track * of root-level deserializers. This is where most succesful * cache lookups get resolved. * Map will contain resolvers for all kinds of types, including * container types: this is different from the component cache * which will only cache bean deserializers. *

* Given that we don't expect much concurrency for additions * (should very quickly converge to zero after startup), let's * explicitly define a low concurrency setting. *

* Since version 1.5, these may are either "raw" deserializers (when * no type information is needed for base type), or type-wrapped * deserializers (if it is needed) */ final protected ConcurrentHashMap> _rootDeserializers = new ConcurrentHashMap>(64, 0.6f, 2); /* /********************************************************** /* Life-cycle: constructing instance /********************************************************** */ /** * Default constructor, which will construct the default * {@link JsonFactory} as necessary, use * {@link SerializerProvider} as its * {@link SerializerProvider}, and * {@link BeanSerializerFactory} as its * {@link SerializerFactory}. * This means that it * can serialize all standard JDK types, as well as regular * Java Beans (based on method names and Jackson-specific annotations), * but does not support JAXB annotations. */ public ObjectMapper() { this(null, null, null); } /** * Constructs instance that uses specified {@link JsonFactory} * for constructing necessary {@link JsonParser}s and/or * {@link JsonGenerator}s. */ public ObjectMapper(JsonFactory jf) { this(jf, null, null); } /** * Copy-constructor, mostly used to support {@link #copy}. * * @since 2.1 */ protected ObjectMapper(ObjectMapper src) { _jsonFactory = src._jsonFactory.copy(); _jsonFactory.setCodec(this); _subtypeResolver = src._subtypeResolver; _rootNames = new RootNameLookup(); _typeFactory = src._typeFactory; _serializationConfig = src._serializationConfig; HashMap> mixins = new HashMap>(src._mixInAnnotations); _serializationConfig = new SerializationConfig(src._serializationConfig, mixins); _deserializationConfig = new DeserializationConfig(src._deserializationConfig, mixins); _serializerProvider = src._serializerProvider; _deserializationContext = src._deserializationContext; // Default serializer factory is stateless, can just assign _serializerFactory = src._serializerFactory; } /** * Constructs instance that uses specified {@link JsonFactory} * for constructing necessary {@link JsonParser}s and/or * {@link JsonGenerator}s, and uses given providers for accessing * serializers and deserializers. * * @param jf JsonFactory to use: if null, a new {@link MappingJsonFactory} will be constructed * @param sp SerializerProvider to use: if null, a {@link SerializerProvider} will be constructed * @param dc Blueprint deserialization context instance to use for creating * actual context objects; if null, will construct standard * {@link DeserializationContext} */ public ObjectMapper(JsonFactory jf, DefaultSerializerProvider sp, DefaultDeserializationContext dc) { /* 02-Mar-2009, tatu: Important: we MUST default to using * the mapping factory, otherwise tree serialization will * have problems with POJONodes. * 03-Jan-2010, tatu: and obviously we also must pass 'this', * to create actual linking. */ if (jf == null) { _jsonFactory = new MappingJsonFactory(this); } else { _jsonFactory = jf; if (jf.getCodec() == null) { // as per [JACKSON-741] _jsonFactory.setCodec(this); } } _subtypeResolver = new StdSubtypeResolver(); _rootNames = new RootNameLookup(); // and default type factory is shared one _typeFactory = TypeFactory.defaultInstance(); _serializationConfig = new SerializationConfig(DEFAULT_BASE, _subtypeResolver, _mixInAnnotations); _deserializationConfig = new DeserializationConfig(DEFAULT_BASE, _subtypeResolver, _mixInAnnotations); _serializerProvider = (sp == null) ? new DefaultSerializerProvider.Impl() : sp; _deserializationContext = (dc == null) ? new DefaultDeserializationContext.Impl(BeanDeserializerFactory.instance) : dc; // Default serializer factory is stateless, can just assign _serializerFactory = BeanSerializerFactory.instance; } /** * Method for creating a new {@link ObjectMapper} instance that * has same initial configuration as this instance. Note that this * also requires making a copy of the underlying {@link JsonFactory} * instance. *

* Method is typically * used when multiple, differently configured mappers are needed. * Although configuration is shared, cached serializers and deserializers * are NOT shared, which means that the new instance may be re-configured * before use; meaning that it behaves the same way as if an instance * was constructed from scratch. * * @since 2.1 */ public ObjectMapper copy() { _checkInvalidCopy(ObjectMapper.class); return new ObjectMapper(this); } /** * @since 2.1 * @param exp */ protected void _checkInvalidCopy(Class exp) { if (getClass() != exp) { throw new IllegalStateException("Failed copy(): "+getClass().getName() +" (version: "+version()+") does not override copy(); it has to"); } } /* /********************************************************** /* Versioned impl /********************************************************** */ /** * Method that will return version information stored in and read from jar * that contains this class. */ @Override public Version version() { return com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION; } /* /********************************************************** /* Module registration, discovery /********************************************************** */ /** * Method for registering a module that can extend functionality * provided by this mapper; for example, by adding providers for * custom serializers and deserializers. * * @param module Module to register */ public ObjectMapper registerModule(Module module) { /* Let's ensure we have access to name and version information, * even if we do not have immediate use for either. This way we know * that they will be available from beginning */ String name = module.getModuleName(); if (name == null) { throw new IllegalArgumentException("Module without defined name"); } Version version = module.version(); if (version == null) { throw new IllegalArgumentException("Module without defined version"); } final ObjectMapper mapper = this; // And then call registration module.setupModule(new Module.SetupContext() { // // // Accessors @Override public Version getMapperVersion() { return version(); } @SuppressWarnings("unchecked") @Override public C getOwner() { // why do we need the cast here?!? return (C) mapper; } @Override public TypeFactory getTypeFactory() { return _typeFactory; } @Override public boolean isEnabled(MapperFeature f) { return mapper.isEnabled(f); } @Override public boolean isEnabled(DeserializationFeature f) { return mapper.isEnabled(f); } @Override public boolean isEnabled(SerializationFeature f) { return mapper.isEnabled(f); } @Override public boolean isEnabled(JsonFactory.Feature f) { return mapper.isEnabled(f); } @Override public boolean isEnabled(JsonParser.Feature f) { return mapper.isEnabled(f); } @Override public boolean isEnabled(JsonGenerator.Feature f) { return mapper.isEnabled(f); } // // // Methods for registering handlers: deserializers @Override public void addDeserializers(Deserializers d) { DeserializerFactory df = mapper._deserializationContext._factory.withAdditionalDeserializers(d); mapper._deserializationContext = mapper._deserializationContext.with(df); } @Override public void addKeyDeserializers(KeyDeserializers d) { DeserializerFactory df = mapper._deserializationContext._factory.withAdditionalKeyDeserializers(d); mapper._deserializationContext = mapper._deserializationContext.with(df); } @Override public void addBeanDeserializerModifier(BeanDeserializerModifier modifier) { DeserializerFactory df = mapper._deserializationContext._factory.withDeserializerModifier(modifier); mapper._deserializationContext = mapper._deserializationContext.with(df); } // // // Methods for registering handlers: serializers @Override public void addSerializers(Serializers s) { mapper._serializerFactory = mapper._serializerFactory.withAdditionalSerializers(s); } @Override public void addKeySerializers(Serializers s) { mapper._serializerFactory = mapper._serializerFactory.withAdditionalKeySerializers(s); } @Override public void addBeanSerializerModifier(BeanSerializerModifier modifier) { mapper._serializerFactory = mapper._serializerFactory.withSerializerModifier(modifier); } // // // Methods for registering handlers: other @Override public void addAbstractTypeResolver(AbstractTypeResolver resolver) { DeserializerFactory df = mapper._deserializationContext._factory.withAbstractTypeResolver(resolver); mapper._deserializationContext = mapper._deserializationContext.with(df); } @Override public void addTypeModifier(TypeModifier modifier) { TypeFactory f = mapper._typeFactory; f = f.withModifier(modifier); mapper.setTypeFactory(f); } @Override public void addValueInstantiators(ValueInstantiators instantiators) { DeserializerFactory df = mapper._deserializationContext._factory.withValueInstantiators(instantiators); mapper._deserializationContext = mapper._deserializationContext.with(df); } @Override public void setClassIntrospector(ClassIntrospector ci) { mapper._deserializationConfig = mapper._deserializationConfig.with(ci); mapper._serializationConfig = mapper._serializationConfig.with(ci); } @Override public void insertAnnotationIntrospector(AnnotationIntrospector ai) { mapper._deserializationConfig = mapper._deserializationConfig.withInsertedAnnotationIntrospector(ai); mapper._serializationConfig = mapper._serializationConfig.withInsertedAnnotationIntrospector(ai); } @Override public void appendAnnotationIntrospector(AnnotationIntrospector ai) { mapper._deserializationConfig = mapper._deserializationConfig.withAppendedAnnotationIntrospector(ai); mapper._serializationConfig = mapper._serializationConfig.withAppendedAnnotationIntrospector(ai); } @Override public void registerSubtypes(Class... subtypes) { mapper.registerSubtypes(subtypes); } @Override public void registerSubtypes(NamedType... subtypes) { mapper.registerSubtypes(subtypes); } @Override public void setMixInAnnotations(Class target, Class mixinSource) { mapper.addMixInAnnotations(target, mixinSource); } @Override public void addDeserializationProblemHandler(DeserializationProblemHandler handler) { mapper.addHandler(handler); } }); return this; } /** * Convenience method for registering specified modules in order; * functionally equivalent to: *

     *   for (Module module : modules) {
     *      registerModule(module);
     *   }
     *
* * @since 2.2 */ public ObjectMapper registerModules(Module... modules) { for (Module module : modules) { registerModule(module); } return this; } /** * Convenience method for registering specified modules in order; * functionally equivalent to: *
     *   for (Module module : modules) {
     *      registerModule(module);
     *   }
     *
* * @since 2.2 */ public ObjectMapper registerModules(Iterable modules) { for (Module module : modules) { registerModule(module); } return this; } /** * Method for locating available methods, using JDK {@link ServiceLoader} * facility, along with module-provided SPI. *

* Note that method does not do any caching, so calls should be considered * potentially expensive. * * @since 2.2 */ public static List findModules() { return findModules(null); } /** * Method for locating available methods, using JDK {@link ServiceLoader} * facility, along with module-provided SPI. *

* Note that method does not do any caching, so calls should be considered * potentially expensive. * * @since 2.2 */ public static List findModules(ClassLoader classLoader) { ArrayList modules = new ArrayList(); ServiceLoader loader = (classLoader == null) ? ServiceLoader.load(Module.class) : ServiceLoader.load(Module.class, classLoader); for (Module module : loader) { modules.add(module); } return modules; } /** * Convenience method that is functionally equivalent to: * * mapper.registerModules(mapper.findModules()); * *

* As with {@link #findModules()}, no caching is done for modules, so care * needs to be taken to either create and share a single mapper instance; * or to cache introspected set of modules. * * @since 2.2 */ public ObjectMapper findAndRegisterModules() { return registerModules(findModules()); } /* /********************************************************** /* Configuration: main config object access /********************************************************** */ /** * Method that returns the shared default {@link SerializationConfig} * object that defines configuration settings for serialization. *

* Note that since instances are immutable, you can NOT change settings * by accessing an instance and calling methods: this will simply create * new instance of config object. */ public SerializationConfig getSerializationConfig() { return _serializationConfig; } /** * Method that returns * the shared default {@link DeserializationConfig} object * that defines configuration settings for deserialization. *

* Note that since instances are immutable, you can NOT change settings * by accessing an instance and calling methods: this will simply create * new instance of config object. */ public DeserializationConfig getDeserializationConfig() { return _deserializationConfig; } /** * Method for getting current {@link DeserializationContext}. *

* Note that since instances are immutable, you can NOT change settings * by accessing an instance and calling methods: this will simply create * new instance of context object. */ public DeserializationContext getDeserializationContext() { return _deserializationContext; } /* /********************************************************** /* Configuration: ser/deser factory, provider access /********************************************************** */ /** * Method for setting specific {@link SerializerFactory} to use * for constructing (bean) serializers. */ public ObjectMapper setSerializerFactory(SerializerFactory f) { _serializerFactory = f; return this; } /** * Method for getting current {@link SerializerFactory}. *

* Note that since instances are immutable, you can NOT change settings * by accessing an instance and calling methods: this will simply create * new instance of factory object. */ public SerializerFactory getSerializerFactory() { return _serializerFactory; } /** * Method for setting specific {@link SerializerProvider} to use * for handling caching of {@link JsonSerializer} instances. */ public ObjectMapper setSerializerProvider(DefaultSerializerProvider p) { _serializerProvider = p; return this; } public SerializerProvider getSerializerProvider() { return _serializerProvider; } /* /********************************************************** /* Configuration: mix-in annotations /********************************************************** */ /** * Method to use for defining mix-in annotations to use for augmenting * annotations that processable (serializable / deserializable) * classes have. * Mixing in is done when introspecting class annotations and properties. * Map passed contains keys that are target classes (ones to augment * with new annotation overrides), and values that are source classes * (have annotations to use for augmentation). * Annotations from source classes (and their supertypes) * will override * annotations that target classes (and their super-types) have. */ public final void setMixInAnnotations(Map, Class> sourceMixins) { _mixInAnnotations.clear(); if (sourceMixins != null && sourceMixins.size() > 0) { for (Map.Entry,Class> en : sourceMixins.entrySet()) { _mixInAnnotations.put(new ClassKey(en.getKey()), en.getValue()); } } } /** * Method to use for adding mix-in annotations to use for augmenting * specified class or interface. All annotations from * mixinSource are taken to override annotations * that target (or its supertypes) has. * * @param target Class (or interface) whose annotations to effectively override * @param mixinSource Class (or interface) whose annotations are to * be "added" to target's annotations, overriding as necessary */ public final void addMixInAnnotations(Class target, Class mixinSource) { _mixInAnnotations.put(new ClassKey(target), mixinSource); } public final Class findMixInClassFor(Class cls) { return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls)); } public final int mixInCount() { return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size(); } /* /********************************************************** /* Configuration, introspection /********************************************************** */ /** * Method for accessing currently configured visibility checker; * object used for determining whether given property element * (method, field, constructor) can be auto-detected or not. */ public VisibilityChecker getVisibilityChecker() { return _serializationConfig.getDefaultVisibilityChecker(); } /** * Method for setting currently configured visibility checker; * object used for determining whether given property element * (method, field, constructor) can be auto-detected or not. * This default checker is used if no per-class overrides * are defined. */ public void setVisibilityChecker(VisibilityChecker vc) { _deserializationConfig = _deserializationConfig.with(vc); _serializationConfig = _serializationConfig.with(vc); } /** * Convenience method that allows changing configuration for * underlying {@link VisibilityChecker}s, to change details of what kinds of * properties are auto-detected. * Basically short cut for doing: *

     *  mapper.setVisibilityChecker(
     *     mapper.getVisibilityChecker().withVisibility(forMethod, visibility)
     *  );
     *
* one common use case would be to do: *
     *  mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);
     *
* which would make all member fields serializable without further annotations, * instead of just public fields (default setting). * * @param forMethod Type of property descriptor affected (field, getter/isGetter, * setter, creator) * @param visibility Minimum visibility to require for the property descriptors of type * * @return Modified mapper instance (that is, "this"), to allow chaining * of configuration calls */ public ObjectMapper setVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { _deserializationConfig = _deserializationConfig.withVisibility(forMethod, visibility); _serializationConfig = _serializationConfig.withVisibility(forMethod, visibility); return this; } /** * Method for accessing subtype resolver in use. */ public SubtypeResolver getSubtypeResolver() { return _subtypeResolver; } /** * Method for setting custom subtype resolver to use. */ public ObjectMapper setSubtypeResolver(SubtypeResolver str) { _subtypeResolver = str; _deserializationConfig = _deserializationConfig.with(str); _serializationConfig = _serializationConfig.with(str); return this; } /** * Method for changing {@link AnnotationIntrospector} used by this * mapper instance for both serialization and deserialization */ public ObjectMapper setAnnotationIntrospector(AnnotationIntrospector ai) { _serializationConfig = _serializationConfig.with(ai); _deserializationConfig = _deserializationConfig.with(ai); return this; } /** * Method for changing {@link AnnotationIntrospector} instances used * by this mapper instance for serialization and deserialization, * specifying them separately so that different introspection can be * used for different aspects * * @since 2.1 * * @param serializerAI {@link AnnotationIntrospector} to use for configuring * serialization * @param deserializerAI {@link AnnotationIntrospector} to use for configuring * deserialization */ public ObjectMapper setAnnotationIntrospectors(AnnotationIntrospector serializerAI, AnnotationIntrospector deserializerAI) { _serializationConfig = _serializationConfig.with(serializerAI); _deserializationConfig = _deserializationConfig.with(deserializerAI); return this; } /** * Method for setting custom property naming strategy to use. */ public ObjectMapper setPropertyNamingStrategy(PropertyNamingStrategy s) { _serializationConfig = _serializationConfig.with(s); _deserializationConfig = _deserializationConfig.with(s); return this; } /** * Method for setting defalt POJO property inclusion strategy for serialization. */ public ObjectMapper setSerializationInclusion(JsonInclude.Include incl) { _serializationConfig = _serializationConfig.withSerializationInclusion(incl); return this; } /* /********************************************************** /* Type information configuration (1.5+) /********************************************************** */ /** * Convenience method that is equivalent to calling *
     *  enableObjectTyping(DefaultTyping.OBJECT_AND_NON_CONCRETE);
     *
*/ public ObjectMapper enableDefaultTyping() { return enableDefaultTyping(DefaultTyping.OBJECT_AND_NON_CONCRETE); } /** * Convenience method that is equivalent to calling *
     *  enableObjectTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
     *
*/ public ObjectMapper enableDefaultTyping(DefaultTyping dti) { return enableDefaultTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY); } /** * Method for enabling automatic inclusion of type information, needed * for proper deserialization of polymorphic types (unless types * have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}). * * @param applicability Defines kinds of types for which additional type information * is added; see {@link DefaultTyping} for more information. */ public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInfo.As includeAs) { TypeResolverBuilder typer = new DefaultTypeResolverBuilder(applicability); // we'll always use full class name, when using defaulting typer = typer.init(JsonTypeInfo.Id.CLASS, null); typer = typer.inclusion(includeAs); return setDefaultTyping(typer); } /** * Method for enabling automatic inclusion of type information -- needed * for proper deserialization of polymorphic types (unless types * have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) -- * using "As.PROPERTY" inclusion mechanism and specified property name * to use for inclusion (default being "@class" since default type information * always uses class name as type identifier) */ public ObjectMapper enableDefaultTypingAsProperty(DefaultTyping applicability, String propertyName) { TypeResolverBuilder typer = new DefaultTypeResolverBuilder(applicability); // we'll always use full class name, when using defaulting typer = typer.init(JsonTypeInfo.Id.CLASS, null); typer = typer.inclusion(JsonTypeInfo.As.PROPERTY); typer = typer.typeProperty(propertyName); return setDefaultTyping(typer); } /** * Method for disabling automatic inclusion of type information; if so, only * explicitly annotated types (ones with * {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) will have * additional embedded type information. */ public ObjectMapper disableDefaultTyping() { return setDefaultTyping(null); } /** * Method for enabling automatic inclusion of type information, using * specified handler object for determining which types this affects, * as well as details of how information is embedded. * * @param typer Type information inclusion handler */ public ObjectMapper setDefaultTyping(TypeResolverBuilder typer) { _deserializationConfig = _deserializationConfig.with(typer); _serializationConfig = _serializationConfig.with(typer); return this; } /** * Method for registering specified class as a subtype, so that * typename-based resolution can link supertypes to subtypes * (as an alternative to using annotations). * Type for given class is determined from appropriate annotation; * or if missing, default name (unqualified class name) */ public void registerSubtypes(Class... classes) { getSubtypeResolver().registerSubtypes(classes); } /** * Method for registering specified class as a subtype, so that * typename-based resolution can link supertypes to subtypes * (as an alternative to using annotations). * Name may be provided as part of argument, but if not will * be based on annotations or use default name (unqualified * class name). */ public void registerSubtypes(NamedType... types) { getSubtypeResolver().registerSubtypes(types); } /* /********************************************************** /* Configuration, basic type handling /********************************************************** */ /** * Accessor for getting currently configured {@link TypeFactory} instance. */ public TypeFactory getTypeFactory() { return _typeFactory; } /** * Method that can be used to override {@link TypeFactory} instance * used by this mapper. *

* Note: will also set {@link TypeFactory} that deserialization and * serialization config objects use. */ public ObjectMapper setTypeFactory(TypeFactory f) { _typeFactory = f; _deserializationConfig = _deserializationConfig.with(f); _serializationConfig = _serializationConfig.with(f); return this; } /** * Convenience method for constructing {@link JavaType} out of given * type (typically java.lang.Class), but without explicit * context. */ public JavaType constructType(Type t) { return _typeFactory.constructType(t); } /* /********************************************************** /* Configuration, deserialization /********************************************************** */ /** * Method for specifying {@link JsonNodeFactory} to use for * constructing root level tree nodes (via method * {@link #createObjectNode} */ public ObjectMapper setNodeFactory(JsonNodeFactory f) { _deserializationConfig = _deserializationConfig.with(f); return this; } /** * Method for adding specified {@link DeserializationProblemHandler} * to be used for handling specific problems during deserialization. */ public ObjectMapper addHandler(DeserializationProblemHandler h) { _deserializationConfig = _deserializationConfig.withHandler(h); return this; } /** * Method for removing all registered {@link DeserializationProblemHandler}s * instances from this mapper. */ public ObjectMapper clearProblemHandlers() { _deserializationConfig = _deserializationConfig.withNoProblemHandlers(); return this; } /* /********************************************************** /* Configuration, serialization /********************************************************** */ /** * Convenience method that is equivalent to: *

     *  mapper.setFilters(mapper.getSerializationConfig().withFilters(filterProvider));
     *
*

* Note that usually it is better to use method {@link #writer(FilterProvider)}; * however, sometimes * this method is more convenient. For example, some frameworks only allow configuring * of ObjectMapper instances and not ObjectWriters. */ public void setFilters(FilterProvider filterProvider) { _serializationConfig = _serializationConfig.withFilters(filterProvider); } /** * Method that will configure default {@link Base64Variant} that * byte[] serializers and deserializers will use. * * @param v Base64 variant to use * * @return This mapper, for convenience to allow chaining * * @since 2.1 */ public ObjectMapper setBase64Variant(Base64Variant v) { _serializationConfig = _serializationConfig.with(v); _deserializationConfig = _deserializationConfig.with(v); return this; } /* /********************************************************** /* Configuration, other /********************************************************** */ /** * Method that can be used to get hold of {@link JsonFactory} that this * mapper uses if it needs to construct {@link JsonParser}s * and/or {@link JsonGenerator}s. * * @return {@link JsonFactory} that this mapper uses when it needs to * construct Json parser and generators */ @Override public JsonFactory getFactory() { return _jsonFactory; } /** * @deprecated Since 2.1: Use {@link #getFactory} instead */ @Deprecated @Override public JsonFactory getJsonFactory() { return _jsonFactory; } /** * Method for configuring the default {@link DateFormat} to use when serializing time * values as Strings, and deserializing from JSON Strings. * This is preferably to directly modifying {@link SerializationConfig} and * {@link DeserializationConfig} instances. * If you need per-request configuration, use {@link #writer(DateFormat)} to * create properly configured {@link ObjectWriter} and use that; this because * {@link ObjectWriter}s are thread-safe whereas ObjectMapper itself is only * thread-safe when configuring methods (such as this one) are NOT called. */ public ObjectMapper setDateFormat(DateFormat dateFormat) { _deserializationConfig = _deserializationConfig.with(dateFormat); _serializationConfig = _serializationConfig.with(dateFormat); return this; } /** * Method for configuring {@link HandlerInstantiator} to use for creating * instances of handlers (such as serializers, deserializers, type and type * id resolvers), given a class. * * @param hi Instantiator to use; if null, use the default implementation */ public Object setHandlerInstantiator(HandlerInstantiator hi) { _deserializationConfig = _deserializationConfig.with(hi); _serializationConfig = _serializationConfig.with(hi); return this; } /** * Method for configuring {@link InjectableValues} which used to find * values to inject. */ public ObjectMapper setInjectableValues(InjectableValues injectableValues) { _injectableValues = injectableValues; return this; } /** * Method for overriding default locale to use for formatting. * Default value used is {@link Locale#getDefault()}. */ public ObjectMapper setLocale(Locale l) { _deserializationConfig = _deserializationConfig.with(l); _serializationConfig = _serializationConfig.with(l); return this; } /** * Method for overriding default TimeZone to use for formatting. * Default value used is {@link TimeZone#getDefault()}. */ public ObjectMapper setTimeZone(TimeZone tz) { _deserializationConfig = _deserializationConfig.with(tz); _serializationConfig = _serializationConfig.with(tz); return this; } /* /********************************************************** /* Configuration, simple features /********************************************************** */ /** * Method for changing state of an on/off mapper feature for * this mapper instance. */ public ObjectMapper configure(MapperFeature f, boolean state) { _serializationConfig = state ? _serializationConfig.with(f) : _serializationConfig.without(f); _deserializationConfig = state ? _deserializationConfig.with(f) : _deserializationConfig.without(f); return this; } /** * Method for changing state of an on/off serialization feature for * this object mapper. */ public ObjectMapper configure(SerializationFeature f, boolean state) { _serializationConfig = state ? _serializationConfig.with(f) : _serializationConfig.without(f); return this; } /** * Method for changing state of an on/off deserialization feature for * this object mapper. */ public ObjectMapper configure(DeserializationFeature f, boolean state) { _deserializationConfig = state ? _deserializationConfig.with(f) : _deserializationConfig.without(f); return this; } /** * Method for changing state of an on/off {@link JsonParser} feature for * {@link JsonFactory} instance this object mapper uses. *

* This is method is basically a shortcut method for calling * {@link JsonFactory#enable} on the shared * {@link JsonFactory} this mapper uses (which is accessible * using {@link #getJsonFactory}). */ public ObjectMapper configure(JsonParser.Feature f, boolean state) { _jsonFactory.configure(f, state); return this; } /** * Method for changing state of an on/off {@link JsonGenerator} feature for * {@link JsonFactory} instance this object mapper uses. *

* This is method is basically a shortcut method for calling * {@link JsonFactory#enable} on the shared * {@link JsonFactory} this mapper uses (which is accessible * using {@link #getJsonFactory}). */ public ObjectMapper configure(JsonGenerator.Feature f, boolean state) { _jsonFactory.configure(f, state); return this; } /** * Method for enabling specified {@link MapperConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper enable(MapperFeature... f) { _deserializationConfig = _deserializationConfig.with(f); _serializationConfig = _serializationConfig.with(f); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper disable(MapperFeature... f) { _deserializationConfig = _deserializationConfig.without(f); _serializationConfig = _serializationConfig.without(f); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper enable(DeserializationFeature feature) { _deserializationConfig = _deserializationConfig.with(feature); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper enable(DeserializationFeature first, DeserializationFeature... f) { _deserializationConfig = _deserializationConfig.with(first, f); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper disable(DeserializationFeature feature) { _deserializationConfig = _deserializationConfig.without(feature); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper disable(DeserializationFeature first, DeserializationFeature... f) { _deserializationConfig = _deserializationConfig.without(first, f); return this; } /** * Method for enabling specified {@link DeserializationConfig} feature. * Modifies and returns this instance; no new object is created. */ public ObjectMapper enable(SerializationFeature f) { _serializationConfig = _serializationConfig.with(f); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper enable(SerializationFeature first, SerializationFeature... f) { _serializationConfig = _serializationConfig.with(first, f); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper disable(SerializationFeature f) { _serializationConfig = _serializationConfig.without(f); return this; } /** * Method for enabling specified {@link DeserializationConfig} features. * Modifies and returns this instance; no new object is created. */ public ObjectMapper disable(SerializationFeature first, SerializationFeature... f) { _serializationConfig = _serializationConfig.without(first, f); return this; } /** * Method for checking whether given Mapper * feature is enabled. */ public boolean isEnabled(MapperFeature f) { // ok to use either one, should be kept in sync return _serializationConfig.isEnabled(f); } /** * Method for checking whether given serialization-specific * feature is enabled. */ public boolean isEnabled(SerializationFeature f) { return _serializationConfig.isEnabled(f); } /** * Method for checking whether given deserialization-specific * feature is enabled. */ public boolean isEnabled(DeserializationFeature f) { return _deserializationConfig.isEnabled(f); } /** * Convenience method, equivalent to: *

     *  getJsonFactory().isEnabled(f);
     *
*/ public boolean isEnabled(JsonFactory.Feature f) { return _jsonFactory.isEnabled(f); } /** * Convenience method, equivalent to: *
     *  getJsonFactory().isEnabled(f);
     *
*/ public boolean isEnabled(JsonParser.Feature f) { return _jsonFactory.isEnabled(f); } /** * Convenience method, equivalent to: *
     *  getJsonFactory().isEnabled(f);
     *
*/ public boolean isEnabled(JsonGenerator.Feature f) { return _jsonFactory.isEnabled(f); } /** * Method that can be used to get hold of {@link JsonNodeFactory} * that this mapper will use when directly constructing * root {@link JsonNode} instances for Trees. *

* Note: this is just a shortcut for calling *

     *   getDeserializationConfig().getNodeFactory()
     *
*/ public JsonNodeFactory getNodeFactory() { return _deserializationConfig.getNodeFactory(); } /* /********************************************************** /* Public API (from ObjectCodec): deserialization /* (mapping from JSON to Java types); /* main methods /********************************************************** */ /** * Method to deserialize JSON content into a non-container * type (it can be an array type, however): typically a bean, array * or a wrapper type (like {@link java.lang.Boolean}). *

* Note: this method should NOT be used if the result type is a * container ({@link java.util.Collection} or {@link java.util.Map}. * The reason is that due to type erasure, key and value types * can not be introspected when using this method. */ @Override @SuppressWarnings("unchecked") public T readValue(JsonParser jp, Class valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueType)); } /** * Method to deserialize JSON content into a Java type, reference * to which is passed as argument. Type is passed using so-called * "super type token" (see ) * and specifically needs to be used if the root type is a * parameterized (generic) container type. */ @Override @SuppressWarnings("unchecked") public T readValue(JsonParser jp, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueTypeRef)); } /** * Method to deserialize JSON content into a Java type, reference * to which is passed as argument. Type is passed using * Jackson specific type; instance of which can be constructed using * {@link TypeFactory}. */ @Override @SuppressWarnings("unchecked") public final T readValue(JsonParser jp, ResolvedType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, (JavaType) valueType); } /** * Type-safe overloaded method, basically alias for {@link #readValue(JsonParser, ResolvedType)}. */ @SuppressWarnings("unchecked") public T readValue(JsonParser jp, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, valueType); } /** * Method to deserialize JSON content as tree expressed * using set of {@link JsonNode} instances. Returns * root of the resulting tree (where root can consist * of just a single node if the current event is a * value event, not container). */ @Override public T readTree(JsonParser jp) throws IOException, JsonProcessingException { /* 02-Mar-2009, tatu: One twist; deserialization provider * will map JSON null straight into Java null. But what * we want to return is the "null node" instead. */ /* 05-Aug-2011, tatu: Also, must check for EOF here before * calling readValue(), since that'll choke on it otherwise */ DeserializationConfig cfg = getDeserializationConfig(); JsonToken t = jp.getCurrentToken(); if (t == null) { t = jp.nextToken(); if (t == null) { return null; } } JsonNode n = (JsonNode) _readValue(cfg, jp, JSON_NODE_TYPE); if (n == null) { n = getNodeFactory().nullNode(); } @SuppressWarnings("unchecked") T result = (T) n; return result; } /** * Method for reading sequence of Objects from parser stream. * Sequence can be either root-level "unwrapped" sequence (without surrounding * JSON array), or a sequence contained in a JSON Array. * In either case {@link JsonParser} must point to the first token of * the first element, OR not point to any token (in which case it is advanced * to the next token). This means, specifically, that for wrapped sequences, * parser MUST NOT point to the surrounding START_ARRAY but rather * to the token following it. *

* Note that {@link ObjectReader} has more complete set of variants. */ @Override public MappingIterator readValues(JsonParser jp, ResolvedType valueType) throws IOException, JsonProcessingException { return readValues(jp, (JavaType) valueType); } /** * Type-safe overloaded method, basically alias for {@link #readValues(JsonParser, ResolvedType)}. */ public MappingIterator readValues(JsonParser jp, JavaType valueType) throws IOException, JsonProcessingException { DeserializationConfig config = getDeserializationConfig(); DeserializationContext ctxt = createDeserializationContext(jp, config); JsonDeserializer deser = _findRootDeserializer(ctxt, valueType); // false -> do NOT close JsonParser (since caller passed it) return new MappingIterator(valueType, jp, ctxt, deser, false, null); } /** * Type-safe overloaded method, basically alias for {@link #readValues(JsonParser, ResolvedType)}. */ @Override public MappingIterator readValues(JsonParser jp, Class valueType) throws IOException, JsonProcessingException { return readValues(jp, _typeFactory.constructType(valueType)); } /** * Method for reading sequence of Objects from parser stream. */ @Override public MappingIterator readValues(JsonParser jp, TypeReference valueTypeRef) throws IOException, JsonProcessingException { return readValues(jp, _typeFactory.constructType(valueTypeRef)); } /* /********************************************************** /* Public API not included in ObjectCodec: deserialization /* (mapping from JSON to Java types) /********************************************************** */ /** * Method to deserialize JSON content as tree expressed * using set of {@link JsonNode} instances. * Returns root of the resulting tree (where root can consist * of just a single node if the current event is a * value event, not container). * * @param in Input stream used to read JSON content * for building the JSON tree. */ public JsonNode readTree(InputStream in) throws IOException, JsonProcessingException { JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(in), JSON_NODE_TYPE); return (n == null) ? NullNode.instance : n; } /** * Method to deserialize JSON content as tree expressed * using set of {@link JsonNode} instances. * Returns root of the resulting tree (where root can consist * of just a single node if the current event is a * value event, not container). * * @param r Reader used to read JSON content * for building the JSON tree. */ public JsonNode readTree(Reader r) throws IOException, JsonProcessingException { JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(r), JSON_NODE_TYPE); return (n == null) ? NullNode.instance : n; } /** * Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances. * Returns root of the resulting tree (where root can consist of just a single node if the current * event is a value event, not container). * * @param content JSON content to parse to build the JSON tree. */ public JsonNode readTree(String content) throws IOException, JsonProcessingException { JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(content), JSON_NODE_TYPE); return (n == null) ? NullNode.instance : n; } /** * Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances. * Returns root of the resulting tree (where root can consist of just a single node if the current * event is a value event, not container). * * @param content JSON content to parse to build the JSON tree. */ public JsonNode readTree(byte[] content) throws IOException, JsonProcessingException { JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(content), JSON_NODE_TYPE); return (n == null) ? NullNode.instance : n; } /** * Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances. * Returns root of the resulting tree (where root can consist of just a single node if the current * event is a value event, not container). * * @param file File of which contents to parse as JSON for building a tree instance */ public JsonNode readTree(File file) throws IOException, JsonProcessingException { JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(file), JSON_NODE_TYPE); return (n == null) ? NullNode.instance : n; } /** * Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances. * Returns root of the resulting tree (where root can consist of just a single node if the current * event is a value event, not container). * * @param source URL to use for fetching contents to parse as JSON for building a tree instance */ public JsonNode readTree(URL source) throws IOException, JsonProcessingException { JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(source), JSON_NODE_TYPE); return (n == null) ? NullNode.instance : n; } /* /********************************************************** /* Public API (from ObjectCodec): serialization /* (mapping from Java types to Json) /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, using provided {@link JsonGenerator}. */ @Override public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { SerializationConfig config = getSerializationConfig(); // 10-Aug-2012, tatu: as per [Issue#12], must handle indentation: if (config.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } if (config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseableValue(jgen, value, config); } else { _serializerProvider(config).serializeValue(jgen, value); if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } } } /** * Method to serialize given JSON Tree, using generator * provided. */ public void writeTree(JsonGenerator jgen, JsonNode rootNode) throws IOException, JsonProcessingException { SerializationConfig config = getSerializationConfig(); _serializerProvider(config).serializeValue(jgen, rootNode); if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } } /* /********************************************************** /* Public API (from ObjectCodec): Tree Model support /********************************************************** */ /** *

* Note: return type is co-variant, as basic ObjectCodec * abstraction can not refer to concrete node types (as it's * part of core package, whereas impls are part of mapper * package) */ @Override public ObjectNode createObjectNode() { return _deserializationConfig.getNodeFactory().objectNode(); } /** *

* Note: return type is co-variant, as basic ObjectCodec * abstraction can not refer to concrete node types (as it's * part of core package, whereas impls are part of mapper * package) */ @Override public ArrayNode createArrayNode() { return _deserializationConfig.getNodeFactory().arrayNode(); } /** * Method for constructing a {@link JsonParser} out of JSON tree * representation. * * @param n Root node of the tree that resulting parser will read from */ @Override public JsonParser treeAsTokens(TreeNode n) { return new TreeTraversingParser((JsonNode) n, this); } /** * Convenience conversion method that will bind data given JSON tree * contains into specific value (usually bean) type. *

* Equivalent to: *

     *   objectMapper.convertValue(n, valueClass);
     *
*/ @SuppressWarnings("unchecked") @Override public T treeToValue(TreeNode n, Class valueType) throws JsonProcessingException { try { // [Issue-11]: Simple cast when we just want to cast to, say, ObjectNode // ... one caveat; while everything is Object.class, let's not take shortcut if (valueType != Object.class && valueType.isAssignableFrom(n.getClass())) { return (T) n; } return readValue(treeAsTokens(n), valueType); } catch (JsonProcessingException e) { throw e; } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } } /** * Reverse of {@link #treeToValue}; given a value (usually bean), will * construct equivalent JSON Tree representation. Functionally same * as if serializing value into JSON and parsing JSON as tree, but * more efficient. * * @param Actual node type; usually either basic {@link JsonNode} or * {@link com.fasterxml.jackson.databind.node.ObjectNode} * @param fromValue Bean value to convert * @return Root node of the resulting JSON tree */ @SuppressWarnings("unchecked") public T valueToTree(Object fromValue) throws IllegalArgumentException { if (fromValue == null) return null; TokenBuffer buf = new TokenBuffer(this); JsonNode result; try { writeValue(buf, fromValue); JsonParser jp = buf.asParser(); result = readTree(jp); jp.close(); } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } return (T) result; } /* /********************************************************** /* Extended Public API, accessors /********************************************************** */ /** * Method that can be called to check whether mapper thinks * it could serialize an instance of given Class. * Check is done * by checking whether a serializer can be found for the type. * * @return True if mapper can find a serializer for instances of * given class (potentially serializable), false otherwise (not * serializable) */ public boolean canSerialize(Class type) { return _serializerProvider(getSerializationConfig()).hasSerializerFor(type); } /** * Method that can be called to check whether mapper thinks * it could deserialize an Object of given type. * Check is done * by checking whether a deserializer can be found for the type. * * @return True if mapper can find a serializer for instances of * given class (potentially serializable), false otherwise (not * serializable) */ public boolean canDeserialize(JavaType type) { return createDeserializationContext(null, getDeserializationConfig()).hasValueDeserializerFor(type); } /* /********************************************************** /* Extended Public API, deserialization, /* convenience methods /********************************************************** */ @SuppressWarnings("unchecked") public T readValue(File src, Class valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public T readValue(File src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public T readValue(File src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public T readValue(URL src, Class valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public T readValue(URL src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public T readValue(URL src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public T readValue(String content, Class valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public T readValue(String content, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public T readValue(String content, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(content), valueType); } @SuppressWarnings("unchecked") public T readValue(Reader src, Class valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public T readValue(Reader src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public T readValue(Reader src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public T readValue(InputStream src, Class valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public T readValue(InputStream src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public T readValue(InputStream src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public T readValue(byte[] src, Class valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings("unchecked") public T readValue(byte[] src, int offset, int len, Class valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public T readValue(byte[] src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public T readValue(byte[] src, int offset, int len, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public T readValue(byte[] src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public T readValue(byte[] src, int offset, int len, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), valueType); } /* /********************************************************** /* Extended Public API: serialization /* (mapping from Java types to JSON) /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, written to File provided. */ public void writeValue(File resultFile, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(resultFile, JsonEncoding.UTF8), value); } /** * Method that can be used to serialize any Java value as * JSON output, using output stream provided (using encoding * {@link JsonEncoding#UTF8}). *

* Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(OutputStream out, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(out, JsonEncoding.UTF8), value); } /** * Method that can be used to serialize any Java value as * JSON output, using Writer provided. *

* Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(Writer w, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(w), value); } /** * Method that can be used to serialize any Java value as * a String. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.StringWriter} * and constructing String, but more efficient. *

* Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ public String writeValueAsString(Object value) throws JsonProcessingException { // alas, we have to pull the recycler directly here... SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler()); try { _configAndWriteValue(_jsonFactory.createGenerator(sw), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException.fromUnexpectedIOE(e); } return sw.getAndClear(); } /** * Method that can be used to serialize any Java value as * a byte array. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.ByteArrayOutputStream} * and getting bytes, but more efficient. * Encoding used will be UTF-8. *

* Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ public byte[] writeValueAsBytes(Object value) throws JsonProcessingException { ByteArrayBuilder bb = new ByteArrayBuilder(_jsonFactory._getBufferRecycler()); try { _configAndWriteValue(_jsonFactory.createGenerator(bb, JsonEncoding.UTF8), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException.fromUnexpectedIOE(e); } byte[] result = bb.toByteArray(); bb.release(); return result; } /* /********************************************************** /* Extended Public API: constructing ObjectWriters /* for more advanced configuration /********************************************************** */ /** * Convenience method for constructing {@link ObjectWriter} * with default settings. */ public ObjectWriter writer() { return new ObjectWriter(this, getSerializationConfig()); } /** * Factory method for constructing {@link ObjectWriter} with * specified feature enabled (compared to settings that this * mapper instance has). */ public ObjectWriter writer(SerializationFeature feature) { return new ObjectWriter(this, getSerializationConfig().with(feature)); } /** * Factory method for constructing {@link ObjectWriter} with * specified features enabled (compared to settings that this * mapper instance has). */ public ObjectWriter writer(SerializationFeature first, SerializationFeature... other) { return new ObjectWriter(this, getSerializationConfig().with(first, other)); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified {@link DateFormat}; or, if * null passed, using timestamp (64-bit number. */ public ObjectWriter writer(DateFormat df) { return new ObjectWriter(this, getSerializationConfig().with(df)); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified JSON View (filter). */ public ObjectWriter writerWithView(Class serializationView) { return new ObjectWriter(this, getSerializationConfig().withView(serializationView)); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified root type, instead of actual * runtime type of value. Type must be a super-type of runtime * type. */ public ObjectWriter writerWithType(Class rootType) { return new ObjectWriter(this, getSerializationConfig(), // 15-Mar-2013, tatu: Important! Indicate that static typing is needed: ((rootType == null) ? null :_typeFactory.constructType(rootType)), /*PrettyPrinter*/null); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified root type, instead of actual * runtime type of value. Type must be a super-type of runtime type. */ public ObjectWriter writerWithType(TypeReference rootType) { return new ObjectWriter(this, getSerializationConfig(), // 15-Mar-2013, tatu: Important! Indicate that static typing is needed: ((rootType == null) ? null : _typeFactory.constructType(rootType)), /*PrettyPrinter*/null); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified root type, instead of actual * runtime type of value. Type must be a super-type of runtime type. */ public ObjectWriter writerWithType(JavaType rootType) { return new ObjectWriter(this, getSerializationConfig(), rootType, /*PrettyPrinter*/null); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified pretty printer for indentation * (or if null, no pretty printer) */ public ObjectWriter writer(PrettyPrinter pp) { if (pp == null) { // need to use a marker to indicate explicit disabling of pp pp = ObjectWriter.NULL_PRETTY_PRINTER; } return new ObjectWriter(this, getSerializationConfig(), /*root type*/ null, pp); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using the default pretty printer for indentation */ public ObjectWriter writerWithDefaultPrettyPrinter() { return new ObjectWriter(this, getSerializationConfig(), /*root type*/ null, _defaultPrettyPrinter()); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified filter provider. */ public ObjectWriter writer(FilterProvider filterProvider) { return new ObjectWriter(this, getSerializationConfig().withFilters(filterProvider)); } /** * Factory method for constructing {@link ObjectWriter} that will * pass specific schema object to {@link JsonGenerator} used for * writing content. * * @param schema Schema to pass to generator */ public ObjectWriter writer(FormatSchema schema) { _verifySchemaType(schema); return new ObjectWriter(this, getSerializationConfig(), schema); } /** * Factory method for constructing {@link ObjectWriter} that will * use specified Base64 encoding variant for Base64-encoded binary data. * * @since 2.1 */ public ObjectWriter writer(Base64Variant defaultBase64) { return new ObjectWriter(this, getSerializationConfig().with(defaultBase64)); } /* /********************************************************** /* Extended Public API: constructing ObjectReaders /* for more advanced configuration /********************************************************** */ /** * Factory method for constructing {@link ObjectReader} with * default settings. Note that the resulting instance is NOT usable as is, * without defining expected value type. */ public ObjectReader reader() { return new ObjectReader(this, getDeserializationConfig()) .with(_injectableValues); } /** * Factory method for constructing {@link ObjectReader} with * specified feature enabled (compared to settings that this * mapper instance has). * Note that the resulting instance is NOT usable as is, * without defining expected value type. */ public ObjectReader reader(DeserializationFeature feature) { return new ObjectReader(this, getDeserializationConfig().with(feature)); } /** * Factory method for constructing {@link ObjectReader} with * specified features enabled (compared to settings that this * mapper instance has). * Note that the resulting instance is NOT usable as is, * without defining expected value type. */ public ObjectReader reader(DeserializationFeature first, DeserializationFeature... other) { return new ObjectReader(this, getDeserializationConfig().with(first, other)); } /** * Factory method for constructing {@link ObjectReader} that will * update given Object (usually Bean, but can be a Collection or Map * as well, but NOT an array) with JSON data. Deserialization occurs * normally except that the root-level value in JSON is not used for * instantiating a new object; instead give updateable object is used * as root. * Runtime type of value object is used for locating deserializer, * unless overridden by other factory methods of {@link ObjectReader} */ public ObjectReader readerForUpdating(Object valueToUpdate) { JavaType t = _typeFactory.constructType(valueToUpdate.getClass()); return new ObjectReader(this, getDeserializationConfig(), t, valueToUpdate, null, _injectableValues); } /** * Factory method for constructing {@link ObjectReader} that will * read or update instances of specified type */ public ObjectReader reader(JavaType type) { return new ObjectReader(this, getDeserializationConfig(), type, null, null, _injectableValues); } /** * Factory method for constructing {@link ObjectReader} that will * read or update instances of specified type */ public ObjectReader reader(Class type) { return reader(_typeFactory.constructType(type)); } /** * Factory method for constructing {@link ObjectReader} that will * read or update instances of specified type */ public ObjectReader reader(TypeReference type) { return reader(_typeFactory.constructType(type)); } /** * Factory method for constructing {@link ObjectReader} that will * use specified {@link JsonNodeFactory} for constructing JSON trees. */ public ObjectReader reader(JsonNodeFactory f) { return new ObjectReader(this, getDeserializationConfig()).with(f); } /** * Factory method for constructing {@link ObjectReader} that will * pass specific schema object to {@link JsonParser} used for * reading content. * * @param schema Schema to pass to parser */ public ObjectReader reader(FormatSchema schema) { _verifySchemaType(schema); return new ObjectReader(this, getDeserializationConfig(), null, null, schema, _injectableValues); } /** * Factory method for constructing {@link ObjectReader} that will * use specified injectable values. * * @param injectableValues Injectable values to use */ public ObjectReader reader(InjectableValues injectableValues) { return new ObjectReader(this, getDeserializationConfig(), null, null, null, injectableValues); } /** * Factory method for constructing {@link ObjectReader} that will * deserialize objects using specified JSON View (filter). */ public ObjectReader readerWithView(Class view) { return new ObjectReader(this, getDeserializationConfig().withView(view)); } /** * Factory method for constructing {@link ObjectReader} that will * use specified Base64 encoding variant for Base64-encoded binary data. * * @since 2.1 */ public ObjectReader reader(Base64Variant defaultBase64) { return new ObjectReader(this, getDeserializationConfig().with(defaultBase64)); } /* /********************************************************** /* Extended Public API: convenience type conversion /********************************************************** */ /** * Convenience method for doing two-step conversion from given value, into * instance of given value type. This is functionality equivalent to first * serializing given value into JSON, then binding JSON data into value * of given type, but may be executed without fully serializing into * JSON. Same converters (serializers, deserializers) will be used as for * data binding, meaning same object mapper configuration works. * * @throws IllegalArgumentException If conversion fails due to incompatible type; * if so, root cause will contain underlying checked exception data binding * functionality threw */ @SuppressWarnings("unchecked") public T convertValue(Object fromValue, Class toValueType) throws IllegalArgumentException { // sanity check for null first: if (fromValue == null) return null; return (T) _convert(fromValue, _typeFactory.constructType(toValueType)); } @SuppressWarnings("unchecked") public T convertValue(Object fromValue, TypeReference toValueTypeRef) throws IllegalArgumentException { return (T) convertValue(fromValue, _typeFactory.constructType(toValueTypeRef)); } @SuppressWarnings("unchecked") public T convertValue(Object fromValue, JavaType toValueType) throws IllegalArgumentException { // sanity check for null first: if (fromValue == null) return null; return (T) _convert(fromValue, toValueType); } /** * Actual conversion implementation: instead of using existing read * and write methods, much of code is inlined. Reason for this is * that we must avoid wrapping/unwrapping both for efficiency and * for correctness. If wrapping/unwrapping is actually desired, * caller must use explicit writeValue and * readValue methods. */ protected Object _convert(Object fromValue, JavaType toValueType) throws IllegalArgumentException { // also, as per [Issue-11], consider case for simple cast /* But with caveats: one is that while everything is Object.class, we don't * want to "optimize" that out; and the other is that we also do not want * to lose conversions of generic types. */ Class targetType = toValueType.getRawClass(); if (targetType != Object.class && !toValueType.hasGenericTypes() && targetType.isAssignableFrom(fromValue.getClass())) { return fromValue; } /* Then use TokenBuffer, which is a JsonGenerator: * (see [JACKSON-175]) */ TokenBuffer buf = new TokenBuffer(this); try { // inlined 'writeValue' with minor changes: // first: disable wrapping when writing SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE); // no need to check for closing of TokenBuffer _serializerProvider(config).serializeValue(buf, fromValue); // then matching read, inlined 'readValue' with minor mods: final JsonParser jp = buf.asParser(); Object result; // ok to pass in existing feature flags; unwrapping handled by mapper final DeserializationConfig deserConfig = getDeserializationConfig(); JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { DeserializationContext ctxt = createDeserializationContext(jp, deserConfig); result = _findRootDeserializer(ctxt, toValueType).getNullValue(); } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = null; } else { // pointing to event other than null DeserializationContext ctxt = createDeserializationContext(jp, deserConfig); JsonDeserializer deser = _findRootDeserializer(ctxt, toValueType); // note: no handling of unwarpping result = deser.deserialize(jp, ctxt); } jp.close(); return result; } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } } /* /********************************************************** /* Extended Public API: JSON Schema generation /********************************************************** */ /** * Generate Json-schema * instance for specified class. * * @param t The class to generate schema for * @return Constructed JSON schema. */ @SuppressWarnings("deprecation") public com.fasterxml.jackson.databind.jsonschema.JsonSchema generateJsonSchema(Class t) throws JsonMappingException { return _serializerProvider(getSerializationConfig()).generateJsonSchema(t); } /** * Method for visiting type hierarchy for given type, using specified visitor. *

* This method can be used for things like * generating Json Schema * instance for specified type. * * @param type Type to generate schema for (possibly with generic signature) * * @since 2.1 */ public void acceptJsonFormatVisitor(Class type, JsonFormatVisitorWrapper visitor) throws JsonMappingException { acceptJsonFormatVisitor(_typeFactory.constructType(type), visitor); } /** * Method for visiting type hierarchy for given type, using specified visitor. * Visitation uses Serializer hierarchy and related properties *

* This method can be used for things like * generating Json Schema * instance for specified type. * * @param type Type to generate schema for (possibly with generic signature) * * @since 2.1 */ public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor) throws JsonMappingException { if (type == null) { throw new IllegalArgumentException("type must be provided"); } _serializerProvider(getSerializationConfig()).acceptJsonFormatVisitor(type, visitor); } /* /********************************************************** /* Internal methods for serialization, overridable /********************************************************** */ /** * Overridable helper method used for constructing * {@link SerializerProvider} to use for serialization. */ protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) { return _serializerProvider.createInstance(config, _serializerFactory); } /** * Helper method that should return default pretty-printer to * use for generators constructed by this mapper, when instructed * to use default pretty printer. */ protected PrettyPrinter _defaultPrettyPrinter() { return _defaultPrettyPrinter; } /** * Method called to configure the generator as necessary and then * call write functionality */ protected final void _configAndWriteValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { SerializationConfig cfg = getSerializationConfig(); // [JACKSON-96]: allow enabling pretty printing for ObjectMapper directly if (cfg.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } // [JACKSON-282]: consider Closeable if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _configAndWriteCloseable(jgen, value, cfg); return; } boolean closed = false; try { _serializerProvider(cfg).serializeValue(jgen, value); closed = true; jgen.close(); } finally { /* won't try to close twice; also, must catch exception (so it * will not mask exception that is pending) */ if (!closed) { try { jgen.close(); } catch (IOException ioe) { } } } } protected final void _configAndWriteValue(JsonGenerator jgen, Object value, Class viewClass) throws IOException, JsonGenerationException, JsonMappingException { SerializationConfig cfg = getSerializationConfig().withView(viewClass); if (cfg.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } // [JACKSON-282]: consider Closeable if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _configAndWriteCloseable(jgen, value, cfg); return; } boolean closed = false; try { _serializerProvider(cfg).serializeValue(jgen, value); closed = true; jgen.close(); } finally { if (!closed) { try { jgen.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its close() * method is to be called right after serialization has been called */ private final void _configAndWriteCloseable(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { _serializerProvider(cfg).serializeValue(jgen, value); JsonGenerator tmpJgen = jgen; jgen = null; tmpJgen.close(); Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { /* Need to close both generator and value, as long as they haven't yet * been closed */ if (jgen != null) { try { jgen.close(); } catch (IOException ioe) { } } if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its close() * method is to be called right after serialization has been called */ private final void _writeCloseableValue(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { _serializerProvider(cfg).serializeValue(jgen, value); if (cfg.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /* /********************************************************** /* Internal methods for deserialization, overridable /********************************************************** */ /** * Internal helper method called to create an instance of {@link DeserializationContext} * for deserializing a single root value. * Can be overridden if a custom context is needed. */ protected DefaultDeserializationContext createDeserializationContext(JsonParser jp, DeserializationConfig cfg) { return _deserializationContext.createInstance(cfg, jp, _injectableValues); } /** * Actual implementation of value reading+binding operation. */ protected Object _readValue(DeserializationConfig cfg, JsonParser jp, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { /* First: may need to read the next token, to initialize * state (either before first read from parser, or after * previous token has been cleared) */ Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { // [JACKSON-643]: Ask JsonDeserializer what 'null value' to use: DeserializationContext ctxt = createDeserializationContext(jp, cfg); result = _findRootDeserializer(ctxt, valueType).getNullValue(); } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = null; } else { // pointing to event other than null DeserializationContext ctxt = createDeserializationContext(jp, cfg); JsonDeserializer deser = _findRootDeserializer(ctxt, valueType); // ok, let's get the value if (cfg.useRootWrapping()) { result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser); } else { result = deser.deserialize(jp, ctxt); } } // Need to consume the token too jp.clearCurrentToken(); return result; } protected Object _readMapAndClose(JsonParser jp, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { try { Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { // [JACKSON-643]: Ask JsonDeserializer what 'null value' to use: DeserializationContext ctxt = createDeserializationContext(jp, getDeserializationConfig()); result = _findRootDeserializer(ctxt, valueType).getNullValue(); } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = null; } else { DeserializationConfig cfg = getDeserializationConfig(); DeserializationContext ctxt = createDeserializationContext(jp, cfg); JsonDeserializer deser = _findRootDeserializer(ctxt, valueType); if (cfg.useRootWrapping()) { result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser); } else { result = deser.deserialize(jp, ctxt); } } // Need to consume the token too jp.clearCurrentToken(); return result; } finally { try { jp.close(); } catch (IOException ioe) { } } } /** * Method called to ensure that given parser is ready for reading * content for data binding. * * @return First token to be used for data binding after this call: * can never be null as exception will be thrown if parser can not * provide more tokens. * * @throws IOException if the underlying input source has problems during * parsing * @throws JsonParseException if parser has problems parsing content * @throws JsonMappingException if the parser does not have any more * content to map (note: Json "null" value is considered content; * enf-of-stream not) */ protected JsonToken _initForReading(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { /* First: must point to a token; if not pointing to one, advance. * This occurs before first read from JsonParser, as well as * after clearing of current token. */ JsonToken t = jp.getCurrentToken(); if (t == null) { // and then we must get something... t = jp.nextToken(); if (t == null) { /* [JACKSON-546] Throw mapping exception, since it's failure to map, * not an actual parsing problem */ throw JsonMappingException.from(jp, "No content to map due to end-of-input"); } } return t; } protected Object _unwrapAndDeserialize(JsonParser jp, DeserializationContext ctxt, DeserializationConfig config, JavaType rootType, JsonDeserializer deser) throws IOException, JsonParseException, JsonMappingException { String expName = config.getRootName(); if (expName == null) { SerializedString sstr = _rootNames.findRootName(rootType, config); expName = sstr.getValue(); } if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw JsonMappingException.from(jp, "Current token not START_OBJECT (needed to unwrap root name '" +expName+"'), but "+jp.getCurrentToken()); } if (jp.nextToken() != JsonToken.FIELD_NAME) { throw JsonMappingException.from(jp, "Current token not FIELD_NAME (to contain expected root name '" +expName+"'), but "+jp.getCurrentToken()); } String actualName = jp.getCurrentName(); if (!expName.equals(actualName)) { throw JsonMappingException.from(jp, "Root name '"+actualName+"' does not match expected ('" +expName+"') for type "+rootType); } // ok, then move to value itself.... jp.nextToken(); Object result = deser.deserialize(jp, ctxt); // and last, verify that we now get matching END_OBJECT if (jp.nextToken() != JsonToken.END_OBJECT) { throw JsonMappingException.from(jp, "Current token not END_OBJECT (to match wrapper object with root name '" +expName+"'), but "+jp.getCurrentToken()); } return result; } /* /********************************************************** /* Internal methods, other /********************************************************** */ /** * Method called to locate deserializer for the passed root-level value. */ protected JsonDeserializer _findRootDeserializer(DeserializationContext ctxt, JavaType valueType) throws JsonMappingException { // First: have we already seen it? JsonDeserializer deser = _rootDeserializers.get(valueType); if (deser != null) { return deser; } // Nope: need to ask provider to resolve it deser = ctxt.findRootValueDeserializer(valueType); if (deser == null) { // can this happen? throw new JsonMappingException("Can not find a deserializer for type "+valueType); } _rootDeserializers.put(valueType, deser); return deser; } /** * @since 2.2 */ protected void _verifySchemaType(FormatSchema schema) { if (schema != null) { if (!_jsonFactory.canUseSchema(schema)) { throw new IllegalArgumentException("Can not use FormatSchema of type "+schema.getClass().getName() +" for format "+_jsonFactory.getFormatName()); } } } } ObjectReader.java000066400000000000000000001555751215056657300336710ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.*; import java.net.URL; import java.util.Iterator; import java.util.Locale; import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.io.SerializedString; import com.fasterxml.jackson.core.type.ResolvedType; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.deser.DataFormatReaders; import com.fasterxml.jackson.databind.deser.DefaultDeserializationContext; import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.NullNode; import com.fasterxml.jackson.databind.node.TreeTraversingParser; import com.fasterxml.jackson.databind.type.SimpleType; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.RootNameLookup; /** * Builder object that can be used for per-serialization configuration of * deserialization parameters, such as root type to use or object * to update (instead of constructing new instance). *

* Uses "fluent" (or, kind of, builder) pattern so that instances are immutable * (and thus fully thread-safe with no external synchronization); * new instances are constructed for different configurations. * Instances are initially constructed by {@link ObjectMapper} and can be * reused, shared, cached; both because of thread-safety and because * instances are relatively light-weight. */ public class ObjectReader extends ObjectCodec implements Versioned, java.io.Serializable // since 2.1 { private static final long serialVersionUID = -4251443320039569153L; private final static JavaType JSON_NODE_TYPE = SimpleType.constructUnsafe(JsonNode.class); /* /********************************************************** /* Immutable configuration from ObjectMapper /********************************************************** */ /** * General serialization configuration settings; while immutable, * can use copy-constructor to create modified instances as necessary. */ protected final DeserializationConfig _config; /** * Blueprint instance of deserialization context; used for creating * actual instance when needed. */ protected final DefaultDeserializationContext _context; /** * Factory used for constructing {@link JsonGenerator}s */ protected final JsonFactory _jsonFactory; /** * Flag that indicates whether root values are expected to be unwrapped or not */ protected final boolean _unwrapRoot; /* /********************************************************** /* Configuration that can be changed during building /********************************************************** */ /** * Declared type of value to instantiate during deserialization. * Defines which deserializer to use; as well as base type of instance * to construct if an updatable value is not configured to be used * (subject to changes by embedded type information, for polymorphic * types). If {@link #_valueToUpdate} is non-null, only used for * locating deserializer. */ protected final JavaType _valueType; /** * We may pre-fetch deserializer as soon as {@link #_valueType} * is known, and if so, reuse it afterwards. * This allows avoiding further deserializer lookups and increases * performance a bit on cases where readers are reused. * * @since 2.1 */ protected final JsonDeserializer _rootDeserializer; /** * Instance to update with data binding; if any. If null, * a new instance is created, if non-null, properties of * this value object will be updated instead. * Note that value can be of almost any type, except not * {@link com.fasterxml.jackson.databind.type.ArrayType}; array * types can not be modified because array size is immutable. */ protected final Object _valueToUpdate; /** * When using data format that uses a schema, schema is passed * to parser. */ protected final FormatSchema _schema; /** * Values that can be injected during deserialization, if any. */ protected final InjectableValues _injectableValues; /** * Optional detector used for auto-detecting data format that byte-based * input uses. *

* NOTE: If defined non-null, readValue() methods that take * {@link Reader} or {@link String} input will fail with exception, * because format-detection only works on byte-sources. Also, if format * can not be detect reliably (as per detector settings), * a {@link JsonParseException} will be thrown). * * @since 2.1 */ protected final DataFormatReaders _dataFormatReaders; /* /********************************************************** /* Caching /********************************************************** */ /** * Root-level cached deserializers */ final protected ConcurrentHashMap> _rootDeserializers; /** * Cache for root names used when root-wrapping is enabled. */ protected final RootNameLookup _rootNames; /* /********************************************************** /* Life-cycle, construction /********************************************************** */ /** * Constructor used by {@link ObjectMapper} for initial instantiation */ protected ObjectReader(ObjectMapper mapper, DeserializationConfig config) { this(mapper, config, null, null, null, null); } /** * Constructor called when a root deserializer should be fetched based * on other configuration. */ protected ObjectReader(ObjectMapper mapper, DeserializationConfig config, JavaType valueType, Object valueToUpdate, FormatSchema schema, InjectableValues injectableValues) { _config = config; _context = mapper._deserializationContext; _rootDeserializers = mapper._rootDeserializers; _jsonFactory = mapper._jsonFactory; _rootNames = mapper._rootNames; _valueType = valueType; _valueToUpdate = valueToUpdate; if (valueToUpdate != null && valueType.isArrayType()) { throw new IllegalArgumentException("Can not update an array value"); } _schema = schema; _injectableValues = injectableValues; _unwrapRoot = config.useRootWrapping(); _rootDeserializer = _prefetchRootDeserializer(config, valueType); _dataFormatReaders = null; } /** * Copy constructor used for building variations. */ protected ObjectReader(ObjectReader base, DeserializationConfig config, JavaType valueType, JsonDeserializer rootDeser, Object valueToUpdate, FormatSchema schema, InjectableValues injectableValues, DataFormatReaders dataFormatReaders) { _config = config; _context = base._context; _rootDeserializers = base._rootDeserializers; _jsonFactory = base._jsonFactory; _rootNames = base._rootNames; _valueType = valueType; _rootDeserializer = rootDeser; _valueToUpdate = valueToUpdate; if (valueToUpdate != null && valueType.isArrayType()) { throw new IllegalArgumentException("Can not update an array value"); } _schema = schema; _injectableValues = injectableValues; _unwrapRoot = config.useRootWrapping(); _dataFormatReaders = dataFormatReaders; } /** * Copy constructor used when modifying simple feature flags */ protected ObjectReader(ObjectReader base, DeserializationConfig config) { _config = config; _context = base._context; _rootDeserializers = base._rootDeserializers; _jsonFactory = base._jsonFactory; _rootNames = base._rootNames; _valueType = base._valueType; _rootDeserializer = base._rootDeserializer; _valueToUpdate = base._valueToUpdate; _schema = base._schema; _injectableValues = base._injectableValues; _unwrapRoot = config.useRootWrapping(); _dataFormatReaders = base._dataFormatReaders; } protected ObjectReader(ObjectReader base, JsonFactory f) { _config = base._config; _context = base._context; _rootDeserializers = base._rootDeserializers; _jsonFactory = f; _rootNames = base._rootNames; _valueType = base._valueType; _rootDeserializer = base._rootDeserializer; _valueToUpdate = base._valueToUpdate; _schema = base._schema; _injectableValues = base._injectableValues; _unwrapRoot = base._unwrapRoot; _dataFormatReaders = base._dataFormatReaders; } /** * Method that will return version information stored in and read from jar * that contains this class. */ @Override public Version version() { return com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION; } /* /********************************************************** /* Life-cycle, fluent factory methods /********************************************************** */ public ObjectReader with(DeserializationConfig config) { return _with(config); } /** * Method for constructing a new reader instance that is configured * with specified feature enabled. */ public ObjectReader with(DeserializationFeature feature) { return _with(_config.with(feature)); } /** * Method for constructing a new reader instance that is configured * with specified features enabled. */ public ObjectReader with(DeserializationFeature first, DeserializationFeature... other) { return _with(_config.with(first, other)); } /** * Method for constructing a new reader instance that is configured * with specified features enabled. */ public ObjectReader withFeatures(DeserializationFeature... features) { return _with(_config.withFeatures(features)); } /** * Method for constructing a new reader instance that is configured * with specified feature disabled. */ public ObjectReader without(DeserializationFeature feature) { return _with(_config.without(feature)); } /** * Method for constructing a new reader instance that is configured * with specified features disabled. */ public ObjectReader without(DeserializationFeature first, DeserializationFeature... other) { return _with(_config.without(first, other)); } /** * Method for constructing a new reader instance that is configured * with specified features disabled. */ public ObjectReader withoutFeatures(DeserializationFeature... features) { return _with(_config.withoutFeatures(features)); } /** * Method for constructing a new instance with configuration that uses * passed {@link InjectableValues} to provide injectable values. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader with(InjectableValues injectableValues) { if (_injectableValues == injectableValues) { return this; } return new ObjectReader(this, _config, _valueType, _rootDeserializer, _valueToUpdate, _schema, injectableValues, _dataFormatReaders); } /** * Method for constructing a new reader instance with configuration that uses * passed {@link JsonNodeFactory} for constructing {@link JsonNode} * instances. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader with(JsonNodeFactory f) { return _with(_config.with(f)); } /** * Method for constructing a new reader instance with configuration that uses * passed {@link JsonFactory} for constructing underlying Readers. *

* NOTE: only factories that DO NOT REQUIRE SPECIAL MAPPERS * (that is, ones that return false for * {@link JsonFactory#requiresCustomCodec()}) can be used: trying * to use one that requires custom codec will throw exception * * @since 2.1 */ public ObjectReader with(JsonFactory f) { if (f == _jsonFactory) { return this; } ObjectReader r = new ObjectReader(this, f); // Also, try re-linking, if possible... if (f.getCodec() == null) { f.setCodec(r); } return r; } /** * Method for constructing a new instance with configuration that * specifies what root name to expect for "root name unwrapping". * See {@link DeserializationConfig#withRootName(String)} for * details. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader withRootName(String rootName) { return _with(_config.withRootName(rootName)); } /** * Method for constructing a new instance with configuration that * passes specified {@link FormatSchema} to {@link JsonParser} that * is constructed for parsing content. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader with(FormatSchema schema) { if (_schema == schema) { return this; } _verifySchemaType(schema); return new ObjectReader(this, _config, _valueType, _rootDeserializer, _valueToUpdate, schema, _injectableValues, _dataFormatReaders); } /** * Method for constructing a new reader instance that is configured * to data bind into specified type. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader withType(JavaType valueType) { if (valueType != null && valueType.equals(_valueType)) { return this; } JsonDeserializer rootDeser = _prefetchRootDeserializer(_config, valueType); // type is stored here, no need to make a copy of config DataFormatReaders det = _dataFormatReaders; if (det != null) { det = det.withType(valueType); } return new ObjectReader(this, _config, valueType, rootDeser, _valueToUpdate, _schema, _injectableValues, det); } /** * Method for constructing a new reader instance that is configured * to data bind into specified type. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader withType(Class valueType) { return withType(_config.constructType(valueType)); } /** * Method for constructing a new reader instance that is configured * to data bind into specified type. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader withType(java.lang.reflect.Type valueType) { return withType(_config.getTypeFactory().constructType(valueType)); } /** * Method for constructing a new reader instance that is configured * to data bind into specified type. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader withType(TypeReference valueTypeRef) { return withType(_config.getTypeFactory().constructType(valueTypeRef.getType())); } /** * Method for constructing a new instance with configuration that * updates passed Object (as root value), instead of constructing * a new value. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader withValueToUpdate(Object value) { if (value == _valueToUpdate) return this; if (value == null) { throw new IllegalArgumentException("cat not update null value"); } JavaType t; /* no real benefit from pre-fetching, as updating readers are much * less likely to be reused, and value type may also be forced * with a later chained call... */ if (_valueType == null) { t = _config.constructType(value.getClass()); } else { t = _valueType; } return new ObjectReader(this, _config, t, _rootDeserializer, value, _schema, _injectableValues, _dataFormatReaders); } /** * Method for constructing a new instance with configuration that * uses specified View for filtering. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectReader withView(Class activeView) { return _with(_config.withView(activeView)); } public ObjectReader with(Locale l) { return _with(_config.with(l)); } public ObjectReader with(TimeZone tz) { return _with(_config.with(tz)); } public ObjectReader withHandler(DeserializationProblemHandler h) { return _with(_config.withHandler(h)); } public ObjectReader with(Base64Variant defaultBase64) { return _with(_config.with(defaultBase64)); } /** * Fluent factory method for constructing a reader that will try to * auto-detect underlying data format, using specified list of * {@link JsonFactory} instances, and default {@link DataFormatReaders} settings * (for customized {@link DataFormatReaders}, you can construct instance yourself). * to construct appropriate {@link JsonParser} for actual parsing. *

* Note: since format detection only works with byte sources, it is possible to * get a failure from some 'readValue()' methods. Also, if input can not be reliably * (enough) detected as one of specified types, an exception will be thrown. *

* Note: not all {@link JsonFactory} types can be passed: specifically, ones that * require "custom codec" (like XML factory) will not work. Instead, use * method that takes {@link ObjectReader} instances instead of factories. * * @param readers Data formats accepted, in decreasing order of priority (that is, * matches checked in listed order, first match wins) * * @return Newly configured writer instance * * @since 2.1 */ public ObjectReader withFormatDetection(ObjectReader... readers) { return withFormatDetection(new DataFormatReaders(readers)); } /** * Fluent factory method for constructing a reader that will try to * auto-detect underlying data format, using specified * {@link DataFormatReaders}. *

* NOTE: since format detection only works with byte sources, it is possible to * get a failure from some 'readValue()' methods. Also, if input can not be reliably * (enough) detected as one of specified types, an exception will be thrown. * * @param readers DataFormatReaders to use for detecting underlying format. * * @return Newly configured writer instance * * @since 2.1 */ public ObjectReader withFormatDetection(DataFormatReaders readers) { return new ObjectReader(this, _config, _valueType, _rootDeserializer, _valueToUpdate, _schema, _injectableValues, readers); } /* /********************************************************** /* Simple accessors /********************************************************** */ public boolean isEnabled(DeserializationFeature f) { return _config.isEnabled(f); } public boolean isEnabled(MapperFeature f) { return _config.isEnabled(f); } public boolean isEnabled(JsonParser.Feature f) { return _jsonFactory.isEnabled(f); } /** * @since 2.2 */ public DeserializationConfig getConfig() { return _config; } /** * @since 2.1 */ @Override public JsonFactory getFactory() { return _jsonFactory; } /** * @deprecated Since 2.1: Use {@link #getFactory} instead */ @Deprecated @Override public JsonFactory getJsonFactory() { return _jsonFactory; } public TypeFactory getTypeFactory() { return _config.getTypeFactory(); } /* /********************************************************** /* Deserialization methods; basic ones to support ObjectCodec first /* (ones that take JsonParser) /********************************************************** */ /** * Method that binds content read using given parser, using * configuration of this reader, including expected result type. * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. *

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @SuppressWarnings("unchecked") public T readValue(JsonParser jp) throws IOException, JsonProcessingException { return (T) _bind(jp, _valueToUpdate); } /** * Convenience method that binds content read using given parser, using * configuration of this reader, except that expected value type * is specified with the call (instead of currently configured root type). * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. *

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @SuppressWarnings("unchecked") @Override public T readValue(JsonParser jp, Class valueType) throws IOException, JsonProcessingException { return (T) withType(valueType).readValue(jp); } /** * Convenience method that binds content read using given parser, using * configuration of this reader, except that expected value type * is specified with the call (instead of currently configured root type). * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. *

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @SuppressWarnings("unchecked") @Override public T readValue(JsonParser jp, TypeReference valueTypeRef) throws IOException, JsonProcessingException { return (T) withType(valueTypeRef).readValue(jp); } /** * Convenience method that binds content read using given parser, using * configuration of this reader, except that expected value type * is specified with the call (instead of currently configured root type). * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. *

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @Override @SuppressWarnings("unchecked") public T readValue(JsonParser jp, ResolvedType valueType) throws IOException, JsonProcessingException { return (T) withType((JavaType)valueType).readValue(jp); } /** * Type-safe overloaded method, basically alias for {@link #readValue(JsonParser, ResolvedType)}. *

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @SuppressWarnings("unchecked") public T readValue(JsonParser jp, JavaType valueType) throws IOException, JsonProcessingException { return (T) withType(valueType).readValue(jp); } /** * Convenience method that binds content read using given parser, using * configuration of this reader, except that content is bound as * JSON tree instead of configured root value type. *

* Note: if an object was specified with {@link #withValueToUpdate}, it * will be ignored. *

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @SuppressWarnings("unchecked") @Override public T readTree(JsonParser jp) throws IOException, JsonProcessingException { return (T) _bindAsTree(jp); } /** * Convenience method that is equivalent to: *

     *   withType(valueType).readValues(jp);
     *
*

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @Override public Iterator readValues(JsonParser jp, Class valueType) throws IOException, JsonProcessingException { return withType(valueType).readValues(jp); } /** * Convenience method that is equivalent to: *

     *   withType(valueTypeRef).readValues(jp);
     *
*

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @Override public Iterator readValues(JsonParser jp, TypeReference valueTypeRef) throws IOException, JsonProcessingException { return withType(valueTypeRef).readValues(jp); } /** * Convenience method that is equivalent to: *

     *   withType(valueType).readValues(jp);
     *
*

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ @Override public Iterator readValues(JsonParser jp, ResolvedType valueType) throws IOException, JsonProcessingException { return readValues(jp, (JavaType) valueType); } /** * Convenience method that is equivalent to: *

     *   withType(valueType).readValues(jp);
     *
*

* NOTE: this method never tries to auto-detect format, since actual * (data-format specific) parser is given. */ public Iterator readValues(JsonParser jp, JavaType valueType) throws IOException, JsonProcessingException { return withType(valueType).readValues(jp); } /* /********************************************************** /* Deserialization methods; others similar to what ObjectMapper has /********************************************************** */ /** * Method that binds content read from given input source, * using configuration of this reader. * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. */ @SuppressWarnings("unchecked") public T readValue(InputStream src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return (T) _detectBindAndClose(_dataFormatReaders.findFormat(src), false); } return (T) _bindAndClose(_jsonFactory.createParser(src), _valueToUpdate); } /** * Method that binds content read from given input source, * using configuration of this reader. * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. */ @SuppressWarnings("unchecked") public T readValue(Reader src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { _reportUndetectableSource(src); } return (T) _bindAndClose(_jsonFactory.createParser(src), _valueToUpdate); } /** * Method that binds content read from given JSON string, * using configuration of this reader. * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. */ @SuppressWarnings("unchecked") public T readValue(String src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { _reportUndetectableSource(src); } return (T) _bindAndClose(_jsonFactory.createParser(src), _valueToUpdate); } /** * Method that binds content read from given byte array, * using configuration of this reader. * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. */ @SuppressWarnings("unchecked") public T readValue(byte[] src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return (T) _detectBindAndClose(src, 0, src.length); } return (T) _bindAndClose(_jsonFactory.createParser(src), _valueToUpdate); } /** * Method that binds content read from given byte array, * using configuration of this reader. * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. */ @SuppressWarnings("unchecked") public T readValue(byte[] src, int offset, int length) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return (T) _detectBindAndClose(src, offset, length); } return (T) _bindAndClose(_jsonFactory.createParser(src, offset, length), _valueToUpdate); } @SuppressWarnings("unchecked") public T readValue(File src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true); } return (T) _bindAndClose(_jsonFactory.createParser(src), _valueToUpdate); } /** * Method that binds content read from given input source, * using configuration of this reader. * Value return is either newly constructed, or root value that * was specified with {@link #withValueToUpdate(Object)}. */ @SuppressWarnings("unchecked") public T readValue(URL src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true); } return (T) _bindAndClose(_jsonFactory.createParser(src), _valueToUpdate); } /** * Convenience method for converting results from given JSON tree into given * value type. Basically short-cut for: *

     *   objectReader.readValue(src.traverse())
     *
*/ @SuppressWarnings("unchecked") public T readValue(JsonNode src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { _reportUndetectableSource(src); } return (T) _bindAndClose(treeAsTokens(src), _valueToUpdate); } /** * Method that reads content from given input source, * using configuration of this reader, and binds it as JSON Tree. *

* Note that if an object was specified with a call to * {@link #withValueToUpdate(Object)} * it will just be ignored; result is always a newly constructed * {@link JsonNode} instance. */ public JsonNode readTree(InputStream in) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return _detectBindAndCloseAsTree(in); } return _bindAndCloseAsTree(_jsonFactory.createParser(in)); } /** * Method that reads content from given input source, * using configuration of this reader, and binds it as JSON Tree. *

* Note that if an object was specified with a call to * {@link #withValueToUpdate(Object)} * it will just be ignored; result is always a newly constructed * {@link JsonNode} instance. */ public JsonNode readTree(Reader r) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { _reportUndetectableSource(r); } return _bindAndCloseAsTree(_jsonFactory.createParser(r)); } /** * Method that reads content from given JSON input String, * using configuration of this reader, and binds it as JSON Tree. *

* Note that if an object was specified with a call to * {@link #withValueToUpdate(Object)} * it will just be ignored; result is always a newly constructed * {@link JsonNode} instance. */ public JsonNode readTree(String json) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { _reportUndetectableSource(json); } return _bindAndCloseAsTree(_jsonFactory.createParser(json)); } /* /********************************************************** /* Deserialization methods; reading sequence of values /********************************************************** */ /** * Method for reading sequence of Objects from parser stream. *

* Sequence can be either root-level "unwrapped" sequence (without surrounding * JSON array), or a sequence contained in a JSON Array. * In either case {@link JsonParser} must point to the first token of * the first element, OR not point to any token (in which case it is advanced * to the next token). This means, specifically, that for wrapped sequences, * parser MUST NOT point to the surrounding START_ARRAY but rather * to the token following it. */ public MappingIterator readValues(JsonParser jp) throws IOException, JsonProcessingException { DeserializationContext ctxt = createDeserializationContext(jp, _config); // false -> do not close as caller gave parser instance return new MappingIterator(_valueType, jp, ctxt, _findRootDeserializer(ctxt, _valueType), false, _valueToUpdate); } /** * Method for reading sequence of Objects from parser stream. *

* Sequence can be either wrapped or unwrapped root-level sequence: * wrapped means that the elements are enclosed in JSON Array; * and unwrapped that elements are directly accessed at main level. * Assumption is that iff the first token of the document is * START_ARRAY, we have a wrapped sequence; otherwise * unwrapped. For wrapped sequences, leading START_ARRAY * is skipped, so that for both cases, underlying {@link JsonParser} * will point to what is expected to be the first token of the first * element. *

* Note that the wrapped vs unwrapped logic means that it is NOT * possible to use this method for reading an unwrapped sequence * of elements written as JSON Arrays: to read such sequences, one * has to use {@link #readValues(JsonParser)}, making sure parser * points to the first token of the first element (i.e. the second * START_ARRAY which is part of the first element). */ public MappingIterator readValues(InputStream src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return _detectBindAndReadValues(_dataFormatReaders.findFormat(src), false); } return _bindAndReadValues(_jsonFactory.createParser(src), _valueToUpdate); } /** * Overloaded version of {@link #readValue(InputStream)}. */ public MappingIterator readValues(Reader src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { _reportUndetectableSource(src); } JsonParser jp = _jsonFactory.createParser(src); if (_schema != null) { jp.setSchema(_schema); } jp.nextToken(); DeserializationContext ctxt = createDeserializationContext(jp, _config); return new MappingIterator(_valueType, jp, ctxt, _findRootDeserializer(ctxt, _valueType), true, _valueToUpdate); } /** * Overloaded version of {@link #readValue(InputStream)}. * * @param json String that contains JSON content to parse */ public MappingIterator readValues(String json) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { _reportUndetectableSource(json); } JsonParser jp = _jsonFactory.createParser(json); if (_schema != null) { jp.setSchema(_schema); } jp.nextToken(); DeserializationContext ctxt = createDeserializationContext(jp, _config); return new MappingIterator(_valueType, jp, ctxt, _findRootDeserializer(ctxt, _valueType), true, _valueToUpdate); } /** * Overloaded version of {@link #readValue(InputStream)}. */ public MappingIterator readValues(byte[] src, int offset, int length) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return _detectBindAndReadValues(_dataFormatReaders.findFormat(src, offset, length), false); } return _bindAndReadValues(_jsonFactory.createParser(src), _valueToUpdate); } /** * Overloaded version of {@link #readValue(InputStream)}. */ public final MappingIterator readValues(byte[] src) throws IOException, JsonProcessingException { return readValues(src, 0, src.length); } /** * Overloaded version of {@link #readValue(InputStream)}. */ public MappingIterator readValues(File src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return _detectBindAndReadValues( _dataFormatReaders.findFormat(_inputStream(src)), false); } return _bindAndReadValues(_jsonFactory.createParser(src), _valueToUpdate); } /** * Overloaded version of {@link #readValue(InputStream)}. * * @param src URL to read to access JSON content to parse. */ public MappingIterator readValues(URL src) throws IOException, JsonProcessingException { if (_dataFormatReaders != null) { return _detectBindAndReadValues( _dataFormatReaders.findFormat(_inputStream(src)), true); } return _bindAndReadValues(_jsonFactory.createParser(src), _valueToUpdate); } /* /********************************************************** /* Implementation of rest of ObjectCodec methods /********************************************************** */ @Override public JsonNode createArrayNode() { return _config.getNodeFactory().arrayNode(); } @Override public JsonNode createObjectNode() { return _config.getNodeFactory().objectNode(); } @Override public JsonParser treeAsTokens(TreeNode n) { return new TreeTraversingParser((JsonNode) n, this); } @Override public T treeToValue(TreeNode n, Class valueType) throws JsonProcessingException { try { return readValue(treeAsTokens(n), valueType); } catch (JsonProcessingException e) { throw e; } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } } @Override public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonProcessingException { throw new UnsupportedOperationException("Not implemented for ObjectReader"); } /* /********************************************************** /* Helper methods, data-binding /********************************************************** */ /** * Actual implementation of value reading+binding operation. */ protected Object _bind(JsonParser jp, Object valueToUpdate) throws IOException, JsonParseException, JsonMappingException { /* First: may need to read the next token, to initialize state (either * before first read from parser, or after previous token has been cleared) */ Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { if (valueToUpdate == null) { DeserializationContext ctxt = createDeserializationContext(jp, _config); result = _findRootDeserializer(ctxt, _valueType).getNullValue(); } else { result = valueToUpdate; } } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = valueToUpdate; } else { // pointing to event other than null DeserializationContext ctxt = createDeserializationContext(jp, _config); JsonDeserializer deser = _findRootDeserializer(ctxt, _valueType); if (_unwrapRoot) { result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser); } else { if (valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, valueToUpdate); result = valueToUpdate; } } } // Need to consume the token too jp.clearCurrentToken(); return result; } protected Object _bindAndClose(JsonParser jp, Object valueToUpdate) throws IOException, JsonParseException, JsonMappingException { if (_schema != null) { jp.setSchema(_schema); } try { Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { if (valueToUpdate == null) { DeserializationContext ctxt = createDeserializationContext(jp, _config); result = _findRootDeserializer(ctxt, _valueType).getNullValue(); } else { result = valueToUpdate; } } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = valueToUpdate; } else { DeserializationContext ctxt = createDeserializationContext(jp, _config); JsonDeserializer deser = _findRootDeserializer(ctxt, _valueType); if (_unwrapRoot) { result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser); } else { if (valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, valueToUpdate); result = valueToUpdate; } } } return result; } finally { try { jp.close(); } catch (IOException ioe) { } } } protected JsonNode _bindAsTree(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { JsonNode result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL || t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = NullNode.instance; } else { DeserializationContext ctxt = createDeserializationContext(jp, _config); JsonDeserializer deser = _findRootDeserializer(ctxt, JSON_NODE_TYPE); if (_unwrapRoot) { result = (JsonNode) _unwrapAndDeserialize(jp, ctxt, JSON_NODE_TYPE, deser); } else { result = (JsonNode) deser.deserialize(jp, ctxt); } } // Need to consume the token too jp.clearCurrentToken(); return result; } protected JsonNode _bindAndCloseAsTree(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { if (_schema != null) { jp.setSchema(_schema); } try { return _bindAsTree(jp); } finally { try { jp.close(); } catch (IOException ioe) { } } } /** * @since 2.1 */ protected MappingIterator _bindAndReadValues(JsonParser p, Object valueToUpdate) throws IOException, JsonProcessingException { if (_schema != null) { p.setSchema(_schema); } p.nextToken(); DeserializationContext ctxt = createDeserializationContext(p, _config); return new MappingIterator(_valueType, p, ctxt, _findRootDeserializer(ctxt, _valueType), true, _valueToUpdate); } protected static JsonToken _initForReading(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { /* First: must point to a token; if not pointing to one, advance. * This occurs before first read from JsonParser, as well as * after clearing of current token. */ JsonToken t = jp.getCurrentToken(); if (t == null) { // and then we must get something... t = jp.nextToken(); if (t == null) { /* [JACKSON-546] Throw mapping exception, since it's failure to map, * not an actual parsing problem */ throw JsonMappingException.from(jp, "No content to map due to end-of-input"); } } return t; } /** * Method called to locate deserializer for the passed root-level value. */ protected JsonDeserializer _findRootDeserializer(DeserializationContext ctxt, JavaType valueType) throws JsonMappingException { if (_rootDeserializer != null) { return _rootDeserializer; } // Sanity check: must have actual type... if (valueType == null) { throw new JsonMappingException("No value type configured for ObjectReader"); } // First: have we already seen it? JsonDeserializer deser = _rootDeserializers.get(valueType); if (deser != null) { return deser; } // Nope: need to ask provider to resolve it deser = ctxt.findRootValueDeserializer(valueType); if (deser == null) { // can this happen? throw new JsonMappingException("Can not find a deserializer for type "+valueType); } _rootDeserializers.put(valueType, deser); return deser; } /** * Method called to locate deserializer ahead of time, if permitted * by configuration. Method also is NOT to throw an exception if * access fails. */ protected JsonDeserializer _prefetchRootDeserializer( DeserializationConfig config, JavaType valueType) { if (valueType == null || !_config.isEnabled(DeserializationFeature.EAGER_DESERIALIZER_FETCH)) { return null; } // already cached? JsonDeserializer deser = _rootDeserializers.get(valueType); if (deser == null) { try { // If not, need to resolve; for which we need a temporary context as well: DeserializationContext ctxt = createDeserializationContext(null, _config); deser = ctxt.findRootValueDeserializer(valueType); if (deser != null) { _rootDeserializers.put(valueType, deser); } return deser; } catch (JsonProcessingException e) { // need to swallow? } } return deser; } protected Object _unwrapAndDeserialize(JsonParser jp, DeserializationContext ctxt, JavaType rootType, JsonDeserializer deser) throws IOException, JsonParseException, JsonMappingException { String expName = _config.getRootName(); if (expName == null) { SerializedString sstr = _rootNames.findRootName(rootType, _config); expName = sstr.getValue(); } if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw JsonMappingException.from(jp, "Current token not START_OBJECT (needed to unwrap root name '" +expName+"'), but "+jp.getCurrentToken()); } if (jp.nextToken() != JsonToken.FIELD_NAME) { throw JsonMappingException.from(jp, "Current token not FIELD_NAME (to contain expected root name '" +expName+"'), but "+jp.getCurrentToken()); } String actualName = jp.getCurrentName(); if (!expName.equals(actualName)) { throw JsonMappingException.from(jp, "Root name '"+actualName+"' does not match expected ('" +expName+"') for type "+rootType); } // ok, then move to value itself.... jp.nextToken(); Object result; if (_valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, _valueToUpdate); result = _valueToUpdate; } // and last, verify that we now get matching END_OBJECT if (jp.nextToken() != JsonToken.END_OBJECT) { throw JsonMappingException.from(jp, "Current token not END_OBJECT (to match wrapper object with root name '" +expName+"'), but "+jp.getCurrentToken()); } return result; } /* /********************************************************** /* Internal methods, format auto-detection (since 2.1) /********************************************************** */ protected Object _detectBindAndClose(byte[] src, int offset, int length) throws IOException { DataFormatReaders.Match match = _dataFormatReaders.findFormat(src, offset, length); if (!match.hasMatch()) { _reportUnkownFormat(_dataFormatReaders, match); } JsonParser jp = match.createParserWithMatch(); return match.getReader()._bindAndClose(jp, _valueToUpdate); } protected Object _detectBindAndClose(DataFormatReaders.Match match, boolean forceClosing) throws IOException { if (!match.hasMatch()) { _reportUnkownFormat(_dataFormatReaders, match); } JsonParser p = match.createParserWithMatch(); // One more thing: we Own the input stream now; and while it's // not super clean way to do it, we must ensure closure so: if (forceClosing) { p.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE); } // important: use matching ObjectReader (may not be 'this') return match.getReader()._bindAndClose(p, _valueToUpdate); } protected MappingIterator _detectBindAndReadValues(DataFormatReaders.Match match, boolean forceClosing) throws IOException, JsonProcessingException { if (!match.hasMatch()) { _reportUnkownFormat(_dataFormatReaders, match); } JsonParser p = match.createParserWithMatch(); // One more thing: we Own the input stream now; and while it's // not super clean way to do it, we must ensure closure so: if (forceClosing) { p.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE); } // important: use matching ObjectReader (may not be 'this') return match.getReader()._bindAndReadValues(p, _valueToUpdate); } protected JsonNode _detectBindAndCloseAsTree(InputStream in) throws IOException { DataFormatReaders.Match match = _dataFormatReaders.findFormat(in); if (!match.hasMatch()) { _reportUnkownFormat(_dataFormatReaders, match); } JsonParser p = match.createParserWithMatch(); p.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE); return match.getReader()._bindAndCloseAsTree(p); } /** * Method called to indicate that format detection failed to detect format * of given input */ protected void _reportUnkownFormat(DataFormatReaders detector, DataFormatReaders.Match match) throws JsonProcessingException { throw new JsonParseException("Can not detect format from input, does not look like any of detectable formats " +detector.toString(), JsonLocation.NA); } /* /********************************************************** /* Internal methods, other /********************************************************** */ /** * @since 2.2 */ protected void _verifySchemaType(FormatSchema schema) { if (schema != null) { if (!_jsonFactory.canUseSchema(schema)) { throw new IllegalArgumentException("Can not use FormatSchema of type "+schema.getClass().getName() +" for format "+_jsonFactory.getFormatName()); } } } /** * Internal helper method called to create an instance of {@link DeserializationContext} * for deserializing a single root value. * Can be overridden if a custom context is needed. */ protected DefaultDeserializationContext createDeserializationContext(JsonParser jp, DeserializationConfig cfg) { // 04-Jan-2010, tatu: we do actually need the provider too... (for polymorphic deser) return _context.createInstance(cfg, jp, _injectableValues); } protected ObjectReader _with(DeserializationConfig newConfig) { if (newConfig == _config) { return this; } if (_dataFormatReaders != null) { return new ObjectReader(this, newConfig) .withFormatDetection(_dataFormatReaders.with(newConfig)); } return new ObjectReader(this, newConfig); } protected void _reportUndetectableSource(Object src) throws JsonProcessingException { throw new JsonParseException("Can not use source of type " +src.getClass().getName()+" with format auto-detection: must be byte- not char-based", JsonLocation.NA); } protected InputStream _inputStream(URL src) throws IOException { return src.openStream(); } protected InputStream _inputStream(File f) throws IOException { return new FileInputStream(f); } } ObjectWriter.java000066400000000000000000000671761215056657300337420ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.*; import java.text.DateFormat; import java.util.Locale; import java.util.TimeZone; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.io.SegmentedStringWriter; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.util.ByteArrayBuilder; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.fasterxml.jackson.core.util.Instantiatable; import com.fasterxml.jackson.core.util.MinimalPrettyPrinter; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.ser.SerializerFactory; import com.fasterxml.jackson.databind.type.TypeFactory; /** * Builder object that can be used for per-serialization configuration of * serialization parameters, such as JSON View and root type to use. * (and thus fully thread-safe with no external synchronization); * new instances are constructed for different configurations. * Instances are initially constructed by {@link ObjectMapper} and can be * reused in completely thread-safe manner with no explicit synchronization */ public class ObjectWriter implements Versioned, java.io.Serializable // since 2.1 { private static final long serialVersionUID = -7024829992408267532L; /** * We need to keep track of explicit disabling of pretty printing; * easiest to do by a token value. */ protected final static PrettyPrinter NULL_PRETTY_PRINTER = new MinimalPrettyPrinter(); /* /********************************************************** /* Immutable configuration from ObjectMapper /********************************************************** */ /** * General serialization configuration settings */ protected final SerializationConfig _config; protected final DefaultSerializerProvider _serializerProvider; protected final SerializerFactory _serializerFactory; /** * Factory used for constructing {@link JsonGenerator}s */ protected final JsonFactory _jsonFactory; /* /********************************************************** /* Configuration that can be changed during building /********************************************************** */ /** * Specified root serialization type to use; can be same * as runtime type, but usually one of its super types */ protected final JavaType _rootType; /** * We may pre-fetch serializer if {@link #_rootType} * is known, and if so, reuse it afterwards. * This allows avoiding further serializer lookups and increases * performance a bit on cases where readers are reused. * * @since 2.1 */ protected final JsonSerializer _rootSerializer; /** * To allow for dynamic enabling/disabling of pretty printing, * pretty printer can be optionally configured for writer * as well */ protected final PrettyPrinter _prettyPrinter; /** * When using data format that uses a schema, schema is passed * to generator. */ protected final FormatSchema _schema; /* /********************************************************** /* Life-cycle, constructors /********************************************************** */ /** * Constructor used by {@link ObjectMapper} for initial instantiation */ protected ObjectWriter(ObjectMapper mapper, SerializationConfig config, JavaType rootType, PrettyPrinter pp) { _config = config; _serializerProvider = mapper._serializerProvider; _serializerFactory = mapper._serializerFactory; _jsonFactory = mapper._jsonFactory; if (rootType != null) { rootType = rootType.withStaticTyping(); } _rootType = rootType; _prettyPrinter = pp; _schema = null; _rootSerializer = _prefetchRootSerializer(config, rootType); } /** * Alternative constructor for initial instantiation by {@link ObjectMapper} */ protected ObjectWriter(ObjectMapper mapper, SerializationConfig config) { _config = config; _serializerProvider = mapper._serializerProvider; _serializerFactory = mapper._serializerFactory; _jsonFactory = mapper._jsonFactory; _rootType = null; _rootSerializer = null; _prettyPrinter = null; _schema = null; } /** * Alternative constructor for initial instantiation by {@link ObjectMapper} */ protected ObjectWriter(ObjectMapper mapper, SerializationConfig config, FormatSchema s) { _config = config; _serializerProvider = mapper._serializerProvider; _serializerFactory = mapper._serializerFactory; _jsonFactory = mapper._jsonFactory; _rootType = null; _rootSerializer = null; _prettyPrinter = null; _schema = s; } /** * Copy constructor used for building variations. */ protected ObjectWriter(ObjectWriter base, SerializationConfig config, JavaType rootType, JsonSerializer rootSer, PrettyPrinter pp, FormatSchema s) { _config = config; _serializerProvider = base._serializerProvider; _serializerFactory = base._serializerFactory; _jsonFactory = base._jsonFactory; _rootType = rootType; _rootSerializer = rootSer; _prettyPrinter = pp; _schema = s; } /** * Copy constructor used for building variations. */ protected ObjectWriter(ObjectWriter base, SerializationConfig config) { _config = config; _serializerProvider = base._serializerProvider; _serializerFactory = base._serializerFactory; _jsonFactory = base._jsonFactory; _schema = base._schema; _rootType = base._rootType; _rootSerializer = base._rootSerializer; _prettyPrinter = base._prettyPrinter; } /** * Method that will return version information stored in and read from jar * that contains this class. */ @Override public Version version() { return com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION; } /* /********************************************************** /* Life-cycle, fluent factories /********************************************************** */ /** * Method for constructing a new instance that is configured * with specified feature enabled. */ public ObjectWriter with(SerializationFeature feature) { SerializationConfig newConfig = _config.with(feature); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method for constructing a new instance that is configured * with specified features enabled. */ public ObjectWriter with(SerializationFeature first, SerializationFeature... other) { SerializationConfig newConfig = _config.with(first, other); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method for constructing a new instance that is configured * with specified features enabled. */ public ObjectWriter withFeatures(SerializationFeature... features) { SerializationConfig newConfig = _config.withFeatures(features); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method for constructing a new instance that is configured * with specified feature enabled. */ public ObjectWriter without(SerializationFeature feature) { SerializationConfig newConfig = _config.without(feature); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method for constructing a new instance that is configured * with specified features enabled. */ public ObjectWriter without(SerializationFeature first, SerializationFeature... other) { SerializationConfig newConfig = _config.without(first, other); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method for constructing a new instance that is configured * with specified features enabled. */ public ObjectWriter withoutFeatures(SerializationFeature... features) { SerializationConfig newConfig = _config.withoutFeatures(features); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Fluent factory method that will construct a new writer instance that will * use specified date format for serializing dates; or if null passed, one * that will serialize dates as numeric timestamps. *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectWriter with(DateFormat df) { SerializationConfig newConfig = _config.with(df); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method that will construct a new instance that will use the default * pretty printer for serialization. */ public ObjectWriter withDefaultPrettyPrinter() { return with(new DefaultPrettyPrinter()); } /** * Method that will construct a new instance that uses specified * provider for resolving filter instances by id. */ public ObjectWriter with(FilterProvider filterProvider) { if (filterProvider == _config.getFilterProvider()) { // no change? return this; } return new ObjectWriter(this, _config.withFilters(filterProvider)); } /** * Method that will construct a new instance that will use specified pretty * printer (or, if null, will not do any pretty-printing) */ public ObjectWriter with(PrettyPrinter pp) { if (pp == _prettyPrinter) { return this; } // since null would mean "don't care", need to use placeholder to indicate "disable" if (pp == null) { pp = NULL_PRETTY_PRINTER; } return new ObjectWriter(this, _config, _rootType, _rootSerializer, pp, _schema); } /** * Method for constructing a new instance with configuration that * specifies what root name to use for "root element wrapping". * See {@link SerializationConfig#withRootName(String)} for details. *

* Note that method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectWriter withRootName(String rootName) { SerializationConfig newConfig = _config.withRootName(rootName); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method that will construct a new instance that uses specific format schema * for serialization. *

* Note that method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectWriter withSchema(FormatSchema schema) { if (_schema == schema) { return this; } _verifySchemaType(schema); return new ObjectWriter(this, _config, _rootType, _rootSerializer, _prettyPrinter, schema); } /** * Method that will construct a new instance that uses specific type * as the root type for serialization, instead of runtime dynamic * type of the root object itself. *

* Note that method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectWriter withType(JavaType rootType) { // 15-Mar-2013, tatu: Important! Indicate that static typing is needed: rootType = rootType.withStaticTyping(); JsonSerializer rootSer = _prefetchRootSerializer(_config, rootType); return new ObjectWriter(this, _config, rootType, rootSer, _prettyPrinter, _schema); } /** * Method that will construct a new instance that uses specific type * as the root type for serialization, instead of runtime dynamic * type of the root object itself. */ public ObjectWriter withType(Class rootType) { return withType(_config.constructType(rootType)); } public ObjectWriter withType(TypeReference rootType) { return withType(_config.getTypeFactory().constructType(rootType.getType())); } /** * Method that will construct a new instance that uses specified * serialization view for serialization (with null basically disables * view processing) *

* Note that the method does NOT change state of this reader, but * rather construct and returns a newly configured instance. */ public ObjectWriter withView(Class view) { SerializationConfig newConfig = _config.withView(view); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } public ObjectWriter with(Locale l) { SerializationConfig newConfig = _config.with(l); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } public ObjectWriter with(TimeZone tz) { SerializationConfig newConfig = _config.with(tz); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /** * Method that will construct a new instance that uses specified default * {@link Base64Variant} for base64 encoding * * @since 2.1 */ public ObjectWriter with(Base64Variant b64variant) { SerializationConfig newConfig = _config.with(b64variant); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); } /* /********************************************************** /* Simple accessors /********************************************************** */ public boolean isEnabled(SerializationFeature f) { return _config.isEnabled(f); } public boolean isEnabled(MapperFeature f) { return _config.isEnabled(f); } public boolean isEnabled(JsonParser.Feature f) { return _jsonFactory.isEnabled(f); } /** * @since 2.2 */ public SerializationConfig getConfig() { return _config; } /** * @deprecated Since 2.2, use {@link #getFactory} instead. */ @Deprecated public JsonFactory getJsonFactory() { return _jsonFactory; } /** * @since 2.2 */ public JsonFactory getFactory() { return _jsonFactory; } public TypeFactory getTypeFactory() { return _config.getTypeFactory(); } /** * Diagnostics method that can be called to check whether this writer * has pre-fetched serializer to use: pre-fetching improves performance * when writer instances are reused as it avoids a per-call serializer * lookup. * * @since 2.2 */ public boolean hasPrefetchedSerializer() { return _rootSerializer != null; } /* /********************************************************** /* Serialization methods; ones from ObjectCodec first /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, using provided {@link JsonGenerator}. */ public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { // 10-Aug-2012, tatu: As per [Issue#12], may need to force PrettyPrinter settings, so: _configureJsonGenerator(jgen); if (_config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseableValue(jgen, value, _config); } else { if (_rootType == null) { _serializerProvider(_config).serializeValue(jgen, value); } else { _serializerProvider(_config).serializeValue(jgen, value, _rootType, _rootSerializer); } if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } } } /* /********************************************************** /* Serialization methods, others /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, written to File provided. */ public void writeValue(File resultFile, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(resultFile, JsonEncoding.UTF8), value); } /** * Method that can be used to serialize any Java value as * JSON output, using output stream provided (using encoding * {@link JsonEncoding#UTF8}). *

* Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(OutputStream out, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(out, JsonEncoding.UTF8), value); } /** * Method that can be used to serialize any Java value as * JSON output, using Writer provided. *

* Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(Writer w, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(w), value); } /** * Method that can be used to serialize any Java value as * a String. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.StringWriter} * and constructing String, but more efficient. *

* Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ public String writeValueAsString(Object value) throws JsonProcessingException { // alas, we have to pull the recycler directly here... SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler()); try { _configAndWriteValue(_jsonFactory.createGenerator(sw), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException.fromUnexpectedIOE(e); } return sw.getAndClear(); } /** * Method that can be used to serialize any Java value as * a byte array. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.ByteArrayOutputStream} * and getting bytes, but more efficient. * Encoding used will be UTF-8. *

* Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ public byte[] writeValueAsBytes(Object value) throws JsonProcessingException { ByteArrayBuilder bb = new ByteArrayBuilder(_jsonFactory._getBufferRecycler()); try { _configAndWriteValue(_jsonFactory.createGenerator(bb, JsonEncoding.UTF8), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException.fromUnexpectedIOE(e); } byte[] result = bb.toByteArray(); bb.release(); return result; } /* /********************************************************** /* Other public methods /********************************************************** */ /** * Method for visiting type hierarchy for given type, using specified visitor. * Visitation uses Serializer hierarchy and related properties *

* This method can be used for things like * generating Json Schema * instance for specified type. * * @param type Type to generate schema for (possibly with generic signature) * * @since 2.2 */ public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor) throws JsonMappingException { if (type == null) { throw new IllegalArgumentException("type must be provided"); } _serializerProvider(_config).acceptJsonFormatVisitor(type, visitor); } public boolean canSerialize(Class type) { return _serializerProvider(_config).hasSerializerFor(type); } /* /********************************************************** /* Overridable helper methods /********************************************************** */ /** * Overridable helper method used for constructing * {@link SerializerProvider} to use for serialization. */ protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) { return _serializerProvider.createInstance(config, _serializerFactory); } /* /********************************************************** /* Internal methods /********************************************************** */ /** * @since 2.2 */ protected void _verifySchemaType(FormatSchema schema) { if (schema != null) { if (!_jsonFactory.canUseSchema(schema)) { throw new IllegalArgumentException("Can not use FormatSchema of type "+schema.getClass().getName() +" for format "+_jsonFactory.getFormatName()); } } } /** * Method called to configure the generator as necessary and then * call write functionality */ protected final void _configAndWriteValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configureJsonGenerator(jgen); // [JACKSON-282]: consider Closeable if (_config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseable(jgen, value, _config); return; } boolean closed = false; try { if (_rootType == null) { _serializerProvider(_config).serializeValue(jgen, value); } else { _serializerProvider(_config).serializeValue(jgen, value, _rootType, _rootSerializer); } closed = true; jgen.close(); } finally { /* won't try to close twice; also, must catch exception (so it * will not mask exception that is pending) */ if (!closed) { try { jgen.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its close() * method is to be called right after serialization has been called */ private final void _writeCloseable(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { if (_rootType == null) { _serializerProvider(cfg).serializeValue(jgen, value); } else { _serializerProvider(cfg).serializeValue(jgen, value, _rootType, _rootSerializer); } JsonGenerator tmpJgen = jgen; jgen = null; tmpJgen.close(); Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { /* Need to close both generator and value, as long as they haven't yet * been closed */ if (jgen != null) { try { jgen.close(); } catch (IOException ioe) { } } if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its close() * method is to be called right after serialization has been called */ private final void _writeCloseableValue(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { if (_rootType == null) { _serializerProvider(cfg).serializeValue(jgen, value); } else { _serializerProvider(cfg).serializeValue(jgen, value, _rootType, _rootSerializer); } if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /** * Method called to locate (root) serializer ahead of time, if permitted * by configuration. Method also is NOT to throw an exception if * access fails. */ protected JsonSerializer _prefetchRootSerializer( SerializationConfig config, JavaType valueType) { if (valueType == null || !_config.isEnabled(SerializationFeature.EAGER_SERIALIZER_FETCH)) { return null; } try { return _serializerProvider(config).findTypedValueSerializer(valueType, true, null); } catch (JsonProcessingException e) { // need to swallow? return null; } } /** * Helper method called to set or override settings of passed-in * {@link JsonGenerator} * * @since 2.1 */ private void _configureJsonGenerator(JsonGenerator jgen) { if (_prettyPrinter != null) { PrettyPrinter pp = _prettyPrinter; if (pp == NULL_PRETTY_PRINTER) { jgen.setPrettyPrinter(null); } else { /* [JACKSON-851]: Better take care of stateful PrettyPrinters... * like the DefaultPrettyPrinter. */ if (pp instanceof Instantiatable) { pp = (PrettyPrinter) ((Instantiatable) pp).createInstance(); } jgen.setPrettyPrinter(pp); } } else if (_config.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } // [JACKSON-520]: add support for pass-through schema: if (_schema != null) { jgen.setSchema(_schema); } } } PropertyName.java000066400000000000000000000120251215056657300337430ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; /** * Simple value class used for containing names of properties as defined * by annotations (and possibly other configuration sources). * * @since 2.1 */ public class PropertyName implements java.io.Serializable { private static final long serialVersionUID = 7930806520033045126L; private final static String _USE_DEFAULT = ""; private final static String _NO_NAME = "#disabled"; /** * Special placeholder value that indicates that name to use should be * based on the standard heuristics. This can be different from returning * null, as null means "no information available, whereas this value * indicates explicit defaulting. */ public final static PropertyName USE_DEFAULT = new PropertyName(_USE_DEFAULT, null); /** * Special placeholder value that indicates that there is no name associated. * Exact semantics to use (if any) depend on actual annotation in use, but * commonly this value disables behavior for which name would be needed. */ public final static PropertyName NO_NAME = new PropertyName(new String(_NO_NAME), null); /** * Basic name of the property. */ protected final String _simpleName; /** * Additional namespace, for formats that have such concept (JSON * does not, XML does, for example). */ protected final String _namespace; public PropertyName(String simpleName) { this(simpleName, null); } public PropertyName(String simpleName, String namespace) { _simpleName = (simpleName == null) ? "" : simpleName; _namespace = namespace; } // To support JDK serialization, recovery of Singleton instance protected Object readResolve() { if (_simpleName == null || _USE_DEFAULT.equals(_simpleName)) { return USE_DEFAULT; } if (_simpleName.equals(_NO_NAME)) { return NO_NAME; } return this; } public static PropertyName construct(String simpleName, String ns) { if (simpleName == null) { simpleName = ""; } if (ns == null && simpleName.length() == 0) { return USE_DEFAULT; } return new PropertyName(simpleName, ns); } /** * Fluent factory method for constructing an instance with different * simple name. */ public PropertyName withSimpleName(String simpleName) { if (simpleName == null) { simpleName = ""; } if (simpleName.equals(_simpleName)) { return this; } return new PropertyName(simpleName, _namespace); } /** * Fluent factory method for constructing an instance with different * namespace. */ public PropertyName withNamespace(String ns) { if (ns == null) { if (_namespace == null) { return this; } } else if (ns.equals(_namespace)) { return this; } return new PropertyName(_simpleName, ns); } /* /********************************************************** /* Accessors /********************************************************** */ public String getSimpleName() { return _simpleName; } public String getNamespace() { return _namespace; } public boolean hasSimpleName() { return _simpleName.length() > 0; } public boolean hasNamespace() { return _namespace != null; } /* /********************************************************** /* Std method overrides /********************************************************** */ @Override public boolean equals(Object o) { if (o == this) return true; if (o == null) return false; /* 13-Nov-2012, tatu: by default, require strict type equality. * Re-evaluate if this becomes an issue. */ if (o.getClass() != getClass()) return false; // 13-Nov-2012, tatu: Should we have specific rules on matching USE_DEFAULT? // (like, it only ever matching exact instance) // If we did, would need to check symmetrically; that is, if either 'this' // or 'o' was USE_DEFAULT, both would have to be. PropertyName other = (PropertyName) o; if (_simpleName == null) { if (other._simpleName != null) return false; } else if (!_simpleName.equals(other._simpleName)) { return false; } if (_namespace == null) { return (null == other._namespace); } return _namespace.equals(other._namespace); } @Override public int hashCode() { if (_namespace == null) { return _simpleName.hashCode(); } return _namespace.hashCode() ^ _simpleName.hashCode(); } @Override public String toString() { if (_namespace == null) { return _simpleName; } return "{"+_namespace + "}" + _simpleName; } } PropertyNamingStrategy.java000066400000000000000000000311331215056657300360200ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.AnnotatedField; import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.fasterxml.jackson.databind.introspect.AnnotatedParameter; /** * Class that defines how names of JSON properties ("external names") * are derived from names of POJO methods and fields ("internal names"), * in cases where they are not * auto-detected and no explicit annotations exist for naming. * Methods are passed information about POJO member for which name is needed, * as well as default name that would be used if no custom strategy was used. *

* Default implementation returns suggested ("default") name unmodified. *

* Note that the strategy is guaranteed to be called once per logical property * (which may be represented by multiple members; such as pair of a getter and * a setter), but may be called for each: implementations should not count on * exact number of times, and should work for any member that represent a * property. *

* In absence of a registered custom strategy, default Java property naming strategy * is used, which leaves field names as is, and removes set/get/is prefix * from methods (as well as lower-cases initial sequence of capitalized * characters). */ @SuppressWarnings("serial") public abstract class PropertyNamingStrategy implements java.io.Serializable { /* /********************************************************** /* API /********************************************************** */ /** * Method called to find external name (name used in JSON) for given logical * POJO property, * as defined by given field. * * @param config Configuration in used: either SerializationConfig * or DeserializationConfig, depending on whether method is called * during serialization or deserialization * @param field Field used to access property * @param defaultName Default name that would be used for property in absence of custom strategy * * @return Logical name to use for property that the field represents */ public String nameForField(MapperConfig config, AnnotatedField field, String defaultName) { return defaultName; } /** * Method called to find external name (name used in JSON) for given logical * POJO property, * as defined by given getter method; typically called when building a serializer. * (but not always -- when using "getter-as-setter", may be called during * deserialization) * * @param config Configuration in used: either SerializationConfig * or DeserializationConfig, depending on whether method is called * during serialization or deserialization * @param method Method used to access property. * @param defaultName Default name that would be used for property in absence of custom strategy * * @return Logical name to use for property that the method represents */ public String nameForGetterMethod(MapperConfig config, AnnotatedMethod method, String defaultName) { return defaultName; } /** * Method called to find external name (name used in JSON) for given logical * POJO property, * as defined by given setter method; typically called when building a deserializer * (but not necessarily only then). * * @param config Configuration in used: either SerializationConfig * or DeserializationConfig, depending on whether method is called * during serialization or deserialization * @param method Method used to access property. * @param defaultName Default name that would be used for property in absence of custom strategy * * @return Logical name to use for property that the method represents */ public String nameForSetterMethod(MapperConfig config, AnnotatedMethod method, String defaultName) { return defaultName; } /** * Method called to find external name (name used in JSON) for given logical * POJO property, * as defined by given constructor parameter; typically called when building a deserializer * (but not necessarily only then). * * @param config Configuration in used: either SerializationConfig * or DeserializationConfig, depending on whether method is called * during serialization or deserialization * @param ctorParam Constructor parameter used to pass property. * @param defaultName Default name that would be used for property in absence of custom strategy */ public String nameForConstructorParameter(MapperConfig config, AnnotatedParameter ctorParam, String defaultName) { return defaultName; } /* /********************************************************** /* Standard implementations /********************************************************** */ public static abstract class PropertyNamingStrategyBase extends PropertyNamingStrategy { @Override public String nameForField(MapperConfig config, AnnotatedField field, String defaultName) { return translate(defaultName); } @Override public String nameForGetterMethod(MapperConfig config, AnnotatedMethod method, String defaultName) { return translate(defaultName); } @Override public String nameForSetterMethod(MapperConfig config, AnnotatedMethod method, String defaultName) { return translate(defaultName); } @Override public String nameForConstructorParameter(MapperConfig config, AnnotatedParameter ctorParam, String defaultName) { return translate(defaultName); } public abstract String translate(String propertyName); } /* /********************************************************** /* Standard implementations /********************************************************** */ /** * See {@link LowerCaseWithUnderscoresStrategy} for details. */ public static final PropertyNamingStrategy CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES = new LowerCaseWithUnderscoresStrategy(); /** * A {@link PropertyNamingStrategy} that translates typical camel case Java * property names to lower case JSON element names, separated by * underscores. This implementation is somewhat lenient, in that it * provides some additional translations beyond strictly translating from * camel case only. In particular, the following translations are applied * by this PropertyNamingStrategy. * *

  • Every upper case letter in the Java property name is translated * into two characters, an underscore and the lower case equivalent of the * target character, with three exceptions. *
    1. For contiguous sequences of upper case letters, characters after * the first character are replaced only by their lower case equivalent, * and are not preceded by an underscore. *
      • This provides for reasonable translations of upper case acronyms, * e.g., "theWWW" is translated to "the_www".
    2. *
    3. An upper case character in the first position of the Java property * name is not preceded by an underscore character, and is translated only * to its lower case equivalent. *
      • For example, "Results" is translated to "results", * and not to "_results".
    4. *
    5. An upper case character in the Java property name that is already * preceded by an underscore character is translated only to its lower case * equivalent, and is not preceded by an additional underscore. *
      • For example, "user_Name" is translated to * "user_name", and not to "user__name" (with two * underscore characters).
  • *
  • If the Java property name starts with an underscore, then that * underscore is not included in the translated name, unless the Java * property name is just one character in length, i.e., it is the * underscore character. This applies only to the first character of the * Java property name.
* * These rules result in the following additional example translations from * Java property names to JSON element names. *
  • "userName" is translated to "user_name"
  • *
  • "UserName" is translated to "user_name"
  • *
  • "USER_NAME" is translated to "user_name"
  • *
  • "user_name" is translated to "user_name" (unchanged)
  • *
  • "user" is translated to "user" (unchanged)
  • *
  • "User" is translated to "user"
  • *
  • "USER" is translated to "user"
  • *
  • "_user" is translated to "user"
  • *
  • "_User" is translated to "user"
  • *
  • "__user" is translated to "_user" * (the first of two underscores was removed)
  • *
  • "user__name" is translated to "user__name" * (unchanged, with two underscores)
*/ public static class LowerCaseWithUnderscoresStrategy extends PropertyNamingStrategyBase { @Override public String translate(String input) { if (input == null) return input; // garbage in, garbage out int length = input.length(); StringBuilder result = new StringBuilder(length * 2); int resultLength = 0; boolean wasPrevTranslated = false; for (int i = 0; i < length; i++) { char c = input.charAt(i); if (i > 0 || c != '_') // skip first starting underscore { if (Character.isUpperCase(c)) { if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_') { result.append('_'); resultLength++; } c = Character.toLowerCase(c); wasPrevTranslated = true; } else { wasPrevTranslated = false; } result.append(c); resultLength++; } } return resultLength > 0 ? result.toString() : input; } } /** * See {@link PascalCaseStrategy} for details. * * @since 2.1 */ public static final PropertyNamingStrategy PASCAL_CASE_TO_CAMEL_CASE = new PascalCaseStrategy(); /** * A {@link PropertyNamingStrategy} that translates typical camelCase Java * property names to PascalCase JSON element names (i.e., with a capital * first letter). In particular, the following translations are applied by * this PropertyNamingStrategy. * *
  • The first lower-case letter in the Java property name is translated * into its equivalent upper-case representation.
* * This rules result in the following example translation from * Java property names to JSON element names. *
  • "userName" is translated to "UserName"
* * @since 2.1 */ public static class PascalCaseStrategy extends PropertyNamingStrategyBase { /** * Converts camelCase to PascalCase * * For example, "userName" would be converted to * "UserName". * * @param input formatted as camelCase string * @return input converted to PascalCase format */ @Override public String translate(String input) { if (input == null || input.length() == 0){ return input; // garbage in, garbage out } // Replace first lower-case letter with upper-case equivalent char c = input.charAt(0); if (Character.isUpperCase(c)) { return input; } StringBuilder sb = new StringBuilder(input); sb.setCharAt(0, Character.toUpperCase(c)); return sb.toString(); } } } RuntimeJsonMappingException.java000066400000000000000000000010501215056657300367620ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; /** * Wrapper used when interface does not allow throwing a checked * {@link JsonMappingException} */ @SuppressWarnings("serial") public class RuntimeJsonMappingException extends RuntimeException { public RuntimeJsonMappingException(JsonMappingException cause) { super(cause); } public RuntimeJsonMappingException(String message) { super(message); } public RuntimeJsonMappingException(String message, JsonMappingException cause) { super(message, cause); } } SerializationConfig.java000066400000000000000000000424721215056657300352720ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.text.DateFormat; import java.util.*; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.core.Base64Variant; import com.fasterxml.jackson.databind.cfg.BaseSettings; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfigBase; import com.fasterxml.jackson.databind.introspect.ClassIntrospector; import com.fasterxml.jackson.databind.introspect.VisibilityChecker; import com.fasterxml.jackson.databind.jsontype.SubtypeResolver; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.ser.SerializerFactory; import com.fasterxml.jackson.databind.type.ClassKey; import com.fasterxml.jackson.databind.type.TypeFactory; /** * Object that contains baseline configuration for serialization * process. An instance is owned by {@link ObjectMapper}, which * passes an immutable instance for serialization process to * {@link SerializerProvider} and {@link SerializerFactory} * (either directly, or through {@link ObjectWriter}. *

* Note that instances are considered immutable and as such no copies * should need to be created for sharing; all copying is done with * "fluent factory" methods. * Note also that unlike with Jackson 1, these instances can not be * assigned to {@link ObjectMapper}; in fact, application code should * rarely interact directly with these instance (unlike core Jackson code) */ public final class SerializationConfig extends MapperConfigBase implements java.io.Serializable // since 2.1 { // for 2.1.0: private static final long serialVersionUID = 8849092838541724233L; /** * Set of features enabled; actual type (kind of features) * depends on sub-classes. */ protected final int _serFeatures; /** * Which Bean/Map properties are to be included in serialization? * Default settings is to include all regardless of value; can be * changed to only include non-null properties, or properties * with non-default values. */ protected JsonInclude.Include _serializationInclusion = null; /** * Object used for resolving filter ids to filter instances. * Non-null if explicitly defined; null by default. */ protected final FilterProvider _filterProvider; /* /********************************************************** /* Life-cycle, constructors /********************************************************** */ /** * Constructor used by ObjectMapper to create default configuration object instance. */ public SerializationConfig(BaseSettings base, SubtypeResolver str, Map> mixins) { super(base, str, mixins); _serFeatures = collectFeatureDefaults(SerializationFeature.class); _filterProvider = null; } private SerializationConfig(SerializationConfig src, SubtypeResolver str) { super(src, str); _serFeatures = src._serFeatures; _serializationInclusion = src._serializationInclusion; _filterProvider = src._filterProvider; } private SerializationConfig(SerializationConfig src, int mapperFeatures, int serFeatures) { super(src, mapperFeatures); _serFeatures = serFeatures; _serializationInclusion = src._serializationInclusion; _filterProvider = src._filterProvider; } private SerializationConfig(SerializationConfig src, BaseSettings base) { super(src, base); _serFeatures = src._serFeatures; _serializationInclusion = src._serializationInclusion; _filterProvider = src._filterProvider; } private SerializationConfig(SerializationConfig src, FilterProvider filters) { super(src); _serFeatures = src._serFeatures; _serializationInclusion = src._serializationInclusion; _filterProvider = filters; } private SerializationConfig(SerializationConfig src, Class view) { super(src, view); _serFeatures = src._serFeatures; _serializationInclusion = src._serializationInclusion; _filterProvider = src._filterProvider; } private SerializationConfig(SerializationConfig src, JsonInclude.Include incl) { super(src); _serFeatures = src._serFeatures; _serializationInclusion = incl; _filterProvider = src._filterProvider; } private SerializationConfig(SerializationConfig src, String rootName) { super(src, rootName); _serFeatures = src._serFeatures; _serializationInclusion = src._serializationInclusion; _filterProvider = src._filterProvider; } /** * @since 2.1 */ protected SerializationConfig(SerializationConfig src, Map> mixins) { super(src, mixins); _serFeatures = src._serFeatures; _serializationInclusion = src._serializationInclusion; _filterProvider = src._filterProvider; } /* /********************************************************** /* Life-cycle, factory methods from MapperConfig /********************************************************** */ /** * Fluent factory method that will construct and return a new configuration * object instance with specified features enabled. */ @Override public SerializationConfig with(MapperFeature... features) { int newMapperFlags = _mapperFeatures; for (MapperFeature f : features) { newMapperFlags |= f.getMask(); } return (newMapperFlags == _mapperFeatures) ? this : new SerializationConfig(this, newMapperFlags, _serFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features disabled. */ @Override public SerializationConfig without(MapperFeature... features) { int newMapperFlags = _mapperFeatures; for (MapperFeature f : features) { newMapperFlags &= ~f.getMask(); } return (newMapperFlags == _mapperFeatures) ? this : new SerializationConfig(this, newMapperFlags, _serFeatures); } @Override public SerializationConfig with(AnnotationIntrospector ai) { return _withBase(_base.withAnnotationIntrospector(ai)); } @Override public SerializationConfig withAppendedAnnotationIntrospector(AnnotationIntrospector ai) { return _withBase(_base.withAppendedAnnotationIntrospector(ai)); } @Override public SerializationConfig withInsertedAnnotationIntrospector(AnnotationIntrospector ai) { return _withBase(_base.withInsertedAnnotationIntrospector(ai)); } @Override public SerializationConfig with(ClassIntrospector ci) { return _withBase(_base.withClassIntrospector(ci)); } /** * In addition to constructing instance with specified date format, * will enable or disable SerializationFeature.WRITE_DATES_AS_TIMESTAMPS * (enable if format set as null; disable if non-null) */ @Override public SerializationConfig with(DateFormat df) { SerializationConfig cfg = new SerializationConfig(this, _base.withDateFormat(df)); // Also need to toggle this feature based on existence of date format: if (df == null) { cfg = cfg.with(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); } else { cfg = cfg.without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); } return cfg; } @Override public SerializationConfig with(HandlerInstantiator hi) { return _withBase(_base.withHandlerInstantiator(hi)); } @Override public SerializationConfig with(PropertyNamingStrategy pns) { return _withBase(_base.withPropertyNamingStrategy(pns)); } @Override public SerializationConfig withRootName(String rootName) { if (rootName == null) { if (_rootName == null) { return this; } } else if (rootName.equals(_rootName)) { return this; } return new SerializationConfig(this, rootName); } @Override public SerializationConfig with(SubtypeResolver str) { return (str == _subtypeResolver)? this : new SerializationConfig(this, str); } @Override public SerializationConfig with(TypeFactory tf) { return _withBase(_base.withTypeFactory(tf)); } @Override public SerializationConfig with(TypeResolverBuilder trb) { return _withBase(_base.withTypeResolverBuilder(trb)); } @Override public SerializationConfig withView(Class view) { return (_view == view) ? this : new SerializationConfig(this, view); } @Override public SerializationConfig with(VisibilityChecker vc) { return _withBase(_base.withVisibilityChecker(vc)); } @Override public SerializationConfig withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { return _withBase(_base.withVisibility(forMethod, visibility)); } @Override public SerializationConfig with(Locale l) { return _withBase(_base.with(l)); } @Override public SerializationConfig with(TimeZone tz) { return _withBase(_base.with(tz)); } @Override public SerializationConfig with(Base64Variant base64) { return _withBase(_base.with(base64)); } private final SerializationConfig _withBase(BaseSettings newBase) { return (_base == newBase) ? this : new SerializationConfig(this, newBase); } /* /********************************************************** /* Life-cycle, SerializationConfig specific factory methods /********************************************************** */ /** * Fluent factory method that will construct and return a new configuration * object instance with specified feature enabled. */ public SerializationConfig with(SerializationFeature feature) { int newSerFeatures = _serFeatures | feature.getMask(); return (newSerFeatures == _serFeatures) ? this : new SerializationConfig(this, _mapperFeatures, newSerFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features enabled. */ public SerializationConfig with(SerializationFeature first, SerializationFeature... features) { int newSerFeatures = _serFeatures | first.getMask(); for (SerializationFeature f : features) { newSerFeatures |= f.getMask(); } return (newSerFeatures == _serFeatures) ? this : new SerializationConfig(this, _mapperFeatures, newSerFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features enabled. */ public SerializationConfig withFeatures(SerializationFeature... features) { int newSerFeatures = _serFeatures; for (SerializationFeature f : features) { newSerFeatures |= f.getMask(); } return (newSerFeatures == _serFeatures) ? this : new SerializationConfig(this, _mapperFeatures, newSerFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified feature disabled. */ public SerializationConfig without(SerializationFeature feature) { int newSerFeatures = _serFeatures & ~feature.getMask(); return (newSerFeatures == _serFeatures) ? this : new SerializationConfig(this, _mapperFeatures, newSerFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features disabled. */ public SerializationConfig without(SerializationFeature first, SerializationFeature... features) { int newSerFeatures = _serFeatures & ~first.getMask(); for (SerializationFeature f : features) { newSerFeatures &= ~f.getMask(); } return (newSerFeatures == _serFeatures) ? this : new SerializationConfig(this, _mapperFeatures, newSerFeatures); } /** * Fluent factory method that will construct and return a new configuration * object instance with specified features disabled. */ public SerializationConfig withoutFeatures(SerializationFeature... features) { int newSerFeatures = _serFeatures; for (SerializationFeature f : features) { newSerFeatures &= ~f.getMask(); } return (newSerFeatures == _serFeatures) ? this : new SerializationConfig(this, _mapperFeatures, newSerFeatures); } public SerializationConfig withFilters(FilterProvider filterProvider) { return (filterProvider == _filterProvider) ? this : new SerializationConfig(this, filterProvider); } public SerializationConfig withSerializationInclusion(JsonInclude.Include incl) { return (_serializationInclusion == incl) ? this: new SerializationConfig(this, incl); } /* /********************************************************** /* MapperConfig implementation/overrides /********************************************************** */ @Override public boolean useRootWrapping() { if (_rootName != null) { // empty String disables wrapping; non-empty enables return (_rootName.length() > 0); } return isEnabled(SerializationFeature.WRAP_ROOT_VALUE); } @Override public AnnotationIntrospector getAnnotationIntrospector() { /* 29-Jul-2009, tatu: it's now possible to disable use of * annotations; can be done using "no-op" introspector */ if (isEnabled(MapperFeature.USE_ANNOTATIONS)) { return super.getAnnotationIntrospector(); } return AnnotationIntrospector.nopInstance(); } /** * Accessor for getting bean description that only contains class * annotations: useful if no getter/setter/creator information is needed. */ @Override public BeanDescription introspectClassAnnotations(JavaType type) { return getClassIntrospector().forClassAnnotations(this, type, this); } /** * Accessor for getting bean description that only contains immediate class * annotations: ones from the class, and its direct mix-in, if any, but * not from super types. */ @Override public BeanDescription introspectDirectClassAnnotations(JavaType type) { return getClassIntrospector().forDirectClassAnnotations(this, type, this); } @Override public VisibilityChecker getDefaultVisibilityChecker() { VisibilityChecker vchecker = super.getDefaultVisibilityChecker(); if (!isEnabled(MapperFeature.AUTO_DETECT_GETTERS)) { vchecker = vchecker.withGetterVisibility(Visibility.NONE); } // then global overrides (disabling) if (!isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)) { vchecker = vchecker.withIsGetterVisibility(Visibility.NONE); } if (!isEnabled(MapperFeature.AUTO_DETECT_FIELDS)) { vchecker = vchecker.withFieldVisibility(Visibility.NONE); } return vchecker; } /* /********************************************************** /* Configuration: other /********************************************************** */ public final boolean isEnabled(SerializationFeature f) { return (_serFeatures & f.getMask()) != 0; } public final int getSerializationFeatures() { return _serFeatures; } public JsonInclude.Include getSerializationInclusion() { if (_serializationInclusion != null) { return _serializationInclusion; } return JsonInclude.Include.ALWAYS; } /** * Method for getting provider used for locating filters given * id (which is usually provided with filter annotations). * Will be null if no provided was set for {@link ObjectWriter} * (or if serialization directly called from {@link ObjectMapper}) */ public FilterProvider getFilterProvider() { return _filterProvider; } /* /********************************************************** /* Introspection methods /********************************************************** */ /** * Method that will introspect full bean properties for the purpose * of building a bean serializer */ @SuppressWarnings("unchecked") public T introspect(JavaType type) { return (T) getClassIntrospector().forSerialization(this, type, this); } /* /********************************************************** /* Debug support /********************************************************** */ @Override public String toString() { return "[SerializationConfig: flags=0x"+Integer.toHexString(_serFeatures)+"]"; } } SerializationFeature.java000066400000000000000000000315371215056657300354600ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import com.fasterxml.jackson.databind.cfg.ConfigFeature; /** * Enumeration that defines simple on/off features that affect * the way Java objects are serialized. *

* Note that features can be set both through * {@link ObjectMapper} (as sort of defaults) and through * {@link ObjectWriter}. * In first case these defaults must follow "config-then-use" patterns * (i.e. defined once, not changed afterwards); all per-call * changes must be done using {@link ObjectWriter}. */ public enum SerializationFeature implements ConfigFeature { /* /****************************************************** /* Generic output features /****************************************************** */ /** * Feature that can be enabled to make root value (usually JSON * Object but can be any type) wrapped within a single property * JSON object, where key as the "root name", as determined by * annotation introspector (esp. for JAXB that uses * @XmlRootElement.name) or fallback (non-qualified * class name). * Feature is mostly intended for JAXB compatibility. *

* Feature is disabled by default. */ WRAP_ROOT_VALUE(false), /** * Feature that allows enabling (or disabling) indentation * for the underlying generator, using the default pretty * printer (see * {@link com.fasterxml.jackson.core.JsonGenerator#useDefaultPrettyPrinter} * for details). *

* Note that this only affects cases where * {@link com.fasterxml.jackson.core.JsonGenerator} * is constructed implicitly by ObjectMapper: if explicit * generator is passed, its configuration is not changed. *

* Also note that if you want to configure details of indentation, * you need to directly configure the generator: there is a * method to use any PrettyPrinter instance. * This feature will only allow using the default implementation. *

* Feature is enabled by default. */ INDENT_OUTPUT(false), /* /****************************************************** /* Error handling features /****************************************************** */ /** * Feature that determines what happens when no accessors are * found for a type (and there are no annotations to indicate * it is meant to be serialized). If enabled (default), an * exception is thrown to indicate these as non-serializable * types; if disabled, they are serialized as empty Objects, * i.e. without any properties. *

* Note that empty types that this feature has only effect on * those "empty" beans that do not have any recognized annotations * (like @JsonSerialize): ones that do have annotations * do not result in an exception being thrown. *

* Feature is enabled by default. */ FAIL_ON_EMPTY_BEANS(true), /** * Feature that determines whether Jackson code should catch * and wrap {@link Exception}s (but never {@link Error}s!) * to add additional information about * location (within input) of problem or not. If enabled, * most exceptions will be caught and re-thrown (exception * specifically being that {@link java.io.IOException}s may be passed * as is, since they are declared as throwable); this can be * convenient both in that all exceptions will be checked and * declared, and so there is more contextual information. * However, sometimes calling application may just want "raw" * unchecked exceptions passed as is. *

*

* Feature is enabled by default. */ WRAP_EXCEPTIONS(true), /* /****************************************************** /* Output life cycle features /****************************************************** */ /** * Feature that determines whether close method of * serialized root level objects (ones for which ObjectMapper's * writeValue() (or equivalent) method is called) * that implement {@link java.io.Closeable} * is called after serialization or not. If enabled, close() will * be called after serialization completes (whether succesfully, or * due to an error manifested by an exception being thrown). You can * think of this as sort of "finally" processing. *

* NOTE: only affects behavior with root objects, and not other * objects reachable from the root object. Put another way, only one * call will be made for each 'writeValue' call. *

* Feature is disabled by default. */ CLOSE_CLOSEABLE(false), /** * Feature that determines whether JsonGenerator.flush() is * called after writeValue() method that takes JsonGenerator * as an argument completes (i.e. does NOT affect methods * that use other destinations); same for methods in {@link ObjectWriter}. * This usually makes sense; but there are cases where flushing * should not be forced: for example when underlying stream is * compressing and flush() causes compression state to be flushed * (which occurs with some compression codecs). *

* Feature is enabled by default. */ FLUSH_AFTER_WRITE_VALUE(true), /* /****************************************************** /* Datatype-specific serialization configuration /****************************************************** */ /** * Feature that determines whether {@link java.util.Date} values * (and Date-based things like {@link java.util.Calendar}s) are to be * serialized as numeric timestamps (true; the default), * or as something else (usually textual representation). * If textual representation is used, the actual format is * one returned by a call to * {@link com.fasterxml.jackson.databind.SerializationConfig#getDateFormat}. *

* Note: whether this feature affects handling of other date-related * types depend on handlers of those types, although ideally they * should use this feature *

* Note: whether {@link java.util.Map} keys are serialized as Strings * or not is controlled using {@link #WRITE_DATE_KEYS_AS_TIMESTAMPS}. *

* Feature is enabled by default. */ WRITE_DATES_AS_TIMESTAMPS(true), /** * Feature that determines whether {@link java.util.Date}s * (and sub-types) used as {@link java.util.Map} keys are serialized * as timestamps or not (if not, will be serialized as textual * values). *

* Default value is 'false', meaning that Date-valued Map keys are serialized * as textual (ISO-8601) values. *

* Feature is disabled by default. */ WRITE_DATE_KEYS_AS_TIMESTAMPS(false), /** * Feature that determines how type char[] is serialized: * when enabled, will be serialized as an explict JSON array (with * single-character Strings as values); when disabled, defaults to * serializing them as Strings (which is more compact). *

* Feature is disabled by default. */ WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS(false), /** * Feature that determines standard serialization mechanism used for * Enum values: if enabled, return value of Enum.toString() * is used; if disabled, return value of Enum.name() is used. *

* Note: this feature should usually have same value * as {@link DeserializationFeature#READ_ENUMS_USING_TO_STRING}. *

* Feature is disabled by default. */ WRITE_ENUMS_USING_TO_STRING(false), /** * Feature that determines whethere Java Enum values are serialized * as numbers (true), or textual values (false). If textual values are * used, other settings are also considered. * If this feature is enabled, * return value of Enum.ordinal() * (an integer) will be used as the serialization. *

* Note that this feature has precedence over {@link #WRITE_ENUMS_USING_TO_STRING}, * which is only considered if this feature is set to false. *

* Feature is disabled by default. */ WRITE_ENUMS_USING_INDEX(false), /** * Feature that determines whether Map entries with null values are * to be serialized (true) or not (false). *

* For further details, check out [JACKSON-314] *

* Feature is enabled by default. */ WRITE_NULL_MAP_VALUES(true), /** * Feature that determines whether Container properties (POJO properties * with declared value of Collection or array; i.e. things that produce JSON * arrays) that are empty (have no elements) * will be serialized as empty JSON arrays (true), or suppressed from output (false). *

* Note that this does not change behavior of {@link java.util.Map}s, or * "Collection-like" types. *

* Feature is enabled by default. */ WRITE_EMPTY_JSON_ARRAYS(true), /** * Feature added for interoperability, to work with oddities of * so-called "BadgerFish" convention. * Feature determines handling of single element {@link java.util.Collection}s * and arrays: if enabled, {@link java.util.Collection}s and arrays that contain exactly * one element will be serialized as if that element itself was serialized. *

* When enabled, a POJO with array that normally looks like this: *

     *  { "arrayProperty" : [ 1 ] }
     *
* will instead be serialized as *
     *  { "arrayProperty" : 1 }
     *
*

* Note that this feature is counterpart to {@link DeserializationFeature#ACCEPT_SINGLE_VALUE_AS_ARRAY} * (that is, usually both are enabled, or neither is). *

* Feature is disabled by default, so that no special handling is done. */ WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED(false), /** * Feature that determines whether {@link java.math.BigDecimal} entries are * serialized using {@link java.math.BigDecimal#toPlainString()} to prevent * values to be written using scientific notation. *

* NOTE: since this feature typically requires use of * {@link com.fasterxml.jackson.core.JsonGenerator#writeNumber(String)} * ot may cause compatibility problems since not all {@link com.fasterxml.jackson.core.JsonGenerator} * implementations support such mode of output: usually only text-based formats * support it. *

* Feature is disabled by default. */ WRITE_BIGDECIMAL_AS_PLAIN(false), /** * Feature that controls whether numeric timestamp values are * to be written using nanosecond timestamps (enabled) or not (disabled); * if and only if datatype supports such resolution. * Only newer datatypes (such as Java8 Date/Time) support such resolution -- * older types (pre-Java8 java.util.Date etc) and Joda do not -- * and this setting has no effect on such types. *

* If disabled, standard millisecond timestamps are assumed. * This is the counterpart to {@link SerializationFeature#WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS}. *

* Feature is enabled by default, to support most accurate time values possible. * * @since 2.2 */ WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS(true), /** * Feature that determines whether {@link java.util.Map} entries are first * sorted by key before serialization or not: if enabled, additional sorting * step is performed if necessary (not necessary for {@link java.util.SortedMap}s), * if disabled, no additional sorting is needed. *

* Feature is disabled by default. */ ORDER_MAP_ENTRIES_BY_KEYS(false), /* /****************************************************** /* Other /****************************************************** */ /** * Feature that determines whether {@link ObjectWriter} should * try to eagerly fetch necessary {@link JsonSerializer} when * possible. This improves performance in cases where similarly * configured {@link ObjectWriter} instance is used multiple * times; and should not significantly affect single-use cases. *

* Note that there should not be any need to normally disable this * feature: only consider that if there are actual perceived problems. *

* Feature is enabled by default. * * @since 2.1 */ EAGER_SERIALIZER_FETCH(true) ; private final boolean _defaultState; private SerializationFeature(boolean defaultState) { _defaultState = defaultState; } @Override public boolean enabledByDefault() { return _defaultState; } @Override public int getMask() { return (1 << ordinal()); } } SerializerProvider.java000066400000000000000000001043231215056657300351450ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databindpackage com.fasterxml.jackson.databind; import java.io.IOException; import java.text.DateFormat; import java.util.*; import com.fasterxml.jackson.annotation.ObjectIdGenerator; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.ser.*; import com.fasterxml.jackson.databind.ser.impl.*; import com.fasterxml.jackson.databind.ser.std.NullSerializer; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.RootNameLookup; /** * Class that defines API used by {@link ObjectMapper} and * {@link JsonSerializer}s to obtain serializers capable of serializing * instances of specific types; as well as the default implementation * of the functionality. *

* Provider handles caching aspects of serializer handling; all construction * details are delegated to {@link SerializerFactory} instance. *

* Object life-cycle is such that an initial instance ("blueprint") is created * and referenced by {@link ObjectMapper} and {@link ObjectWriter} intances; * but for actual usage, a configured instance is created by using * a create method in sub-class * {@link com.fasterxml.jackson.databind.ser.DefaultSerializerProvider}. * Only this instance can be used for actual serialization calls; blueprint * object is only to be used for creating instances. */ public abstract class SerializerProvider extends DatabindContext { protected final static JavaType TYPE_OBJECT = TypeFactory.defaultInstance().uncheckedSimpleType(Object.class); /** * Setting for determining whether mappings for "unknown classes" should be * cached for faster resolution. Usually this isn't needed, but maybe it * is in some cases? */ protected final static boolean CACHE_UNKNOWN_MAPPINGS = false; public final static JsonSerializer DEFAULT_NULL_KEY_SERIALIZER = new FailingSerializer("Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)"); public final static JsonSerializer DEFAULT_UNKNOWN_SERIALIZER = new UnknownSerializer(); /* /********************************************************** /* Configuration, general /********************************************************** */ /** * Serialization configuration to use for serialization processing. */ final protected SerializationConfig _config; /** * View used for currently active serialization, if any. */ final protected Class _serializationView; /* /********************************************************** /* Configuration, factories /********************************************************** */ /** * Factory used for constructing actual serializer instances. */ final protected SerializerFactory _serializerFactory; /* /********************************************************** /* Helper objects for caching /********************************************************** */ /** * Cache for doing type-to-value-serializer lookups. */ final protected SerializerCache _serializerCache; /** * Helper object for keeping track of introspected root names */ final protected RootNameLookup _rootNames; /* /********************************************************** /* Configuration, specialized serializers /********************************************************** */ /** * Serializer that gets called for values of types for which no * serializers can be constructed. *

* The default serializer will simply thrown an exception. */ protected JsonSerializer _unknownTypeSerializer = DEFAULT_UNKNOWN_SERIALIZER; /** * Serializer used to output non-null keys of Maps (which will get * output as JSON Objects), if not null; if null, us the standard * default key serializer. */ protected JsonSerializer _keySerializer; /** * Serializer used to output a null value. Default implementation * writes nulls using {@link JsonGenerator#writeNull}. */ protected JsonSerializer _nullValueSerializer = NullSerializer.instance; /** * Serializer used to (try to) output a null key, due to an entry of * {@link java.util.Map} having null key. * The default implementation will throw an exception if this happens; * alternative implementation (like one that would write an Empty String) * can be defined. */ protected JsonSerializer _nullKeySerializer = DEFAULT_NULL_KEY_SERIALIZER; /* /********************************************************** /* State, for non-blueprint instances: generic /********************************************************** */ /** * For fast lookups, we will have a local non-shared read-only * map that contains serializers previously fetched. */ protected final ReadOnlyClassToSerializerMap _knownSerializers; /** * Lazily acquired and instantiated formatter object: initialized * first time it is needed, reused afterwards. Used via instances * (not blueprints), so that access need not be thread-safe. */ protected DateFormat _dateFormat; /* /********************************************************** /* Life-cycle /********************************************************** */ /** * Constructor for creating master (or "blue-print") provider object, * which is only used as the template for constructing per-binding * instances. */ public SerializerProvider() { _config = null; _serializerFactory = null; _serializerCache = new SerializerCache(); // Blueprints doesn't have access to any serializers... _knownSerializers = null; _rootNames = new RootNameLookup(); _serializationView = null; } /** * "Copy-constructor", used by sub-classes. * * @param src Blueprint object used as the baseline for this instance */ protected SerializerProvider(SerializerProvider src, SerializationConfig config, SerializerFactory f) { if (config == null) { throw new NullPointerException(); } _serializerFactory = f; _config = config; _serializerCache = src._serializerCache; _unknownTypeSerializer = src._unknownTypeSerializer; _keySerializer = src._keySerializer; _nullValueSerializer = src._nullValueSerializer; _nullKeySerializer = src._nullKeySerializer; _rootNames = src._rootNames; /* Non-blueprint instances do have a read-only map; one that doesn't * need synchronization for lookups. */ _knownSerializers = _serializerCache.getReadOnlyLookupMap(); _serializationView = config.getActiveView(); } /* /********************************************************** /* Methods for configuring default settings /********************************************************** */ /** * Method that can be used to specify serializer that will be * used to write JSON property names matching null keys for Java * Maps (which will throw an exception if try write such property * name) */ public void setDefaultKeySerializer(JsonSerializer ks) { if (ks == null) { throw new IllegalArgumentException("Can not pass null JsonSerializer"); } _keySerializer = ks; } /** * Method that can be used to specify serializer that will be * used to write JSON values matching Java null values * instead of default one (which simply writes JSON null) */ public void setNullValueSerializer(JsonSerializer nvs) { if (nvs == null) { throw new IllegalArgumentException("Can not pass null JsonSerializer"); } _nullValueSerializer = nvs; } /** * Method that can be used to specify serializer to use for serializing * all non-null JSON property names, unless more specific key serializer * is found (i.e. if not custom key serializer has been registered for * Java type). *

* Note that key serializer registration are different from value serializer * registrations. */ public void setNullKeySerializer(JsonSerializer nks) { if (nks == null) { throw new IllegalArgumentException("Can not pass null JsonSerializer"); } _nullKeySerializer = nks; } /* /********************************************************** /* DatabindContext implementation /********************************************************** */ /** * Method for accessing configuration for the serialization processing. */ @Override public final SerializationConfig getConfig() { return _config; } @Override public final AnnotationIntrospector getAnnotationIntrospector() { return _config.getAnnotationIntrospector(); } @Override public final TypeFactory getTypeFactory() { return _config.getTypeFactory(); } @Override public final Class getActiveView() { return _serializationView; } /** * @deprecated Since 2.2, use {@link #getActiveView} instead. */ @Deprecated public final Class getSerializationView() { return _serializationView; } /* /********************************************************** /* Access to general configuration /********************************************************** */ /** * Convenience method for checking whether specified serialization * feature is enabled or not. * Shortcut for: *
     *  getConfig().isEnabled(feature);
     *
*/ public final boolean isEnabled(SerializationFeature feature) { return _config.isEnabled(feature); } /** * Convenience method for accessing provider to find serialization filters used, * equivalent to calling: *
     *   getConfig().getFilterProvider();
     *
*/ public final FilterProvider getFilterProvider() { return _config.getFilterProvider(); } /** * Method for accessing default Locale to use: convenience method for *
     *   getConfig().getLocale();
     *
*/ public Locale getLocale() { return _config.getLocale(); } /** * Method for accessing default TimeZone to use: convenience method for *
     *   getConfig().getTimeZone();
     *
*/ public TimeZone getTimeZone() { return _config.getTimeZone(); } /* /********************************************************** /* Access to Object Id aspects /********************************************************** */ /** * Method called to find the Object Id for given POJO, if one * has been generated. Will always return a non-null Object; * contents vary depending on whether an Object Id already * exists or not. */ public abstract WritableObjectId findObjectId(Object forPojo, ObjectIdGenerator generatorType); /* /********************************************************** /* General serializer locating functionality /********************************************************** */ /** * Method called to get hold of a serializer for a value of given type; * or if no such serializer can be found, a default handler (which * may do a best-effort generic serialization or just simply * throw an exception when invoked). *

* Note: this method is only called for non-null values; not for keys * or null values. For these, check out other accessor methods. *

* Note that starting with version 1.5, serializers should also be type-aware * if they handle polymorphic types. That means that it may be necessary * to also use a {@link TypeSerializer} based on declared (static) type * being serializer (whereas actual data may be serialized using dynamic * type) * * @throws JsonMappingException if there are fatal problems with * accessing suitable serializer; including that of not * finding any serializer */ public JsonSerializer findValueSerializer(Class valueType, BeanProperty property) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { // ... possibly as fully typed? ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType)); if (ser == null) { // If neither, must create ser = _createAndCacheUntypedSerializer(valueType); // Not found? Must use the unknown type serializer /* Couldn't create? Need to return the fallback serializer, which * most likely will report an error: but one question is whether * we should cache it? */ if (ser == null) { ser = getUnknownTypeSerializer(valueType); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } } // at this point, resolution has occured, but not contextualization return _handleContextual(ser, property); } /** * Similar to {@link #findValueSerializer(Class,BeanProperty)}, but takes * full generics-aware type instead of raw class. * This is necessary for accurate handling of external type information, * to handle polymorphic types. * * @param property When creating secondary serializers, property for which * serializer is needed: annotations of the property (or bean that contains it) * may be checked to create contextual serializers. */ public JsonSerializer findValueSerializer(JavaType valueType, BeanProperty property) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { // If neither, must create ser = _createAndCacheUntypedSerializer(valueType); // Not found? Must use the unknown type serializer /* Couldn't create? Need to return the fallback serializer, which * most likely will report an error: but one question is whether * we should cache it? */ if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } return _handleContextual(ser, property); } /** * Method called to locate regular serializer, matching type serializer, * and if both found, wrap them in a serializer that calls both in correct * sequence. This method is currently only used for root-level serializer * handling to allow for simpler caching. A call can always be replaced * by equivalent calls to access serializer and type serializer separately. * * @param valueType Type for purpose of locating a serializer; usually dynamic * runtime type, but can also be static declared type, depending on configuration * @param cache Whether resulting value serializer should be cached or not; this is just * a hint * @param property When creating secondary serializers, property for which * serializer is needed: annotations of the property (or bean that contains it) * may be checked to create contextual serializers. */ public JsonSerializer findTypedValueSerializer(Class valueType, boolean cache, BeanProperty property) throws JsonMappingException { // Two-phase lookups; local non-shared cache, then shared: JsonSerializer ser = _knownSerializers.typedValueSerializer(valueType); if (ser != null) { return ser; } // If not, maybe shared map already has it? ser = _serializerCache.typedValueSerializer(valueType); if (ser != null) { return ser; } // Well, let's just compose from pieces: ser = findValueSerializer(valueType, property); TypeSerializer typeSer = _serializerFactory.createTypeSerializer(_config, _config.constructType(valueType)); if (typeSer != null) { typeSer = typeSer.forProperty(property); ser = new TypeWrappedSerializer(typeSer, ser); } if (cache) { _serializerCache.addTypedSerializer(valueType, ser); } return ser; } /** * Method called to locate regular serializer, matching type serializer, * and if both found, wrap them in a serializer that calls both in correct * sequence. This method is currently only used for root-level serializer * handling to allow for simpler caching. A call can always be replaced * by equivalent calls to access serializer and type serializer separately. * * @param valueType Declared type of value being serialized (which may not * be actual runtime type); used for finding both value serializer and * type serializer to use for adding polymorphic type (if any) * @param cache Whether resulting value serializer should be cached or not; this is just * a hint * @param property When creating secondary serializers, property for which * serializer is needed: annotations of the property (or bean that contains it) * may be checked to create contextual serializers. */ public JsonSerializer findTypedValueSerializer(JavaType valueType, boolean cache, BeanProperty property) throws JsonMappingException { // Two-phase lookups; local non-shared cache, then shared: JsonSerializer ser = _knownSerializers.typedValueSerializer(valueType); if (ser != null) { return ser; } // If not, maybe shared map already has it? ser = _serializerCache.typedValueSerializer(valueType); if (ser != null) { return ser; } // Well, let's just compose from pieces: ser = findValueSerializer(valueType, property); TypeSerializer typeSer = _serializerFactory.createTypeSerializer(_config, valueType); if (typeSer != null) { typeSer = typeSer.forProperty(property); ser = new TypeWrappedSerializer(typeSer, ser); } if (cache) { _serializerCache.addTypedSerializer(valueType, ser); } return ser; } /** * Method called to get the serializer to use for serializing * non-null Map keys. Separation from regular * {@link #findValueSerializer} method is because actual write * method must be different (@link JsonGenerator#writeFieldName}; * but also since behavior for some key types may differ. *

* Note that the serializer itself can be called with instances * of any Java object, but not nulls. */ public JsonSerializer findKeySerializer(JavaType keyType, BeanProperty property) throws JsonMappingException { JsonSerializer ser = _serializerFactory.createKeySerializer(_config, keyType, _keySerializer); // 25-Feb-2011, tatu: As per [JACKSON-519], need to ensure contextuality works here, too return _handleContextualResolvable(ser, property); } /* /******************************************************** /* Accessors for specialized serializers /******************************************************** */ /** * @since 2.0 */ public JsonSerializer getDefaultNullKeySerializer() { return _nullKeySerializer; } /** * @since 2.0 */ public JsonSerializer getDefaultNullValueSerializer() { return _nullValueSerializer; } /** * Method called to get the serializer to use for serializing * Map keys that are nulls: this is needed since JSON does not allow * any non-String value as key, including null. *

* Typically, returned serializer * will either throw an exception, or use an empty String; but * other behaviors are possible. */ /** * Method called to find a serializer to use for null values for given * declared type. Note that type is completely based on declared type, * since nulls in Java have no type and thus runtime type can not be * determined. * * @since 2.0 */ public JsonSerializer findNullKeySerializer(JavaType serializationType, BeanProperty property) throws JsonMappingException { return getDefaultNullKeySerializer(); } /** * Method called to get the serializer to use for serializing null * property values. *

* Default implementation simply calls {@link #getDefaultNullValueSerializer()}; * can be overridden to add custom null serialization for properties * of certain type or name. * * @since 2.0 */ public JsonSerializer findNullValueSerializer(BeanProperty property) throws JsonMappingException { return getDefaultNullValueSerializer(); } /** * Method called to get the serializer to use if provider * can not determine an actual type-specific serializer * to use; typically when none of {@link SerializerFactory} * instances are able to construct a serializer. *

* Typically, returned serializer will throw an exception, * although alternatively {@link com.fasterxml.jackson.databind.ser.std.ToStringSerializer} * could be returned as well. * * @param unknownType Type for which no serializer is found */ public JsonSerializer getUnknownTypeSerializer(Class unknownType) { return _unknownTypeSerializer; } /* /********************************************************** /* Methods for creating instances based on annotations /********************************************************** */ /** * Method that can be called to construct and configure serializer instance, * either given a {@link Class} to instantiate (with default constructor), * or an uninitialized serializer instance. * Either way, serialize will be properly resolved * (via {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer}) and/or contextualized * (via {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}) as necessary. * * @param annotated Annotated entity that contained definition * @param serDef Serializer definition: either an instance or class */ public abstract JsonSerializer serializerInstance(Annotated annotated, Object serDef) throws JsonMappingException; /* /******************************************************** /* Convenience methods /******************************************************** */ /** * Convenience method that will serialize given value (which can be * null) using standard serializer locating functionality. It can * be called for all values including field and Map values, but usually * field values are best handled calling * {@link #defaultSerializeField} instead. */ public final void defaultSerializeValue(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { if (value == null) { getDefaultNullValueSerializer().serialize(null, jgen, this); } else { Class cls = value.getClass(); findTypedValueSerializer(cls, true, null).serialize(value, jgen, this); } } /** * Convenience method that will serialize given field with specified * value. Value may be null. Serializer is done using the usual * null) using standard serializer locating functionality. */ public final void defaultSerializeField(String fieldName, Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { jgen.writeFieldName(fieldName); if (value == null) { /* Note: can't easily check for suppression at this point * any more; caller must check it. */ getDefaultNullValueSerializer().serialize(null, jgen, this); } else { Class cls = value.getClass(); findTypedValueSerializer(cls, true, null).serialize(value, jgen, this); } } /* /********************************************************** /* Convenience methods /********************************************************** */ /** * Method that will handle serialization of Date(-like) values, using * {@link SerializationConfig} settings to determine expected serialization * behavior. * Note: date here means "full" date, that is, date AND time, as per * Java convention (and not date-only values like in SQL) */ public final void defaultSerializeDateValue(long timestamp, JsonGenerator jgen) throws IOException, JsonProcessingException { // [JACKSON-87]: Support both numeric timestamps and textual if (isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)) { jgen.writeNumber(timestamp); } else { jgen.writeString(_dateFormat().format(new Date(timestamp))); } } /** * Method that will handle serialization of Date(-like) values, using * {@link SerializationConfig} settings to determine expected serialization * behavior. * Note: date here means "full" date, that is, date AND time, as per * Java convention (and not date-only values like in SQL) */ public final void defaultSerializeDateValue(Date date, JsonGenerator jgen) throws IOException, JsonProcessingException { // [JACKSON-87]: Support both numeric timestamps and textual if (isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)) { jgen.writeNumber(date.getTime()); } else { jgen.writeString(_dateFormat().format(date)); } } /** * Method that will handle serialization of Dates used as {@link java.util.Map} keys, * based on {@link SerializationFeature#WRITE_DATE_KEYS_AS_TIMESTAMPS} * value (and if using textual representation, configured date format) */ public void defaultSerializeDateKey(long timestamp, JsonGenerator jgen) throws IOException, JsonProcessingException { if (isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)) { jgen.writeFieldName(String.valueOf(timestamp)); } else { jgen.writeFieldName(_dateFormat().format(new Date(timestamp))); } } /** * Method that will handle serialization of Dates used as {@link java.util.Map} keys, * based on {@link SerializationFeature#WRITE_DATE_KEYS_AS_TIMESTAMPS} * value (and if using textual representation, configured date format) */ public void defaultSerializeDateKey(Date date, JsonGenerator jgen) throws IOException, JsonProcessingException { if (isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)) { jgen.writeFieldName(String.valueOf(date.getTime())); } else { jgen.writeFieldName(_dateFormat().format(date)); } } public final void defaultSerializeNull(JsonGenerator jgen) throws IOException, JsonProcessingException { getDefaultNullValueSerializer().serialize(null, jgen, this); } /* /******************************************************** /* Helper methods /******************************************************** */ protected void _reportIncompatibleRootType(Object value, JavaType rootType) throws IOException, JsonProcessingException { /* 07-Jan-2010, tatu: As per [JACKSON-456] better handle distinction between wrapper types, * primitives */ if (rootType.isPrimitive()) { Class wrapperType = ClassUtil.wrapperType(rootType.getRawClass()); // If it's just difference between wrapper, primitive, let it slide if (wrapperType.isAssignableFrom(value.getClass())) { return; } } throw new JsonMappingException("Incompatible types: declared root type ("+rootType+") vs " +value.getClass().getName()); } /** * Method that will try to find a serializer, either from cache * or by constructing one; but will not return an "unknown" serializer * if this can not be done but rather returns null. * * @return Serializer if one can be found, null if not. */ protected JsonSerializer _findExplicitUntypedSerializer(Class runtimeType) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer ser = _knownSerializers.untypedValueSerializer(runtimeType); if (ser != null) { return ser; } // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(runtimeType); if (ser != null) { return ser; } return _createAndCacheUntypedSerializer(runtimeType); } /* /********************************************************** /* Low-level methods for actually constructing and initializing /* serializers /********************************************************** */ /** * Method that will try to construct a value serializer; and if * one is successfully created, cache it for reuse. */ protected JsonSerializer _createAndCacheUntypedSerializer(Class type) throws JsonMappingException { JsonSerializer ser; try { ser = _createUntypedSerializer(_config.constructType(type)); } catch (IllegalArgumentException iae) { /* We better only expose checked exceptions, since those * are what caller is expected to handle */ throw new JsonMappingException(iae.getMessage(), null, iae); } if (ser != null) { _serializerCache.addAndResolveNonTypedSerializer(type, ser, this); } return ser; } protected JsonSerializer _createAndCacheUntypedSerializer(JavaType type) throws JsonMappingException { JsonSerializer ser; try { ser = _createUntypedSerializer(type); } catch (IllegalArgumentException iae) { /* We better only expose checked exceptions, since those * are what caller is expected to handle */ throw new JsonMappingException(iae.getMessage(), null, iae); } if (ser != null) { _serializerCache.addAndResolveNonTypedSerializer(type, ser, this); } return ser; } /** * @since 2.1 */ protected JsonSerializer _createUntypedSerializer(JavaType type) throws JsonMappingException { // 17-Feb-2013, tatu: Used to call deprecated method (that passed property) return (JsonSerializer)_serializerFactory.createSerializer(this, type); } /** * Helper method called to resolve and contextualize given * serializer, if and as necessary. */ protected JsonSerializer _handleContextualResolvable(JsonSerializer ser, BeanProperty property) throws JsonMappingException { if (ser instanceof ResolvableSerializer) { ((ResolvableSerializer) ser).resolve(this); } return _handleContextual(ser, property); } @SuppressWarnings("unchecked") protected JsonSerializer _handleResolvable(JsonSerializer ser) throws JsonMappingException { if (ser instanceof ResolvableSerializer) { ((ResolvableSerializer) ser).resolve(this); } return (JsonSerializer) ser; } @SuppressWarnings("unchecked") protected JsonSerializer _handleContextual(JsonSerializer ser, BeanProperty property) throws JsonMappingException { if (ser instanceof ContextualSerializer) { ser = ((ContextualSerializer) ser).createContextual(this, property); } return (JsonSerializer) ser; } /* /********************************************************** /* Internal methods /********************************************************** */ protected final DateFormat _dateFormat() { if (_dateFormat != null) { return _dateFormat; } /* 24-Feb-2012, tatu: At this point, all timezone configuration * should have occured, with respect to default dateformat * and timezone configuration. But we still better clone * an instance as formatters may be stateful. */ DateFormat df = _config.getDateFormat(); _dateFormat = df = (DateFormat) df.clone(); return df; } } jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/annotation/000077500000000000000000000000001215056657300327045ustar00rootroot00000000000000JacksonStdImpl.java000066400000000000000000000014221215056657300363540ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/annotationpackage com.fasterxml.jackson.databind.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.fasterxml.jackson.annotation.JacksonAnnotation; /** * Marker interface used to indicate implementation classes * (serializers, deserializers etc) that are standard ones Jackson * uses; not custom ones that application has added. It can be * added in cases where certain optimizations can be made if * default instances are uses; for example when handling conversions * of "natural" JSON types like Strings, booleans and numbers. */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotation public @interface JacksonStdImpl { } JsonDeserialize.java000066400000000000000000000121721215056657300365650ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/annotationpackage com.fasterxml.jackson.databind.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.KeyDeserializer; import com.fasterxml.jackson.databind.util.Converter; /** * Annotation use for configuring deserialization aspects, by attaching * to "setter" methods or fields, or to value classes. * When annotating value classes, configuration is used for instances * of the value class but can be overridden by more specific annotations * (ones that attach to methods or fields). *

* An example annotation would be: *

 *  @JsonDeserialize(using=MySerializer.class,
 *    as=MyHashMap.class,
 *    keyAs=MyHashKey.class,
 *    contentAs=MyHashValue.class
 *  )
 *
*

*/ @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @com.fasterxml.jackson.annotation.JacksonAnnotation public @interface JsonDeserialize { // // // Annotations for explicitly specifying deserialize/builder /** * Deserializer class to use for deserializing associated value. * Depending on what is annotated, * value is either an instance of annotated class (used globablly * anywhere where class deserializer is needed); or only used for * deserializing property access via a setter method. */ public Class> using() default JsonDeserializer.None.class; /** * Deserializer class to use for deserializing contents (elements * of a Collection/array, values of Maps) of annotated property. * Can only be used on instances (methods, fields, constructors), * and not value classes themselves. */ public Class> contentUsing() default JsonDeserializer.None.class; /** * Deserializer class to use for deserializing Map keys * of annotated property. * Can only be used on instances (methods, fields, constructors), * and not value classes themselves. */ public Class keyUsing() default KeyDeserializer.None.class; /** * Annotation for specifying if an external Builder class is to * be used for building up deserialized instances of annotated * class. If so, an instance of referenced class is first constructed * (possibly using a Creator method; or if none defined, using default * constructor), and its "with-methods" are used for populating fields; * and finally "build-method" is invoked to complete deserialization. */ public Class builder() default NoClass.class; // // // Annotations for specifying intermediate Converters (2.2+) /** * Which helper object (if any) is to be used to convert from Jackson-bound * intermediate type (source type of converter) into actual property type * (which must be same as result type of converter). This is often used * for two-step deserialization; Jackson binds data into suitable intermediate * type (like Tree representation), and converter then builds actual property * type. * * @since 2.2 */ public Class> converter() default Converter.None.class; /** * Similar to {@link #converter}, but used for values of structures types * (List, arrays, Maps). * * @since 2.2 */ public Class> contentConverter() default Converter.None.class; // // // Annotations for explicitly specifying deserialization type // // // (which is used for choosing deserializer, if not explicitly // // // specified /** * Concrete type to deserialize values as, instead of type otherwise * declared. Must be a subtype of declared type; otherwise an * exception may be thrown by deserializer. *

* Bogus type {@link NoClass} can be used to indicate that declared * type is used as is (i.e. this annotation property has no setting); * this since annotation properties are not allowed to have null value. *

* Note: if {@link #using} is also used it has precedence * (since it directly specified * deserializer, whereas this would only be used to locate the * deserializer) * and value of this annotation property is ignored. */ public Class as() default NoClass.class; /** * Concrete type to deserialize keys of {@link java.util.Map} as, * instead of type otherwise declared. * Must be a subtype of declared type; otherwise an exception may be * thrown by deserializer. */ public Class keyAs() default NoClass.class; /** * Concrete type to deserialize content (elements * of a Collection/array, values of Maps) values as, * instead of type otherwise declared. * Must be a subtype of declared type; otherwise an exception may be * thrown by deserializer. */ public Class contentAs() default NoClass.class; } JsonNaming.java000066400000000000000000000010571215056657300355360ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/annotationpackage com.fasterxml.jackson.databind.annotation; import java.lang.annotation.*; import com.fasterxml.jackson.databind.PropertyNamingStrategy; /** * Annotation that can be used to indicate a {@link PropertyNamingStrategy} * to use for annotated class. Overrides the global (default) strategy. * * @since 2.1 */ @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @com.fasterxml.jackson.annotation.JacksonAnnotation public @interface JsonNaming { public Class value(); } JsonPOJOBuilder.java000066400000000000000000000046411215056657300364050ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/annotationpackage com.fasterxml.jackson.databind.annotation; import java.lang.annotation.*; /** * Annotation used to configure details of a Builder class: * instances of which are used as Builders for deserialized * POJO values, instead of POJOs being instantiated using * constructors or factory methods. * Note that this annotation is NOT used to define what is * the Builder class for a POJO: rather, this is determined * by {@link JsonDeserialize#builder} property of {@link JsonDeserialize}. *

* Annotation is typically used if the naming convention * of a Builder class is different from defaults: *

    *
* * @since 2.0 */ @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @com.fasterxml.jackson.annotation.JacksonAnnotation public @interface JsonPOJOBuilder { /** * Property to use for re-defining which zero-argument method * is considered the actual "build-method": method called after * all data has been bound, and the actual instance needs to * be instantiated. *

* Default value is "build". */ public String buildMethodName() default "build"; /** * Property used for (re)defining name prefix to use for * auto-detecting "with-methods": methods that are similar to * "set-methods" (in that they take an argument), but that * may also return the new builder instance to use * (which may be 'this', or a new modified builder instance). * Note that in addition to this prefix, it is also possible * to use {@link com.fasterxml.jackson.annotation.JsonProperty} * annotation to indicate "with-methods" (as well as * {@link com.fasterxml.jackson.annotation.JsonSetter}). *

* Default value is "with", so that method named "withValue()" * would be used for binding JSON property "value" (using type * indicated by the argument; or one defined with annotations. */ public String withPrefix() default "with"; /* /********************************************************** /* Helper classes /********************************************************** */ /** * Simple value container for containing values read from * {@link JsonPOJOBuilder} annotation instance. */ public class Value { public final String buildMethodName; public final String withPrefix; public Value(JsonPOJOBuilder ann) { buildMethodName = ann.buildMethodName(); withPrefix = ann.withPrefix(); } } } JsonSerialize.java000066400000000000000000000200761215056657300362560ustar00rootroot00000000000000jackson-databind-jackson-databind-2.2.2/src/main/java/com/fasterxml/jackson/databind/annotationpackage com.fasterxml.jackson.databind.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.util.Converter; /** * Annotation used for configuring serialization aspects, by attaching * to "getter" methods or fields, or to value classes. * When annotating value classes, configuration is used for instances * of the value class but can be overridden by more specific annotations * (ones that attach to methods or fields). *

* An example annotation would be: *

 *  @JsonSerialize(using=MySerializer.class,
 *    as=MySubClass.class,
 *    typing=JsonSerialize.Typing.STATIC
 *  )
 *
* (which would be redundant, since some properties block others: * specifically, 'using' has precedence over 'as', which has precedence * over 'typing' setting) */ @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @com.fasterxml.jackson.annotation.JacksonAnnotation public @interface JsonSerialize { // // // Annotations for explicitly specifying deserializer /** * Serializer class to use for * serializing associated value. Depending on what is annotated, * value is either an instance of annotated class (used globablly * anywhere where class serializer is needed); or only used for * serializing property access via a getter method. */ public Class> using() default JsonSerializer.None.class; /** * Serializer class to use for serializing contents (elements * of a Collection/array, values of Maps) of annotated property. * Can only be used on properties (methods, fields, constructors), * and not value classes themselves (as they are typically generic) */ public Class> contentUsing() default JsonSerializer.None.class; /** * Serializer class to use for serializing Map keys * of annotated property. * Can only be used on properties (methods, fields, constructors), * and not value classes themselves. */ public Class> keyUsing() default JsonSerializer.None.class; // // // Annotations for type handling, explicit declaration // // // (type used for choosing deserializer, if not explicitly // // // specified) /** * Supertype (of declared type, which itself is supertype of runtime type) * to use as type when locating serializer to use. *

* Bogus type {@link NoClass} can be used to indicate that declared * type is used as is (i.e. this annotation property has no setting); * this since annotation properties are not allowed to have null value. *

* Note: if {@link #using} is also used it has precedence * (since it directly specifies * serializer, whereas this would only be used to locate the * serializer) * and value of this annotation property is ignored. */ public Class as() default NoClass.class; /** * Concrete type to serialize keys of {@link java.util.Map} as, * instead of type otherwise declared. * Must be a supertype of declared type; otherwise an exception may be * thrown by serializer. */ public Class keyAs() default NoClass.class; /** * Concrete type to serialize content value (elements * of a Collection/array, values of Maps) as, * instead of type otherwise declared. * Must be a supertype of declared type; otherwise an exception may be * thrown by serializer. */ public Class contentAs() default NoClass.class; /** * Whether type detection used is dynamic or static: that is, * whether actual runtime type is used (dynamic), or just the * declared type (static). */ public Typing typing() default Typing.DYNAMIC; // // // Annotations for specifying intermediate Converters (2.2+) /** * Which helper object is to be used to convert type into something * that Jackson knows how to serialize; either because base type * can not be serialized easily, or just to alter serialization. * * @since 2.2 */ public Class> converter() default Converter.None.class; /** * Similar to {@link #converter}, but used for values of structures types * (List, arrays, Maps). * Note that this property does NOT have effect when used as Class annotation; * it can only be used as property annotation: this because association between * container and value types is loose and as such converters seldom make sense * for such usage. * * @since 2.2 */ public Class> contentConverter() default Converter.None.class; // // // Annotation(s) for inclusion criteria /** * Which properties of annotated Bean are * to be included in serialization (has no effect on other types * like enums, primitives or collections). * Choices are "all", "properties that have value other than null" * and "properties that have non-default value" (i.e. default value * being property setting for a Bean constructed with default no-arg * constructor, often null). * * @deprecated As of Jackson 2.0, this annotation has been replaced * by {@link com.fasterxml.jackson.annotation.JsonInclude} */ @Deprecated public Inclusion include() default Inclusion.ALWAYS; /* /********************************************************** /* Value enumerations needed /********************************************************** */ /** * Enumeration used with {@link JsonSerialize#include} property * to define which properties * of Java Beans are to be included in serialization */ public enum Inclusion { /** * Value that indicates that properties are to be always included, * independent of value */ ALWAYS, /** * Value that indicates that only properties with non-null * values are to be included. */ NON_NULL, /** * Value that indicates that only properties that have values * that differ from default settings (meaning values they have * when Bean is constructed with its no-arguments constructor) * are to be included. Value is generally not useful with * {@link java.util.Map}s, since they have no default values; * and if used, works same as {@link #ALWAYS}. */ NON_DEFAULT, /** * Value that indicates that only properties that have values * that values that are null or what is considered empty are * not to be included. * Emptiness is defined for following type: *