jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/ 0000775 0000000 0000000 00000000000 12516567542 0022450 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/.gitignore 0000664 0000000 0000000 00000000235 12516567542 0024440 0 ustar 00root root 0000000 0000000 # use glob syntax.
syntax: glob
*.class
*~
*.bak
*.off
*.old
.DS_Store
# building
target
# Eclipse
.classpath
.project
.settings
# IDEA
*.iml
*.ipr
*.iws
jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/README.md 0000664 0000000 0000000 00000020132 12516567542 0023725 0 ustar 00root root 0000000 0000000 # Overview
This projects contains [Jackson](http://wiki.fasterxml.com/JacksonHome) extension component for
reading and writing [XML](http://en.wikipedia.org/wiki/Xml) encoded data.
Further, the goal is to emulate how [JAXB](http://en.wikipedia.org/wiki/JAXB) data-binding works
with "Code-first" approach (that is, no support is added for "Schema-first" approach).
Support for JAXB annotations is provided by [JAXB annotation module](https://github.com/FasterXML/jackson-module-jaxb-annotations);
this module provides low-level abstractions (`JsonParser`, `JsonGenerator`, `JsonFactory`) as well as small number of higher level
overrides needed to make data-binding work.
It is worth noting, however, that the goal is NOT to be full JAXB clone; or to be general purpose XML toolkit.
Specifically:
* While XML serialization should ideally be similar to JAXB output, deviations are not necessarily considered bugs -- we do "best-effort" matching
* What should be guaranteed is that any XML written using this module must be readable using module as well: that is, we do aim for full XML serialization.
* From above: there are XML constructs that module will not be able to handle; including some cases JAXB supports
* This module may, however, also support constructs and use cases JAXB does not handle: specifically, rich type and object id support of Jackson are supported.
[](https://fasterxml.ci.cloudbees.com/job/jackson-dataformat-xml-master/)
# Status
As of version 2.3, module is fully functional and considered production ready.
## Maven dependency
To use Jackson 2.x compatible version of this extension on Maven-based projects, use following dependency:
```xml
com.fasterxml.jackson.dataformatjackson-dataformat-xml2.4.0
```
(or whatever version is most up-to-date at the moment)
Also: you usually also want to make sure that XML library in use is [Woodstox](http://wiki.fasterxml.com/WoodstoxHome) since it is not only faster than Stax implementation JDK provides, but also works better and avoids some known issues like adding unnecessary namespace prefixes.
You can do this by adding this in your `pom.xml`:
```xml
org.codehaus.woodstoxwoodstox-core-asl4.1.4
```
# Usage
Although module implements low-level (`JsonFactory` / `JsonParser` / `JsonGenerator`) abstractions,
most usage is through data-binding level. This because a small number of work-arounds have been added
at data-binding level, to work around XML peculiarities: that is, stream of `JsonToken`s that parser
produces has idiosyncracies that need special handling.
Usually you either create `XmlMapper` simply by:
```java
XmlMapper mapper = new XmlMapper();
```
but in case you need to configure settings, you will want to do:
```java
JacksonXmlModule module = new JacksonXmlModule();
// and then configure, for example:
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);
// and you can also configure AnnotationIntrospectors etc here:
```
as many features that `XmlMapper` needs are provided by `JacksonXmlModule`; default
`XmlMapper` simply constructs module with default settings.
## Serializing POJOs as XML
Serialization is done very similar to JSON serialization: all that needs to change is `ObjectMapper` instance to use:
```java
// Important: create XmlMapper; it will use proper factories, workarounds
ObjectMapper xmlMapper = new XmlMapper();
String xml = xmlMapper.writeValueAsString(new Simple());
// or
xmlMapper.writeValue(new File("/tmp/stuff.json"), new Simple());
```
and with POJO like:
```java
public class Simple {
public int x = 1;
public int y = 2;
}
```
you would get something like:
```xml
12
```
(except that by default output is not indented: you can enabled indentation using standard Jackson mechanisms)
## Deserializing POJOs from XML
Similar to serialization, deserialization is not very different from JSON deserialization:
```java
ObjectMapper xmlMapper = new XmlMapper();
Simple value = xmlMapper.readValue("12", Simple.class);
```
## Incremental/partial reading/writing (2.4+)
It is also possible to do incremental writes. This is done by creating Stax
`XMLInputFactory` separately (similar to how with JSON you would create `JsonGenerator`), and then:
```java
// First create Stax components we need
XMLInputFactory f = XMLInputFactory.newFactory();
StringWriter out = new StringWriter();
XMLStreamWriter sw = f.createXMLStreamWriter(out);
// then Jackson components
XmlMapper mapper = new XmlMapper(f);
sw.writeStartDocument();
sw.writeStartElement("root");
// Write whatever content POJOs...
SomePojo value1 = ...;
OtherPojo value2 = ...;
mapper.writeValue(sw, value1);
mapper.writeValue(sw, value2);
// and/or regular Stax output
sw.writeComment("Some insightful commentary here");
sw.writeEndElement();
sw.writeEndDocument();
```
Similarly it is possible to read content, sub-tree by sub-tree; assuming similar XML content
we would use
```java
XMLOutputFactory f = XMLOutputFactory.newFactory();
File inputFile = ...;
XMLStreamReader sr = f.createXMLStreamReader(new FileInputStream(inputFile));
XmlMapper mapper = new XmlMapper();
sr.next(); // to point to
sr.next(); // to point to root-element under root
SomePojo value1 = mapper.readValue(sr, SomePojo.class);
// sr now points to matching END_ELEMENT, so move forward
sr.next(); // should verify it's either closing root or new start, left as exercise
OtherPojo value = mapper.readValue(sr, OtherPojo.class);
// and more, as needed, then
sr.close();
```
## Additional annotations
In addition to standard [Jackson annotations](https://github.com/FasterXML/jackson-annotations) and optional JAXB (`javax.xml.bind.annotation`), this project also adds couple of its own annotations for convenience, to support XML-specific details:
* `@JacksonXmlElementWrapper` allows specifying XML element to use for wrapping `List` and `Map` properties
* `@JacksonXmlProperty` allows specifying XML namespace and local name for a property; as well as whether property is to be written as an XML element or attribute.
* `@JacksonXmlRootElement` allows specifying XML element to use for wrapping the root element (default uses 'simple name' of the value class)
* `@JacksonXmlText` allows specifying that value of one property is to be serialized as "unwrapped" text, and not in an element.
* `@JacksonXmlCData` allows specifying that the value of a property is to be serialized within a CData tag.
for longer description, check out [XML module annotations](https://github.com/FasterXML/jackson-dataformat-xml/wiki/Jackson-XML-annotations).
## Known Limitations
Currently, following limitations exist beyond basic Jackson (JSON) limitations:
* Root value should be a POJO; and specifically following types can be serialized as properties but not as root values:
* Java arrays
* `java.util.Collection` values (Lists, Sets)
* `Enum`s (support for these may be added in future -- but not as of 2.4)
* Lists and arrays are "wrapped" by default, when using Jackson annotations, but unwrapped when using JAXB annotations (if supported, see below)
* Unwrapped List/array support was added in Jackson 2.1 (2.0 does NOT support them; arrays are always wrapped)
* `@JacksonXmlElementWrapper.useWrapping` can be set to 'false' to disable wrapping
* `JacksonXmlModule.setDefaultUseWrapper()` can be used to specify whether "wrapped" or "unwrapped" setting is the default
* Tree Model is only supported in limited fashion: specifically, Java arrays and `Collection`s can be written, but can not be read, since it is not possible to distinguish Arrays and Objects without additional information.
# See Also
* XML module [wiki page](https://github.com/FasterXML/jackson-dataformat-xml/wiki) for more information
* Using XML with [DropWizard](https://github.com/dropwizard/dropwizard)? Check out [this extension](https://github.com/yunspace/dropwizard-xml)!
jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/pom.xml 0000664 0000000 0000000 00000014624 12516567542 0023774 0 ustar 00root root 0000000 0000000
4.0.0com.fasterxml.jacksonjackson-parent2.5.1com.fasterxml.jackson.dataformatjackson-dataformat-xml2.5.3Jackson-dataformat-XMLbundleData format extension for Jackson (http://jackson.codehaus.org) to offer
alternative support for serializing POJOs as XML and deserializing XML as pojos.
Support implemented on top of Stax API (javax.xml.stream), by implementing core Jackson Streaming API types like JsonGenerator, JsonParser and JsonFactory.
Some data-binding types overridden as well (ObjectMapper sub-classed as XmlMapper).
http://wiki.fasterxml.com/JacksonExtensionXmlDataBindingscm:git:git@github.com:FasterXML/jackson-dataformat-xml.gitscm:git:git@github.com:FasterXML/jackson-dataformat-xml.githttp://github.com/FasterXML/jackson-dataformat-xmljackson-dataformat-xml-2.5.32.5.02.5.3${version.jackson.core}com/fasterxml/jackson/dataformat/xml${project.groupId}.xmlcom.fasterxml.jackson.dataformat.xml
,com.fasterxml.jackson.dataformat.xml.annotation
,com.fasterxml.jackson.dataformat.xml.deser
,com.fasterxml.jackson.dataformat.xml.jaxb
,com.fasterxml.jackson.dataformat.xml.ser
,com.fasterxml.jackson.dataformat.xml.utiljavax.xml.bind.annotation, javax.xml.namespace, javax.xml.stream, javax.xml.transform
,org.codehaus.stax2, org.codehaus.stax2.io, org.codehaus.stax2.ri
,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.type, com.fasterxml.jackson.core.util
,com.fasterxml.jackson.databind
,com.fasterxml.jackson.databind.cfg
,com.fasterxml.jackson.databind.deser
,com.fasterxml.jackson.databind.deser.std
,com.fasterxml.jackson.databind.introspect, com.fasterxml.jackson.databind.module
,com.fasterxml.jackson.databind.jsontype, com.fasterxml.jackson.databind.jsontype.impl
,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.module.jaxbcom.fasterxml.jackson.corejackson-core${version.jackson.core}com.fasterxml.jackson.corejackson-annotations${version.jackson.annotations}com.fasterxml.jackson.corejackson-databind${version.jackson.core}com.fasterxml.jackson.modulejackson-module-jaxb-annotations${version.jackson.jaxb}javax.xml.streamstax-api1.0-2providedorg.codehaus.woodstoxstax2-api3.1.4org.codehaus.woodstoxwoodstox-core-asl4.3.0testcom.google.code.maven-replacer-pluginreplacerprocess-packageVersiongenerate-sourcesorg.apache.maven.pluginsmaven-surefire-plugin${version.plugin.surefire}com/fasterxml/jackson/dataformat/xml/failing/*.java**/Test*.java**/*Test.javaforce-releasetruetrue
jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/release-notes/ 0000775 0000000 0000000 00000000000 12516567542 0025216 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/release-notes/CREDITS 0000664 0000000 0000000 00000001226 12516567542 0026237 0 ustar 00root root 0000000 0000000 Here are people who have contributed to development of this project:
(version numbers in brackets indicate release in which the problem was fixed)
Tatu Saloranta, tatu.saloranta@iki.fi: author
Sebastien Dionne:
* Suggested Issue-23: Add @JacksonXmlText annotation (alias for JAXB @XmlValue),
to support case of property values as 'unwrapped' text
(2.0.1)
Pascal Gelinas:
* Reported and fixed #84: Problem with @JacksonXmlText when property output is suppressed
(2.3.1)
* Reported and fixed #83: Add support for @JsonUnwrapped
(2.4.0)
Dan Jasek: (oillio@github)
* Contributed #126: Allow specifying properties that should be written as CData
(2.5.0)
jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/release-notes/VERSION 0000664 0000000 0000000 00000012234 12516567542 0026270 0 ustar 00root root 0000000 0000000 Project: jackson-dataformat-xml
------------------------------------------------------------------------
= Releases
------------------------------------------------------------------------
2.5.3 (24-Apr-2015)
2.5.2 (29-Mar-2015)
No changes since 2.5.1
2.5.1 (06-Feb-2015)
#133: Performance regression (2.4->2.5), 10% slower write via databind
2.5.0 (01-Jan-2015)
#120: Encoding not taken in account
(reported by Sébastien D, sdeleuze@github)
#126: Allow specifying properties that should be written as CData
(contributed by Dan J)
#129: Unwrapped collection containing empty CDATA not deserialized correctly
(reported by tjconsult@github)
2.4.6 (not yet released)
- Improvement to `JsonParser.useDefaultPrettyPrinter()` override (wrt #136)
2.4.5 (13-Jan-2015)
2.4.4 (24-Nov-2014)
2.4.3 (04-Oct-2014)
2.4.2 (15-Aug-2014)
No changes.
2.4.1 (17-Jun-2014)
#117: @JsonAnyGetter + @JsonTypeInfo combination prevents serialization of properties as elements
(reported by gawi@github)
2.4.0 (02-Jun-2014)
#76: UnrecognizedPropertyException when containing object is a Collection
(reported by pierre@github)
#83: Add support for @JsonUnwrapped
(contributed by Pascal G)
#99: Problem with DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Lists
(reported by anton0xf@github)
#108: Unwrapped list ignore attributes if 2 lists in sequence
#111: Make vanilla `JaxbAnnotationIntrospector` work, without having to
use `XmlJaxbAnnotationIntrospector`
#115: Allow incremental reading/writing with existing `XMLStreamReader`
and `XMLStreamWriter`.
- Add `JsonFactory.canUseCharArrays()` introspection method
2.3.3 (10-Apr-2014)
#101: Invalid index error when deserializing unwrapped list element with multiple attributes
(reported by yunspace@github; fix suggested by escholz@github)
2.3.2 (01-Mar-2014)
#81: Serialization of a polymorphic class As.Property with Identity info doesn't work
(fixed by Pascal G)
#91: @JsonPropertyOrder not working correctly with attributes
(reported by thrykol@github)
2.3.1 (28-Dec-2013)
#84: Problem with @JacksonXmlText when property output is suppressed
(contributed by Pascal G)
2.3.0 (14-Nov-2013)
#38: Support root-level Collection serialization
#64: Problems deserializing unwrapped lists, with optional (and missing) attribute.
#71: Fix issues with `XmlMapper.convertValue()`
- Add support for `JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN`
- Improved indentation
2.2.3 (22-Aug-2013):
No functional changes.
2.2.2 (31-May-2013)
#66: @JacksonXmlText should imply existence of property (without explicit marking)
(suggested by ShijunK@github)
2.2.1 (03-May-2013)
- Fixed problems with `XmlFactory.copy()` not calling underlying JsonFactory
settings
2.2.0 (22-Apr-2013)
#47: First attribute of list value elements ignored
(reported by dewthefifth@github)
#55: Problems deserializing wrapped lists (annotations not properly recognized)
#56: Indenting disables @JacksonXmlText
(reported by edrik@github)
2.1.3 (19-Jan-2013)
* [JACKSON-879]: Missing OSGi import for 'com.fasterxml.jackson.databind.deser.std'
causing error trying to load 'DelegatingDeserializer' base class.
(reported by Martin S)
* [Issue#45]: Indentation should not be added if element only has attributes
* More fixes to [Issue#48], wrt thaw/unthaw
2.1.2 (04-Dec-2012)
* [Issue#42]: Problems with custom serializers, `JsonGenerator.writeObjectField`
(reported by matejj@github)
* [Issue#44]: Problems with FilterProvider, serialization, annotations
(reported by lalmeras@github)
* [Issue#46]: Indentation not working for unwrapped Lists
(reported by lalmeras@github)
* [Issue#48]: 'XmlMapper.copy()' was missing copy of some fields in `XmlFactory`
(reported by Sean B)
2.1.1 (12-Nov-2012)
* [Issue#39]: Improve error reporting when trying to use non-Stax2
implementation, indentation
* [Issue#41]: Custom (de)serializer registration not working with
JacksonXmlModule
(reported by matejj@github)
2.1.0 (08-Oct-2012)
New minor version, with following changes:
* [Issue#6]: Add support for "unwrapped lists"; now unwrapped is also default
when using JAXB annotations (but not with Jackson annotations, for backwards
compatibility). @JacksonXmlElementWrapper allows explicit per-property
overrides
* [Issue#30]: (from JAXB module, issue #11) Now `@XmlIDREF` forces use of
id value for serialization of a reference property.
* [Issue#33]: Ignore attributes of elements for "List" objects
* [Issue#36]: Add 'JacksonXmlModule.setXMLTextElementName()' to allow
matching 'value' text property of JAXB beans.
2.0.5 (27-Jul-2012)
* [Issue-29]: Binary value not cleared, leading to duplicated binary data
for POJOs.
(reported by 'farfalena'@git)
2.0.4 (26-Jun-2012)
no new fixes, dependencies to core components updated.
2.0.3 (15-Jun-2012)
* [Issue#26]: Root element should use 'default namespace'
2.0.2 (14-May-2012)
No fixes, updates dependencies.
2.0.1 (14-Apr-2012)
* [Issue#23]: Add @JacksonXmlText annotation (alias for JAXB @XmlValue), to
support case of text value with attributes
(requested by Sebastian D)
2.0.0 (25-Mar-2012)
* [Issue#19]: Strange behavior with namespace generation when using 'isAttribute = true'
(reported by Morten-Olav H)
[entries for version 1.x not retained)
jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/ 0000775 0000000 0000000 00000000000 12516567542 0023237 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/ 0000775 0000000 0000000 00000000000 12516567542 0024163 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/ 0000775 0000000 0000000 00000000000 12516567542 0025104 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/ 0000775 0000000 0000000 00000000000 12516567542 0025662 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/ 0000775 0000000 0000000 00000000000 12516567542 0027667 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/ 0000775 0000000 0000000 00000000000 12516567542 0031317 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/ 0000775 0000000 0000000 00000000000 12516567542 0033441 5 ustar 00root root 0000000 0000000 0000775 0000000 0000000 00000000000 12516567542 0034162 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml JacksonXmlAnnotationIntrospector.java 0000664 0000000 0000000 00000014547 12516567542 0043560 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package com.fasterxml.jackson.dataformat.xml;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
import com.fasterxml.jackson.dataformat.xml.annotation.*;
/**
* Extension of {@link JacksonAnnotationIntrospector} that is needed to support
* additional xml-specific annotation that Jackson provides. Note, however, that
* there is no JAXB annotation support here; that is provided with
* separate introspector (see
* {@link com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector}).
*/
public class JacksonXmlAnnotationIntrospector
extends JacksonAnnotationIntrospector
implements XmlAnnotationIntrospector
{
private static final long serialVersionUID = 1L;
/**
* For backwards compatibility with 2.0, the default behavior is
* to assume use of List wrapper if no annotations are used.
*/
public final static boolean DEFAULT_USE_WRAPPER = true;
protected final boolean _cfgDefaultUseWrapper;
public JacksonXmlAnnotationIntrospector() {
this(DEFAULT_USE_WRAPPER);
}
public JacksonXmlAnnotationIntrospector(boolean defaultUseWrapper) {
_cfgDefaultUseWrapper = defaultUseWrapper;
}
/*
/**********************************************************************
/* Overrides of JacksonAnnotationIntrospector impls
/**********************************************************************
*/
@Override
public PropertyName findWrapperName(Annotated ann)
{
JacksonXmlElementWrapper w = ann.getAnnotation(JacksonXmlElementWrapper.class);
if (w != null) {
// Special case: wrapping explicitly blocked?
if (!w.useWrapping()) {
return PropertyName.NO_NAME;
}
// also: need to ensure we use marker:
String localName = w.localName();
if (localName == null || localName.length() == 0) {
return PropertyName.USE_DEFAULT;
}
return PropertyName.construct(w.localName(), w.namespace());
}
/* 09-Sep-2012, tatu: In absence of configurating we need to use our
* default settings...
*/
if (_cfgDefaultUseWrapper) {
return PropertyName.USE_DEFAULT;
}
return null;
}
@Override
public PropertyName findRootName(AnnotatedClass ac)
{
JacksonXmlRootElement root = ac.getAnnotation(JacksonXmlRootElement.class);
if (root != null) {
String local = root.localName();
String ns = root.namespace();
if (local.length() == 0 && ns.length() == 0) {
return PropertyName.USE_DEFAULT;
}
return new PropertyName(local, ns);
}
return super.findRootName(ac);
}
/*
/**********************************************************************
/* XmlAnnotationIntrospector, findXxx
/**********************************************************************
*/
@Override
public String findNamespace(Annotated ann)
{
JacksonXmlProperty prop = ann.getAnnotation(JacksonXmlProperty.class);
if (prop != null) {
return prop.namespace();
}
return null;
}
/*
/**********************************************************************
/* XmlAnnotationIntrospector, isXxx methods
/**********************************************************************
*/
@Override
public Boolean isOutputAsAttribute(Annotated ann)
{
JacksonXmlProperty prop = ann.getAnnotation(JacksonXmlProperty.class);
if (prop != null) {
return prop.isAttribute() ? Boolean.TRUE : Boolean.FALSE;
}
return null;
}
@Override
public Boolean isOutputAsText(Annotated ann)
{
JacksonXmlText prop = ann.getAnnotation(JacksonXmlText.class);
if (prop != null) {
return prop.value() ? Boolean.TRUE : Boolean.FALSE;
}
return null;
}
@Override
public Boolean isOutputAsCData(Annotated ann) {
JacksonXmlCData prop = ann.getAnnotation(JacksonXmlCData.class);
if (prop != null) {
return prop.value() ? Boolean.TRUE : Boolean.FALSE;
}
return null;
}
/*
/**********************************************************************
/* Overrides for name, property detection
/**********************************************************************
*/
@Override
public PropertyName findNameForSerialization(Annotated a)
{
PropertyName name = _findXmlName(a);
if (name == null) {
name = super.findNameForSerialization(a);
if (name == null) {
if (a.hasAnnotation(JacksonXmlText.class)) {
return PropertyName.USE_DEFAULT;
}
}
}
return name;
}
@Override
public PropertyName findNameForDeserialization(Annotated a)
{
PropertyName name = _findXmlName(a);
if (name == null) {
name = super.findNameForDeserialization(a);
if (name == null) {
if (a.hasAnnotation(JacksonXmlText.class)) {
return PropertyName.USE_DEFAULT;
}
}
}
return name;
}
/*
/**********************************************************************
/* Overrides for non-public helper methods
/**********************************************************************
*/
/**
* We will override this method so that we can return instance
* that cleans up type id property name to be a valid xml name.
*/
@Override
protected StdTypeResolverBuilder _constructStdTypeResolverBuilder() {
return new XmlTypeResolverBuilder();
}
/*
/**********************************************************************
/* Internal methods
/**********************************************************************
*/
protected PropertyName _findXmlName(Annotated a)
{
JacksonXmlProperty pann = a.getAnnotation(JacksonXmlProperty.class);
if (pann != null) {
return PropertyName.construct(pann.localName(), pann.namespace());
}
return null;
}
}
JacksonXmlModule.java 0000664 0000000 0000000 00000011326 12516567542 0040247 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package com.fasterxml.jackson.dataformat.xml;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
import com.fasterxml.jackson.dataformat.xml.deser.XmlBeanDeserializerModifier;
import com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializerModifier;
/**
* Module that implements most functionality needed to support producing and
* consuming XML instead of JSON.
*/
public class JacksonXmlModule
extends SimpleModule
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Determination of whether indexed properties (arrays, Lists) that are not explicitly
* annotated (with {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper}
* or equivalent) should default to using implicit wrapper (with same name as property) or not.
* If enabled, wrapping is used by default; if false, it is not.
*
* Note that JAXB annotation introspector always assumes "do not wrap by default".
* Jackson annotations have different default due to backwards compatibility.
*
* @since 2.1
*/
protected boolean _cfgDefaultUseWrapper = JacksonXmlAnnotationIntrospector.DEFAULT_USE_WRAPPER;
/**
* Name used for pseudo-property used for returning XML Text value (which does
* not have actual element name to use). Defaults to empty String, but
* may be changed for interoperability reasons: JAXB, for example, uses
* "value" as name.
*
* @since 2.1
*/
protected String _cfgNameForTextElement = FromXmlParser.DEFAULT_UNNAMED_TEXT_PROPERTY;
/*
/**********************************************************************
/* Life-cycle: construction
/**********************************************************************
*/
public JacksonXmlModule()
{
super("JackxonXmlModule", PackageVersion.VERSION);
}
@Override
public void setupModule(SetupContext context)
{
// Need to modify BeanDeserializer, BeanSerializer that are used
context.addBeanSerializerModifier(new XmlBeanSerializerModifier());
context.addBeanDeserializerModifier(new XmlBeanDeserializerModifier(_cfgNameForTextElement));
// as well as AnnotationIntrospector
context.insertAnnotationIntrospector(_constructIntrospector());
// and finally inform XmlFactory about overrides, if need be:
if (_cfgNameForTextElement != FromXmlParser.DEFAULT_UNNAMED_TEXT_PROPERTY) {
XmlMapper m = (XmlMapper) context.getOwner();
m.setXMLTextElementName(_cfgNameForTextElement);
}
/* Usually this would be the first call; but here anything added will
* be stuff user may has added, so do it afterwards instead.
*/
super.setupModule(context);
}
/*
/**********************************************************************
/* Life-cycle: configuration
/**********************************************************************
*/
/**
* Method that can be used to define whether {@link AnnotationIntrospector}
* we register will use wrapper for indexed (List, array) properties or not,
* if there are no explicit annotations.
* See {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper}
* for details.
*
* Note that method MUST be called before registering the module; otherwise change
* will not have any effect.
*
* @param state Whether to enable or disable "use wrapper for non-annotated List properties"
*
* @since 2.1
*/
public void setDefaultUseWrapper(boolean state) {
_cfgDefaultUseWrapper = state;
}
/**
* Method that can be used to define alternate "virtual name" to use
* for XML CDATA segments; that is, text values. Default name is empty String
* (""); but some frameworks use other names: JAXB, for example, uses
* "value".
*
* Note that method MUST be called before registering the module; otherwise change
* will not have any effect.
*
* @param name Virtual name to use when exposing XML character data sections
*
* @since 2.1
*/
public void setXMLTextElementName(String name) {
_cfgNameForTextElement = name;
}
/*
/**********************************************************************
/* Internal methods
/**********************************************************************
*/
protected AnnotationIntrospector _constructIntrospector() {
return new JacksonXmlAnnotationIntrospector(_cfgDefaultUseWrapper);
}
}
PackageVersion.java.in 0000664 0000000 0000000 00000001107 12516567542 0040332 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package @package@;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.Versioned;
import com.fasterxml.jackson.core.util.VersionUtil;
/**
* Automatically generated from PackageVersion.java.in during
* packageVersion-generate execution of maven-replacer-plugin in
* pom.xml.
*/
public final class PackageVersion implements Versioned {
public final static Version VERSION = VersionUtil.parseVersion(
"@projectversion@", "@projectgroupid@", "@projectartifactid@");
@Override
public Version version() {
return VERSION;
}
}
XmlAnnotationIntrospector.java 0000664 0000000 0000000 00000013663 12516567542 0042245 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package com.fasterxml.jackson.dataformat.xml;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
/**
* Additional extension interface used above and beyond
* {@link AnnotationIntrospector} to handle XML-specific configuration.
*/
public interface XmlAnnotationIntrospector
{
/**
* Method that can be called to figure out generic namespace
* property for an annotated object.
*
* @return Null if annotated thing does not define any
* namespace information; non-null namespace (which may
* be empty String) otherwise
*/
public String findNamespace(Annotated ann);
/**
* Method used to check whether given annotated element
* (field, method, constructor parameter) has indicator that suggests
* it be output as an XML attribute or not (as element)
*/
public Boolean isOutputAsAttribute(Annotated ann);
/**
* Method used to check whether given annotated element
* (field, method, constructor parameter) has indicator that suggests
* it should be serialized as text, without element wrapper.
*/
public Boolean isOutputAsText(Annotated ann);
/**
* Method used to check whether given annotated element
* (field, method, constructor parameter) has indicator that suggests
* it should be wrapped in a CDATA tag.
*/
public Boolean isOutputAsCData(Annotated ann);
/*
/**********************************************************************
/* Replacement of 'AnnotationIntrospector.Pair' to use when combining
/* (potential) XMLAnnotationIntrospector instance
/**********************************************************************
*/
/**
* Extension of AnnotationIntrospector.Pair that can
* also dispatch 'XmlAnnotationIntrospector' methods.
*/
public static class Pair extends AnnotationIntrospectorPair
implements XmlAnnotationIntrospector
{
private static final long serialVersionUID = 1L;
protected final XmlAnnotationIntrospector _xmlPrimary;
protected final XmlAnnotationIntrospector _xmlSecondary;
public Pair(AnnotationIntrospector p, AnnotationIntrospector s)
{
super(p, s);
if (p instanceof XmlAnnotationIntrospector) {
_xmlPrimary = (XmlAnnotationIntrospector) p;
} else if (p instanceof JaxbAnnotationIntrospector) {
_xmlPrimary = new JaxbWrapper((JaxbAnnotationIntrospector) p);
} else {
_xmlPrimary = null;
}
if (s instanceof XmlAnnotationIntrospector) {
_xmlSecondary = (XmlAnnotationIntrospector) s;
} else if (s instanceof JaxbAnnotationIntrospector) {
_xmlSecondary = new JaxbWrapper((JaxbAnnotationIntrospector) s);
} else {
_xmlSecondary = null;
}
}
public static XmlAnnotationIntrospector.Pair instance(AnnotationIntrospector a1, AnnotationIntrospector a2) {
return new XmlAnnotationIntrospector.Pair(a1, a2);
}
@Override
public String findNamespace(Annotated ann)
{
String value = (_xmlPrimary == null) ? null : _xmlPrimary.findNamespace(ann);
if (value == null && _xmlSecondary != null) {
value = _xmlSecondary.findNamespace(ann);
}
return value;
}
@Override
public Boolean isOutputAsAttribute(Annotated ann)
{
Boolean value = (_xmlPrimary == null) ? null : _xmlPrimary.isOutputAsAttribute(ann);
if (value == null && _xmlSecondary != null) {
value = _xmlSecondary.isOutputAsAttribute(ann);
}
return value;
}
@Override
public Boolean isOutputAsText(Annotated ann)
{
Boolean value = (_xmlPrimary == null) ? null : _xmlPrimary.isOutputAsText(ann);
if (value == null && _xmlSecondary != null) {
value = _xmlSecondary.isOutputAsText(ann);
}
return value;
}
@Override
public Boolean isOutputAsCData(Annotated ann) {
Boolean value = (_xmlPrimary == null) ? null : _xmlPrimary.isOutputAsCData(ann);
if (value == null && _xmlSecondary != null) {
value = _xmlSecondary.isOutputAsCData(ann);
}
return value;
}
}
/*
/**********************************************************************
/* Helper class used to adapt JaxbAnnoationIntrospector as
/* XmlAnnotationIntrospector
/**********************************************************************
*/
/**
* Wrapper we need to adapt {@link JaxbAnnotationIntrospector} as
* {@link XmlAnnotationIntrospector}: something we can not (alas!)
* do in JAXB module because of dependency direction (JAXB module
* has no knowledge of this module).
*/
static class JaxbWrapper implements XmlAnnotationIntrospector
{
protected final JaxbAnnotationIntrospector _intr;
public JaxbWrapper(JaxbAnnotationIntrospector i) {
_intr = i;
}
@Override
public String findNamespace(Annotated ann) {
return _intr.findNamespace(ann);
}
@Override
public Boolean isOutputAsAttribute(Annotated ann) {
return _intr.isOutputAsAttribute(ann);
}
@Override
public Boolean isOutputAsText(Annotated ann) {
return _intr.isOutputAsText(ann);
}
@Override
public Boolean isOutputAsCData(Annotated ann) {
//There is no CData annotation in JAXB
return null;
}
}
}
XmlFactory.java 0000664 0000000 0000000 00000065220 12516567542 0037122 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package com.fasterxml.jackson.dataformat.xml;
import java.io.*;
import javax.xml.stream.*;
import org.codehaus.stax2.io.Stax2ByteArraySource;
import org.codehaus.stax2.io.Stax2CharArraySource;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.format.InputAccessor;
import com.fasterxml.jackson.core.format.MatchStrength;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.util.VersionUtil;
import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.dataformat.xml.util.StaxUtil;
/**
* Factory used for constructing {@link FromXmlParser} and {@link ToXmlGenerator}
* instances.
*
* Implements {@link JsonFactory} since interface for constructing XML backed
* parsers and generators is quite similar to dealing with JSON.
*
* @author Tatu Saloranta (tatu.saloranta@iki.fi)
*/
public class XmlFactory extends JsonFactory
{
// For 2.5:
private static final long serialVersionUID = 1897624416641000209L;
/**
* Name used to identify XML format
* (and returned by {@link #getFormatName()}
*/
public final static String FORMAT_NAME_XML = "XML";
/**
* Bitfield (set of flags) of all parser features that are enabled
* by default.
*/
final static int DEFAULT_XML_PARSER_FEATURE_FLAGS = FromXmlParser.Feature.collectDefaults();
/**
* Bitfield (set of flags) of all generator features that are enabled
* by default.
*/
final static int DEFAULT_XML_GENERATOR_FEATURE_FLAGS = ToXmlGenerator.Feature.collectDefaults();
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
protected int _xmlParserFeatures;
protected int _xmlGeneratorFeatures;
// non-final for setters (why are they needed again?)
protected transient XMLInputFactory _xmlInputFactory;
protected transient XMLOutputFactory _xmlOutputFactory;
protected String _cfgNameForTextElement;
/*
/**********************************************************
/* Factory construction, configuration
/**********************************************************
*/
/**
* Default constructor used to create factory instances.
* Creation of a factory instance is a light-weight operation,
* but it is still a good idea to reuse limited number of
* factory instances (and quite often just a single instance):
* factories are used as context for storing some reused
* processing objects (such as symbol tables parsers use)
* and this reuse only works within context of a single
* factory instance.
*/
public XmlFactory() { this(null, null, null); }
public XmlFactory(ObjectCodec oc) {
this(oc, null, null);
}
public XmlFactory(XMLInputFactory xmlIn) {
this(null, xmlIn, null);
}
public XmlFactory(XMLInputFactory xmlIn, XMLOutputFactory xmlOut) {
this(null, xmlIn, xmlOut);
}
public XmlFactory(ObjectCodec oc, XMLInputFactory xmlIn, XMLOutputFactory xmlOut)
{
this(oc, DEFAULT_XML_PARSER_FEATURE_FLAGS, DEFAULT_XML_GENERATOR_FEATURE_FLAGS,
xmlIn, xmlOut, null);
}
protected XmlFactory(ObjectCodec oc, int xpFeatures, int xgFeatures,
XMLInputFactory xmlIn, XMLOutputFactory xmlOut,
String nameForTextElem)
{
super(oc);
_xmlParserFeatures = xpFeatures;
_xmlGeneratorFeatures = xgFeatures;
_cfgNameForTextElement = nameForTextElem;
if (xmlIn == null) {
xmlIn = XMLInputFactory.newInstance();
}
if (xmlOut == null) {
xmlOut = XMLOutputFactory.newInstance();
}
_initFactories(xmlIn, xmlOut);
_xmlInputFactory = xmlIn;
_xmlOutputFactory = xmlOut;
}
/**
* @since 2.2.1
*/
protected XmlFactory(XmlFactory src, ObjectCodec oc)
{
super(src, oc);
_xmlParserFeatures = src._xmlParserFeatures;
_xmlGeneratorFeatures = src._xmlGeneratorFeatures;
_cfgNameForTextElement = src._cfgNameForTextElement;
_xmlInputFactory = src._xmlInputFactory;
_xmlOutputFactory = src._xmlOutputFactory;
}
protected void _initFactories(XMLInputFactory xmlIn, XMLOutputFactory xmlOut)
{
// Better ensure namespaces get built properly, so:
xmlOut.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
// and for parser, force coalescing as well (much simpler to use)
xmlIn.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
}
/**
* Note: compared to base implementation by {@link JsonFactory},
* here the copy will actually share underlying XML input and
* output factories, as there is no way to make copies of those.
*
* @since 2.1
*/
@Override
public XmlFactory copy() {
_checkInvalidCopy(XmlFactory.class);
return new XmlFactory(this, null);
}
@Override
public Version version() {
return PackageVersion.VERSION;
}
/*
/**********************************************************
/* Serializable overrides
/**********************************************************
*/
/**
* Hiding place for JDK-serialization unthawed factories...
*/
protected transient String _jdkXmlInFactory;
/**
* Hiding place for JDK-serialization unthawed factories...
*/
protected transient String _jdkXmlOutFactory;
/**
* Method that we need to override to actually make restoration go
* through constructors etc.
*/
@Override // since JsonFactory already implemented it
protected Object readResolve() {
if (_jdkXmlInFactory == null) {
throw new IllegalStateException("No XMLInputFactory class name read during JDK deserialization");
}
if (_jdkXmlOutFactory == null) {
throw new IllegalStateException("No XMLOutputFactory class name read during JDK deserialization");
}
try {
XMLInputFactory inf = (XMLInputFactory) Class.forName(_jdkXmlInFactory).newInstance();
XMLOutputFactory outf = (XMLOutputFactory) Class.forName(_jdkXmlOutFactory).newInstance();
return new XmlFactory(_objectCodec, _xmlParserFeatures, _xmlGeneratorFeatures,
inf, outf, _cfgNameForTextElement);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
} catch (InstantiationException e) {
throw new IllegalArgumentException(e);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
}
}
/**
* In addition to default serialization, which mostly works, need
* to handle case of XML factories, hence override.
*/
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
_jdkXmlInFactory = in.readUTF();
_jdkXmlOutFactory = in.readUTF();
}
/**
* In addition to default serialization, which mostly works, need
* to handle case of XML factories, hence override.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeUTF(_xmlInputFactory.getClass().getName());
out.writeUTF(_xmlOutputFactory.getClass().getName());
}
/*
/**********************************************************
/* Configuration, XML-specific
/**********************************************************
*/
/**
* @since 2.1
*/
public void setXMLTextElementName(String name) {
_cfgNameForTextElement = name;
}
/**
* @since 2.2
*/
public String getXMLTextElementName() {
return _cfgNameForTextElement;
}
/*
/**********************************************************
/* Configuration, XML, parser setting
/**********************************************************
*/
/**
* Method for enabling or disabling specified XML parser feature.
*/
public final XmlFactory configure(FromXmlParser.Feature f, boolean state)
{
if (state) {
enable(f);
} else {
disable(f);
}
return this;
}
/**
* Method for enabling specified XML parser feature.
*/
public XmlFactory enable(FromXmlParser.Feature f) {
_xmlParserFeatures |= f.getMask();
return this;
}
/**
* Method for disabling specified XML parser feature.
*/
public XmlFactory disable(FromXmlParser.Feature f) {
_xmlParserFeatures &= ~f.getMask();
return this;
}
/**
* Checked whether specified XML parser feature is enabled.
*/
public final boolean isEnabled(FromXmlParser.Feature f) {
return (_xmlParserFeatures & f.getMask()) != 0;
}
/*
/******************************************************
/* Configuration, XML, generator settings
/******************************************************
*/
/**
* Method for enabling or disabling specified XML generator feature.
*/
public final XmlFactory configure(ToXmlGenerator.Feature f, boolean state) {
if (state) {
enable(f);
} else {
disable(f);
}
return this;
}
/**
* Method for enabling specified XML generator feature.
*/
public XmlFactory enable(ToXmlGenerator.Feature f) {
_xmlGeneratorFeatures |= f.getMask();
return this;
}
/**
* Method for disabling specified XML generator feature.
*/
public XmlFactory disable(ToXmlGenerator.Feature f) {
_xmlGeneratorFeatures &= ~f.getMask();
return this;
}
/**
* Check whether specified XML generator feature is enabled.
*/
public final boolean isEnabled(ToXmlGenerator.Feature f) {
return (_xmlGeneratorFeatures & f.getMask()) != 0;
}
/*
/**********************************************************
/* Additional configuration
/**********************************************************
*/
/** @since 2.4 */
public XMLInputFactory getXMLInputFactory() {
return _xmlInputFactory;
}
public void setXMLInputFactory(XMLInputFactory f) {
_xmlInputFactory = f;
}
/** @since 2.4 */
public XMLOutputFactory getXMLOutputFactory() {
return _xmlOutputFactory;
}
public void setXMLOutputFactory(XMLOutputFactory f) {
_xmlOutputFactory = f;
}
/*
/**********************************************************
/* Format detection functionality
/**********************************************************
*/
/**
* Method that returns short textual id identifying format
* this factory supports.
*
* Note: sub-classes should override this method; default
* implementation will return null for all sub-classes
*/
@Override
public String getFormatName() {
return FORMAT_NAME_XML;
}
@Override
public MatchStrength hasFormat(InputAccessor acc) throws IOException {
return hasXMLFormat(acc);
}
/**
* XML format does require support from custom {@link ObjectCodec}
* (that is, {@link XmlMapper}), so need to return true here.
*
* @return True since XML format does require support from codec
*/
@Override
public boolean requiresCustomCodec() { return true; }
/*
/**********************************************************
/* Capability overrides
/**********************************************************
*/
/**
* As of 2.4, we do have actual capability for passing char arrays
* efficiently, but unfortunately
* have no working mechanism for recycling buffers. So we have to
* admit that can not make efficient use.
*/
@Override
public boolean canUseCharArrays() { return false; }
/*
/**********************************************************
/* Overrides of public methods: parsing
/**********************************************************
*/
/**
* Overridden just to prevent trying to optimize access via char array;
* while nice idea, problem is that we don't have proper hooks to ensure
* that temporary buffer gets recycled; so let's just use StringReader.
*/
@SuppressWarnings("resource")
@Override
public JsonParser createParser(String content) throws IOException {
Reader r = new StringReader(content);
IOContext ctxt = _createContext(r, true);
if (_inputDecorator != null) {
r = _inputDecorator.decorate(ctxt, r);
}
return _createParser(r, ctxt);
}
/*
/**********************************************************
/* Overrides of public methods: generation
/**********************************************************
*/
@Override
public ToXmlGenerator createGenerator(OutputStream out) throws IOException {
return createGenerator(out, JsonEncoding.UTF8);
}
@Override
public ToXmlGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException
{
// false -> we won't manage the stream unless explicitly directed to
IOContext ctxt = _createContext(out, false);
ctxt.setEncoding(enc);
return new ToXmlGenerator(ctxt,
_generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, _createXmlWriter(out));
}
@Override
public ToXmlGenerator createGenerator(Writer out) throws IOException
{
return new ToXmlGenerator(_createContext(out, false),
_generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, _createXmlWriter(out));
}
@SuppressWarnings("resource")
@Override
public ToXmlGenerator createGenerator(File f, JsonEncoding enc) throws IOException
{
OutputStream out = new FileOutputStream(f);
// true -> yes, we have to manage the stream since we created it
IOContext ctxt = _createContext(out, true);
ctxt.setEncoding(enc);
return new ToXmlGenerator(ctxt, _generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, _createXmlWriter(out));
}
/*
/**********************************************************
/* Extended public API, mostly for XmlMapper
/**********************************************************
*/
/**
* Factory method that wraps given {@link XMLStreamReader}, usually to allow
* partial data-binding.
*
* @since 2.4
*/
public FromXmlParser createParser(XMLStreamReader sr) throws IOException
{
// note: should NOT move parser if already pointing to START_ELEMENT
if (sr.getEventType() != XMLStreamConstants.START_ELEMENT) {
try {
sr = _initializeXmlReader(sr);
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
}
// false -> not managed
FromXmlParser xp = new FromXmlParser(_createContext(sr, false),
_generatorFeatures, _xmlGeneratorFeatures, _objectCodec, sr);
if (_cfgNameForTextElement != null) {
xp.setXMLTextElementName(_cfgNameForTextElement);
}
return xp;
}
/**
* Factory method that wraps given {@link XMLStreamWriter}, usually to allow
* incremental serialization to compose large output by serializing a sequence
* of individual objects.
*
* @since 2.4
*/
public ToXmlGenerator createGenerator(XMLStreamWriter sw) throws IOException
{
try {
sw = _initializeXmlWriter(sw);
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
IOContext ctxt = _createContext(sw, false);
return new ToXmlGenerator(ctxt, _generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, sw);
}
/*
/**********************************************************
/* Internal factory method overrides
/**********************************************************
*/
@Override
protected FromXmlParser _createParser(InputStream in, IOContext ctxt) throws IOException
{
XMLStreamReader sr;
try {
sr = _xmlInputFactory.createXMLStreamReader(in);
sr = _initializeXmlReader(sr);
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
FromXmlParser xp = new FromXmlParser(ctxt, _generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, sr);
if (_cfgNameForTextElement != null) {
xp.setXMLTextElementName(_cfgNameForTextElement);
}
return xp;
}
@Override
protected FromXmlParser _createParser(Reader r, IOContext ctxt) throws IOException
{
XMLStreamReader sr;
try {
sr = _xmlInputFactory.createXMLStreamReader(r);
sr = _initializeXmlReader(sr);
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
FromXmlParser xp = new FromXmlParser(ctxt, _generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, sr);
if (_cfgNameForTextElement != null) {
xp.setXMLTextElementName(_cfgNameForTextElement);
}
return xp;
}
@Override
protected FromXmlParser _createParser(char[] data, int offset, int len, IOContext ctxt,
boolean recycleBuffer) throws IOException
{
// !!! TODO: add proper handling of 'recycleBuffer'; currently its handling
// is always same as if 'false' was passed
XMLStreamReader sr;
try {
sr = _xmlInputFactory.createXMLStreamReader(new Stax2CharArraySource(data, offset, len));
sr = _initializeXmlReader(sr);
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
FromXmlParser xp = new FromXmlParser(ctxt, _generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, sr);
if (_cfgNameForTextElement != null) {
xp.setXMLTextElementName(_cfgNameForTextElement);
}
return xp;
}
@Override
protected FromXmlParser _createParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException
{
XMLStreamReader sr;
try {
sr = _xmlInputFactory.createXMLStreamReader(new Stax2ByteArraySource(data, offset, len));
sr = _initializeXmlReader(sr);
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
FromXmlParser xp = new FromXmlParser(ctxt, _generatorFeatures, _xmlGeneratorFeatures,
_objectCodec, sr);
if (_cfgNameForTextElement != null) {
xp.setXMLTextElementName(_cfgNameForTextElement);
}
return xp;
}
@Override
protected JsonGenerator _createGenerator(Writer out, IOContext ctxt) throws IOException {
// this method should never get called here, so:
VersionUtil.throwInternal();
return null;
}
/*
/**********************************************************************
/* Internal factory methods, XML-specific
/**********************************************************************
*/
protected XMLStreamWriter _createXmlWriter(OutputStream out) throws IOException
{
try {
return _initializeXmlWriter(_xmlOutputFactory.createXMLStreamWriter(out, "UTF-8"));
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
}
protected XMLStreamWriter _createXmlWriter(Writer w) throws IOException
{
try {
return _initializeXmlWriter(_xmlOutputFactory.createXMLStreamWriter(w));
} catch (XMLStreamException e) {
return StaxUtil.throwXmlAsIOException(e);
}
}
protected final XMLStreamWriter _initializeXmlWriter(XMLStreamWriter sw) throws IOException, XMLStreamException
{
// And just for Sun Stax parser (JDK default), seems that we better define default namespace
// (Woodstox doesn't care) -- otherwise it'll add unnecessary odd declaration
sw.setDefaultNamespace("");
return sw;
}
protected final XMLStreamReader _initializeXmlReader(XMLStreamReader sr) throws IOException, XMLStreamException
{
// for now, nothing to do... except let's find the root element
while (sr.next() != XMLStreamConstants.START_ELEMENT) {
;
}
return sr;
}
/*
/**********************************************************************
/* Internal methods, format auto-detection
/**********************************************************************
*/
private final static byte UTF8_BOM_1 = (byte) 0xEF;
private final static byte UTF8_BOM_2 = (byte) 0xBB;
private final static byte UTF8_BOM_3 = (byte) 0xBF;
private final static byte BYTE_x = (byte) 'x';
private final static byte BYTE_m = (byte) 'm';
private final static byte BYTE_l = (byte) 'l';
private final static byte BYTE_D = (byte) 'D';
private final static byte BYTE_LT = (byte) '<';
private final static byte BYTE_QMARK = (byte) '?';
private final static byte BYTE_EXCL = (byte) '!';
private final static byte BYTE_HYPHEN = (byte) '-';
/**
* Method that tries to figure out if content seems to be in some kind
* of XML format.
* Note that implementation here is not nearly as robust as what underlying
* Stax parser will do; the idea is to first support common encodings,
* then expand as needed (for example, it is not all that hard to support
* UTF-16; but it is some work and not needed quite yet)
*/
public static MatchStrength hasXMLFormat(InputAccessor acc) throws IOException
{
/* Basically we just need to find " or , since
* can NOT come outside of root
*/
if (!acc.hasMoreBytes()) {
return MatchStrength.INCONCLUSIVE;
}
b = acc.nextByte();
if (b == BYTE_HYPHEN) {
if (!acc.hasMoreBytes()) {
return MatchStrength.INCONCLUSIVE;
}
if (acc.nextByte() == BYTE_HYPHEN) {
return MatchStrength.SOLID_MATCH;
}
} else if (b == BYTE_D) {
return tryMatch(acc, "OCTYPE", MatchStrength.SOLID_MATCH);
}
} else {
// maybe root element? Just needs to match first char.
if (validXmlNameStartChar(acc, b)) {
return MatchStrength.SOLID_MATCH;
}
}
return MatchStrength.NO_MATCH;
}
private final static boolean validXmlNameStartChar(InputAccessor acc, byte b)
throws IOException
{
/* Can make it actual real XML check in future; for now we do just crude
* check for ASCII range
*/
int ch = (int) b & 0xFF;
if (ch >= 'A') { // in theory, colon could be; in practice it should never be valid (wrt namespace)
// This is where we'd check for multi-byte UTF-8 chars (or whatever encoding is in use)...
return true;
}
return false;
}
private final static MatchStrength tryMatch(InputAccessor acc, String matchStr, MatchStrength fullMatchStrength)
throws IOException
{
for (int i = 0, len = matchStr.length(); i < len; ++i) {
if (!acc.hasMoreBytes()) {
return MatchStrength.INCONCLUSIVE;
}
if (acc.nextByte() != matchStr.charAt(i)) {
return MatchStrength.NO_MATCH;
}
}
return fullMatchStrength;
}
private final static int skipSpace(InputAccessor acc, byte b) throws IOException
{
while (true) {
int ch = (int) b & 0xFF;
if (!(ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t')) {
return ch;
}
if (!acc.hasMoreBytes()) {
return -1;
}
b = acc.nextByte();
ch = (int) b & 0xFF;
}
}
}
XmlMapper.java 0000664 0000000 0000000 00000016131 12516567542 0036734 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package com.fasterxml.jackson.dataformat.xml;
import java.io.IOException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider;
import com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter;
import com.fasterxml.jackson.dataformat.xml.util.XmlRootNameLookup;
/**
* Customized {@link ObjectMapper} that will read and write XML instead of JSON,
* using XML-backed {@link com.fasterxml.jackson.core.JsonFactory}
* implementation ({@link XmlFactory}).
*
* Mapper itself overrides some aspects of functionality to try to handle
* data binding aspects as similar to JAXB as possible.
*/
public class XmlMapper extends ObjectMapper
{
// as of 2.5
private static final long serialVersionUID = -1212805483143619605L;
protected final static JacksonXmlModule DEFAULT_XML_MODULE = new JacksonXmlModule();
// need to hold on to module instance just in case copy() is used
protected final JacksonXmlModule _xmlModule;
/*
/**********************************************************
/* Life-cycle: construction, configuration
/**********************************************************
*/
public XmlMapper() {
this(new XmlFactory());
}
/** @since 2.4 */
public XmlMapper(XMLInputFactory inputF, XMLOutputFactory outF) {
this(new XmlFactory(inputF, outF));
}
/** @since 2.4 */
public XmlMapper(XMLInputFactory inputF) {
this(new XmlFactory(inputF));
}
public XmlMapper(XmlFactory xmlFactory) {
this(xmlFactory, DEFAULT_XML_MODULE);
}
public XmlMapper(JacksonXmlModule module) {
this(new XmlFactory(), module);
}
public XmlMapper(XmlFactory xmlFactory, JacksonXmlModule module)
{
/* Need to override serializer provider (due to root name handling);
* deserializer provider fine as is
*/
super(xmlFactory, new XmlSerializerProvider(new XmlRootNameLookup()), null);
_xmlModule = module;
// but all the rest is done via Module interface!
if (module != null) {
registerModule(module);
}
}
// @since 2.1
@Override
public XmlMapper copy()
{
_checkInvalidCopy(XmlMapper.class);
return new XmlMapper((XmlFactory) _jsonFactory.copy(), _xmlModule);
}
@Override
public Version version() {
return PackageVersion.VERSION;
}
/*
/**********************************************************
/* Additional XML-specific configurations
/**********************************************************
*/
/**
* Method called by {@link JacksonXmlModule} to pass configuration
* information to {@link XmlFactory}, during registration.
*
* @since 2.1
*/
protected void setXMLTextElementName(String name) {
((XmlFactory) _jsonFactory).setXMLTextElementName(name);
}
/*
/**********************************************************
/* Access to configuration settings
/**********************************************************
*/
/**
* @deprecated Since 2.1, use {@link #getFactory} instead
*/
@Override
@Deprecated
public XmlFactory getJsonFactory() {
return (XmlFactory) _jsonFactory;
}
@Override
public XmlFactory getFactory() {
return (XmlFactory) _jsonFactory;
}
public ObjectMapper configure(ToXmlGenerator.Feature f, boolean state) {
((XmlFactory)_jsonFactory).configure(f, state);
return this;
}
public ObjectMapper configure(FromXmlParser.Feature f, boolean state) {
((XmlFactory)_jsonFactory).configure(f, state);
return this;
}
public ObjectMapper enable(ToXmlGenerator.Feature f) {
((XmlFactory)_jsonFactory).enable(f);
return this;
}
public ObjectMapper enable(FromXmlParser.Feature f) {
((XmlFactory)_jsonFactory).enable(f);
return this;
}
public ObjectMapper disable(ToXmlGenerator.Feature f) {
((XmlFactory)_jsonFactory).disable(f);
return this;
}
public ObjectMapper disable(FromXmlParser.Feature f) {
((XmlFactory)_jsonFactory).disable(f);
return this;
}
/*
/**********************************************************
/* XML-specific access
/**********************************************************
*/
/**
* Method for reading a single XML value from given XML-specific input
* source; useful for incremental data-binding, combining traversal using
* basic Stax {@link XMLStreamReader} with data-binding by Jackson.
*
* @since 2.4
*/
public T readValue(XMLStreamReader r, Class valueType) throws IOException {
return readValue(r, _typeFactory.constructType(valueType));
}
/**
* Method for reading a single XML value from given XML-specific input
* source; useful for incremental data-binding, combining traversal using
* basic Stax {@link XMLStreamReader} with data-binding by Jackson.
*
* @since 2.4
*/
public T readValue(XMLStreamReader r, TypeReference valueTypeRef) throws IOException {
return readValue(r, _typeFactory.constructType(valueTypeRef));
}
/**
* Method for reading a single XML value from given XML-specific input
* source; useful for incremental data-binding, combining traversal using
* basic Stax {@link XMLStreamReader} with data-binding by Jackson.
*
* @since 2.4
*/
@SuppressWarnings("resource")
public T readValue(XMLStreamReader r, JavaType valueType) throws IOException
{
FromXmlParser p = getFactory().createParser(r);
return super.readValue(p, valueType);
}
/**
* Method for serializing given value using specific {@link XMLStreamReader}:
* useful when building large XML files by binding individual items, one at
* a time.
*
* @since 2.4
*/
public void writeValue(XMLStreamWriter w0, Object value) throws IOException {
@SuppressWarnings("resource")
ToXmlGenerator g = getFactory().createGenerator(w0);
super.writeValue(g, value);
/* NOTE: above call should do flush(); and we should NOT close here.
* Finally, 'g' has no buffers to release.
*/
}
/*
/**********************************************************
/* Overridden methods
/**********************************************************
*/
/**
* XML indentation differs from JSON indentation, thereby
* need to change default pretty-printer
*/
@Override
protected PrettyPrinter _defaultPrettyPrinter() {
return new DefaultXmlPrettyPrinter();
}
}
XmlPrettyPrinter.java 0000664 0000000 0000000 00000005352 12516567542 0040346 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package com.fasterxml.jackson.dataformat.xml;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.xml.stream.XMLStreamException;
import org.codehaus.stax2.XMLStreamWriter2;
import com.fasterxml.jackson.core.PrettyPrinter;
/**
* There are some XML-specific quirks that need extra TLC when
* indenting: so we will use a refinement of general purpose one.
*/
public interface XmlPrettyPrinter extends PrettyPrinter
{
/**
* Method for forcibly writing a start element, without going
* through Jackson generator (and thus, without updating currently
* active element stack)
*
* @since 2.1
*/
public void writeStartElement(XMLStreamWriter2 sw,
String nsURI, String localName) throws XMLStreamException;
/**
* Method for forcibly writing an end element, without going
* through Jackson generator (and thus, without updating currently
* active element stack)
*
* @since 2.1
*/
public void writeEndElement(XMLStreamWriter2 sw, int nrOfEntries) throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, String text, boolean isCData)
throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName,
char[] buffer, int offset, int len, boolean isCData)
throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, boolean value)
throws XMLStreamException;
// Lots of numbers...
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, int value)
throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, long value)
throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, double value)
throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, float value)
throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, BigInteger value)
throws XMLStreamException;
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, BigDecimal value)
throws XMLStreamException;
// binary element
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName,
byte[] data, int offset, int len)
throws XMLStreamException;
// empty element to represent null
public void writeLeafNullElement(XMLStreamWriter2 sw,
String nsURI, String localName)
throws XMLStreamException;
}
XmlTypeResolverBuilder.java 0000664 0000000 0000000 00000012603 12516567542 0041462 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml package com.fasterxml.jackson.dataformat.xml;
import java.util.Collection;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.MinimalClassNameIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.dataformat.xml.util.StaxUtil;
/**
* Custom specialization of {@link StdTypeResolverBuilder}; needed so that
* type id property name can be modified as necessary to make it legal
* XML element or attribute name.
*/
public class XmlTypeResolverBuilder extends StdTypeResolverBuilder
{
@Override
public StdTypeResolverBuilder init(JsonTypeInfo.Id idType, TypeIdResolver idRes)
{
super.init(idType, idRes);
if (_typeProperty != null) {
_typeProperty = StaxUtil.sanitizeXmlTypeName(_typeProperty);
}
return this;
}
@Override
public StdTypeResolverBuilder typeProperty(String typeIdPropName)
{
// ok to have null/empty; will restore to use defaults
if (typeIdPropName == null || typeIdPropName.length() == 0) {
typeIdPropName = _idType.getDefaultPropertyName();
}
_typeProperty = StaxUtil.sanitizeXmlTypeName(typeIdPropName);
return this;
}
@Override
protected TypeIdResolver idResolver(MapperConfig> config,
JavaType baseType, Collection subtypes,
boolean forSer, boolean forDeser)
{
if (_customIdResolver != null) {
return _customIdResolver;
}
// Only override handlings of class, minimal class; name is good as is
switch (_idType) {
case CLASS:
return new XmlClassNameIdResolver(baseType, config.getTypeFactory());
case MINIMAL_CLASS:
return new XmlMinimalClassNameIdResolver(baseType, config.getTypeFactory());
default:
return super.idResolver(config, baseType, subtypes, forSer, forDeser);
}
}
/*
/**********************************************************************
/* Internal helper methods
/**********************************************************************
*/
/**
* Helper method for encoding regular Java class name in form that
* can be used as XML element name.
*/
protected static String encodeXmlClassName(String className)
{
/* For now, let's just replace '$'s with double dots...
* Perhaps make configurable in future?
*/
int ix = className.lastIndexOf('$');
if (ix >= 0) {
StringBuilder sb = new StringBuilder(className);
do {
sb.replace(ix, ix+1, "..");
ix = className.lastIndexOf('$', ix-1);
} while (ix >= 0);
className = sb.toString();
}
return className;
}
/**
* Helper method for decoding "XML safe" Java class name back into
* actual class name
*/
protected static String decodeXmlClassName(String className)
{
int ix = className.lastIndexOf("..");
if (ix >= 0) {
StringBuilder sb = new StringBuilder(className);
do {
sb.replace(ix, ix+2, "$");
ix = className.lastIndexOf("..", ix-1);
} while (ix >= 0);
className = sb.toString();
}
return className;
}
/*
/**********************************************************************
/* Customized class name handlers
/**********************************************************************
*/
protected static class XmlClassNameIdResolver
extends ClassNameIdResolver
{
public XmlClassNameIdResolver(JavaType baseType, TypeFactory typeFactory)
{
super(baseType, typeFactory);
}
@Override
public String idFromValue(Object value)
{
return encodeXmlClassName(super.idFromValue(value));
}
@SuppressWarnings("deprecation")
@Override
public JavaType typeFromId(String id) {
return super.typeFromId(decodeXmlClassName(id));
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
return super.typeFromId(context, decodeXmlClassName(id));
}
}
protected static class XmlMinimalClassNameIdResolver
extends MinimalClassNameIdResolver
{
public XmlMinimalClassNameIdResolver(JavaType baseType, TypeFactory typeFactory)
{
super(baseType, typeFactory);
}
@Override
public String idFromValue(Object value)
{
return encodeXmlClassName(super.idFromValue(value));
}
@SuppressWarnings("deprecation")
@Override
public JavaType typeFromId(String id) {
return super.typeFromId(decodeXmlClassName(id));
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
return super.typeFromId(context, decodeXmlClassName(id));
}
}
}
0000775 0000000 0000000 00000000000 12516567542 0036334 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/annotation JacksonXmlCData.java 0000664 0000000 0000000 00000001255 12516567542 0042150 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/annotation package com.fasterxml.jackson.dataformat.xml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Adding this annotation will result in value of the property to be serialized
* within a CData tag. Only use on String properties and String collections.
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface JacksonXmlCData
{
/**
* Whether the property text should always be within a CData block
* when serialized.
*/
public boolean value() default true;
}
JacksonXmlElementWrapper.java 0000664 0000000 0000000 00000002444 12516567542 0044127 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/annotation package com.fasterxml.jackson.dataformat.xml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that is similar to JAXB javax.xml.bind.annotation.XmlElementWrapper,
* to indicate wrapper element to use (if any) for Collection types (arrays,
* java.util.Collection). If defined, a separate container (wrapper) element
* is used; if not, entries are written without wrapping.
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JacksonXmlElementWrapper
{
/**
* Marker value (empty String) that denotes that the underlying property
* name should also be used as the wrapper name, effectively "doubling"
* start and end elements.
*
* @since 2.1
*/
public final static String USE_PROPERTY_NAME = "";
String namespace() default USE_PROPERTY_NAME;
String localName() default USE_PROPERTY_NAME;
/**
* Optional property that can be used to explicitly disable wrapping,
* usually via mix-ins, or when using AnnotationIntrospector
* pairs.
*
* @since 2.1
*/
boolean useWrapping() default true;
}
JacksonXmlProperty.java 0000664 0000000 0000000 00000001314 12516567542 0043014 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/annotation package com.fasterxml.jackson.dataformat.xml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that can be used to provide XML-specific configuration
* for properties, above and beyond what
* {@link com.fasterxml.jackson.annotation.JsonProperty} contains.
* It is an alternative to using JAXB annotations.
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface JacksonXmlProperty
{
boolean isAttribute() default false;
String namespace() default "";
String localName() default "";
}
JacksonXmlRootElement.java 0000664 0000000 0000000 00000001153 12516567542 0043426 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/annotation package com.fasterxml.jackson.dataformat.xml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that can be used to define name of root element used
* for the root-level object when serialized, which normally uses
* name of the type (class). It is similar to JAXB XmlRootElement.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface JacksonXmlRootElement
{
String namespace() default "";
String localName() default "";
}
JacksonXmlText.java 0000664 0000000 0000000 00000001626 12516567542 0042122 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/annotation package com.fasterxml.jackson.dataformat.xml.annotation;
import java.lang.annotation.*;
/**
* Interface that is loosely similar to {@link javax.xml.bind.annotation.XmlValue}
* in that it can be used on one (and only one!) property of a POJO.
* It will result in value of the property be serialized without element wrapper,
* as long as there are no element-wrapped other properties (attribute-valued
* properties are acceptable).
* It is also similar to core Jackson JsonValue annotation; but
* has to be separate as JsonValue does not allow any other
* properties.
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JacksonXmlText
{
/**
* Whether serialization of the property should always be done as basic
* XML text or not; if true, will be, if false, not.
*/
public boolean value() default true;
}
package-info.java 0000664 0000000 0000000 00000000317 12516567542 0041524 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/annotation /**
* Package that contains additional annotations that can be
* used to configure XML-specific aspects of serialization
* and deserialization
*/
package com.fasterxml.jackson.dataformat.xml.annotation;
0000775 0000000 0000000 00000000000 12516567542 0035264 5 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/deser ElementWrapper.java 0000664 0000000 0000000 00000005330 12516567542 0041062 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/deser package com.fasterxml.jackson.dataformat.xml.deser;
/**
* Helper class needed to keep track of virtual wrapper elements
* added in the logical XML token stream.
*/
class ElementWrapper
{
protected final ElementWrapper _parent;
protected final String _wrapperName;
protected final String _wrapperNamespace;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
private ElementWrapper(ElementWrapper parent) {
_parent = parent;
_wrapperName = null;
_wrapperNamespace = "";
}
private ElementWrapper(ElementWrapper parent,
String wrapperLocalName, String wrapperNamespace)
{
_parent = parent;
_wrapperName = wrapperLocalName;
_wrapperNamespace = (wrapperNamespace == null) ? "" : wrapperNamespace;
}
/**
* Factory method called to construct a new "matching" wrapper element,
* at level where virtual wrapping is needed.
*/
public static ElementWrapper matchingWrapper(ElementWrapper parent,
String wrapperLocalName, String wrapperNamespace)
{
return new ElementWrapper(parent, wrapperLocalName, wrapperNamespace);
}
/**
* Factory method used for creating intermediate wrapper level, which
* is only used for purpose of keeping track of physical element
* nesting.
*/
public ElementWrapper intermediateWrapper() {
return new ElementWrapper(this, null, null);
}
/*
/**********************************************************
/* API
/**********************************************************
*/
public boolean isMatching() { return _wrapperName != null; }
public String getWrapperLocalName() { return _wrapperName; }
public String getWrapperNamespace() { return _wrapperNamespace; }
public ElementWrapper getParent() { return _parent; }
public boolean matchesWrapper(String localName, String ns)
{
// null means "anything goes", so:
if (_wrapperName == null) {
return true;
}
if (ns == null) {
ns = "";
}
return _wrapperName.equals(localName) && _wrapperNamespace.equals(ns);
}
/*
/**********************************************************
/* Overrides
/**********************************************************
*/
@Override
public String toString()
{
if (_parent == null) {
return "Wrapper: ROOT, matching: "+_wrapperName;
}
if (_wrapperName == null) {
return "Wrapper: empty";
}
return "Wrapper: branch, matching: "+_wrapperName;
}
}
FromXmlParser.java 0000664 0000000 0000000 00000073577 12516567542 0040713 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/deser package com.fasterxml.jackson.dataformat.xml.deser;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Set;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.base.ParserMinimalBase;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.util.ByteArrayBuilder;
import com.fasterxml.jackson.dataformat.xml.PackageVersion;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
/**
* {@link JsonParser} implementation that exposes XML structure as
* set of JSON events that can be used for data binding.
*/
public class FromXmlParser
extends ParserMinimalBase
{
/**
* The default name placeholder for XML text segments is empty
* String ("").
*/
public final static String DEFAULT_UNNAMED_TEXT_PROPERTY = "";
/**
* Enumeration that defines all togglable features for XML parsers
*/
public enum Feature {
;
final boolean _defaultState;
final int _mask;
/**
* Method that calculates bit set (flags) of all features that
* are enabled by default.
*/
public static int collectDefaults()
{
int flags = 0;
for (Feature f : values()) {
if (f.enabledByDefault()) {
flags |= f.getMask();
}
}
return flags;
}
private Feature(boolean defaultState) {
_defaultState = defaultState;
_mask = (1 << ordinal());
}
public boolean enabledByDefault() { return _defaultState; }
public int getMask() { return _mask; }
}
/**
* In cases where a start element has both attributes and non-empty textual
* value, we have to create a bogus property; we will use this as
* the property name.
*
* Name used for pseudo-property used for returning XML Text value (which does
* not have actual element name to use). Defaults to empty String, but
* may be changed for interoperability reasons: JAXB, for example, uses
* "value" as name.
*
* @since 2.1
*/
protected String _cfgNameForTextElement = DEFAULT_UNNAMED_TEXT_PROPERTY;
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* Bit flag composed of bits that indicate which
* {@link FromXmlParser.Feature}s
* are enabled.
*/
protected int _xmlFeatures;
protected ObjectCodec _objectCodec;
/*
/**********************************************************
/* I/O state
/**********************************************************
*/
/**
* Flag that indicates whether parser is closed or not. Gets
* set when parser is either closed by explicit call
* ({@link #close}) or when end-of-input is reached.
*/
protected boolean _closed;
final protected IOContext _ioContext;
/*
/**********************************************************
/* Parsing state
/**********************************************************
*/
/**
* Information about parser context, context in which
* the next token is to be parsed (root, array, object).
*/
protected XmlReadContext _parsingContext;
protected final XmlTokenStream _xmlTokens;
/**
*
* We need special handling to keep track of whether a value
* may be exposed as simple leaf value.
*/
protected boolean _mayBeLeaf;
protected JsonToken _nextToken;
protected String _currText;
protected Set _namesToWrap;
/*
/**********************************************************
/* Parsing state, parsed values
/**********************************************************
*/
/**
* ByteArrayBuilder is needed if 'getBinaryValue' is called. If so,
* we better reuse it for remainder of content.
*/
protected ByteArrayBuilder _byteArrayBuilder = null;
/**
* We will hold on to decoded binary data, for duration of
* current event, so that multiple calls to
* {@link #getBinaryValue} will not need to decode data more
* than once.
*/
protected byte[] _binaryValue;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public FromXmlParser(IOContext ctxt, int genericParserFeatures, int xmlFeatures,
ObjectCodec codec, XMLStreamReader xmlReader)
{
super(genericParserFeatures);
_xmlFeatures = xmlFeatures;
_ioContext = ctxt;
_objectCodec = codec;
_parsingContext = XmlReadContext.createRootContext(-1, -1);
// and thereby start a scope
_nextToken = JsonToken.START_OBJECT;
_xmlTokens = new XmlTokenStream(xmlReader, ctxt.getSourceReference());
}
@Override
public Version version() {
return PackageVersion.VERSION;
}
@Override
public ObjectCodec getCodec() {
return _objectCodec;
}
@Override
public void setCodec(ObjectCodec c) {
_objectCodec = c;
}
/**
* @since 2.1
*/
public void setXMLTextElementName(String name) {
_cfgNameForTextElement = name;
}
/**
* XML format does require support from custom {@link ObjectCodec}
* (that is, {@link XmlMapper}), so need to return true here.
*
* @return True since XML format does require support from codec
*/
@Override
public boolean requiresCustomCodec() {
return false;
}
/*
/**********************************************************
/* Extended API, configuration
/**********************************************************
*/
public FromXmlParser enable(Feature f) {
_xmlFeatures |= f.getMask();
return this;
}
public FromXmlParser disable(Feature f) {
_xmlFeatures &= ~f.getMask();
return this;
}
public final boolean isEnabled(Feature f) {
return (_xmlFeatures & f.getMask()) != 0;
}
public FromXmlParser configure(Feature f, boolean state) {
if (state) {
enable(f);
} else {
disable(f);
}
return this;
}
/*
/**********************************************************
/* Extended API, access to some internal components
/**********************************************************
*/
/**
* Method that allows application direct access to underlying
* Stax {@link XMLStreamWriter}. Note that use of writer is
* discouraged, and may interfere with processing of this writer;
* however, occasionally it may be necessary.
*
* Note: writer instance will always be of type
* {@link org.codehaus.stax2.XMLStreamWriter2} (including
* Typed Access API) so upcasts are safe.
*/
public XMLStreamReader getStaxReader() {
return _xmlTokens.getXmlReader();
}
/*
/**********************************************************
/* Internal API
/**********************************************************
*/
/**
* Method that may be called to indicate that specified names
* (only local parts retained currently: this may be changed in
* future) should be considered "auto-wrapping", meaning that
* they will be doubled to contain two opening elements, two
* matching closing elements. This is needed for supporting
* handling of so-called "unwrapped" array types, something
* XML mappings like JAXB often use.
*
* NOTE: this method is considered part of internal implementation
* interface, and it is NOT guaranteed to remain unchanged
* between minor versions (it is however expected not to change in
* patch versions). So if you have to use it, be prepared for
* possible additional work.
*
* @since 2.1
*/
public void addVirtualWrapping(Set namesToWrap)
{
/* 17-Sep-2012, tatu: Not 100% sure why, but this is necessary to avoid
* problems with Lists-in-Lists properties
*/
String name = _xmlTokens.getLocalName();
if (name != null && namesToWrap.contains(name)) {
_xmlTokens.repeatStartElement();
}
_namesToWrap = namesToWrap;
_parsingContext.setNamesToWrap(namesToWrap);
}
/*
/**********************************************************
/* JsonParser impl
/**********************************************************
*/
/**
* Method that can be called to get the name associated with
* the current event.
*/
@Override
public String getCurrentName()
throws IOException, JsonParseException
{
// [JACKSON-395]: start markers require information from parent
String name;
if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) {
XmlReadContext parent = _parsingContext.getParent();
name = parent.getCurrentName();
} else {
name = _parsingContext.getCurrentName();
}
// sanity check
if (name == null) {
throw new IllegalStateException("Missing name, in state: "+_currToken);
}
return name;
}
@Override
public void overrideCurrentName(String name)
{
// Simple, but need to look for START_OBJECT/ARRAY's "off-by-one" thing:
XmlReadContext ctxt = _parsingContext;
if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) {
ctxt = ctxt.getParent();
}
ctxt.setCurrentName(name);
}
@Override
public void close() throws IOException
{
if (!_closed) {
_closed = true;
try {
if (_ioContext.isResourceManaged() || isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) {
_xmlTokens.closeCompletely();
} else {
_xmlTokens.close();
}
} finally {
// as per [JACKSON-324], do in finally block
// Also, internal buffer(s) can now be released as well
_releaseBuffers();
}
}
}
@Override
public boolean isClosed() { return _closed; }
@Override
public XmlReadContext getParsingContext() {
return _parsingContext;
}
/**
* Method that return the starting location of the current
* token; that is, position of the first character from input
* that starts the current token.
*/
@Override
public JsonLocation getTokenLocation() {
return _xmlTokens.getTokenLocation();
}
/**
* Method that returns location of the last processed character;
* usually for error reporting purposes
*/
@Override
public JsonLocation getCurrentLocation() {
return _xmlTokens.getCurrentLocation();
}
/**
* Since xml representation can not really distinguish between array
* and object starts (both are represented with elements), this method
* is overridden and taken to mean that expecation is that the current
* start element is to mean 'start array', instead of default of
* 'start object'.
*/
@Override
public boolean isExpectedStartArrayToken()
{
JsonToken t = _currToken;
if (t == JsonToken.START_OBJECT) {
_currToken = JsonToken.START_ARRAY;
// Ok: must replace current context with array as well
_parsingContext.convertToArray();
//System.out.println(" isExpectedArrayStart: OBJ->Array, wraps now: "+_parsingContext.getNamesToWrap());
// And just in case a field name was to be returned, wipe it
_nextToken = null;
// and last thing, [Issue#33], better ignore attributes
_xmlTokens.skipAttributes();
return true;
}
//System.out.println(" isExpectedArrayStart?: t="+t);
return (t == JsonToken.START_ARRAY);
}
// DEBUGGING
/*
@Override
public JsonToken nextToken() throws IOException, JsonParseException
{
JsonToken t = nextToken0();
if (t != null) {
switch (t) {
case FIELD_NAME:
System.out.println("JsonToken: FIELD_NAME '"+_parsingContext.getCurrentName()+"'");
break;
case VALUE_STRING:
System.out.println("JsonToken: VALUE_STRING '"+getText()+"'");
break;
default:
System.out.println("JsonToken: "+t);
}
}
return t;
}
*/
@Override
public JsonToken nextToken() throws IOException
{
_binaryValue = null; // to fix [Issue-29]
if (_nextToken != null) {
JsonToken t = _nextToken;
_currToken = t;
_nextToken = null;
switch (t) {
case START_OBJECT:
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
break;
case START_ARRAY:
_parsingContext = _parsingContext.createChildArrayContext(-1, -1);
break;
case END_OBJECT:
case END_ARRAY:
_parsingContext = _parsingContext.getParent();
_namesToWrap = _parsingContext.getNamesToWrap();
break;
case FIELD_NAME:
_parsingContext.setCurrentName(_xmlTokens.getLocalName());
break;
default: // VALUE_STRING, VALUE_NULL
// should be fine as is?
}
return t;
}
int token = _xmlTokens.next();
/* Need to have a loop just because we may have to eat/convert
* a start-element that indicates an array element.
*/
while (token == XmlTokenStream.XML_START_ELEMENT) {
// If we thought we might get leaf, no such luck
if (_mayBeLeaf) {
// leave _mayBeLeaf set, as we start a new context
_nextToken = JsonToken.FIELD_NAME;
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
return (_currToken = JsonToken.START_OBJECT);
}
if (_parsingContext.inArray()) {
/* Yup: in array, so this element could be verified; but it won't be reported
* anyway, and we need to process following event.
*/
token = _xmlTokens.next();
_mayBeLeaf = true;
continue;
}
String name = _xmlTokens.getLocalName();
_parsingContext.setCurrentName(name);
/* Ok: virtual wrapping can be done by simply repeating
* current START_ELEMENT. Couple of ways to do it; but
* start by making _xmlTokens replay the thing...
*/
if (_namesToWrap != null && _namesToWrap.contains(name)) {
_xmlTokens.repeatStartElement();
}
_mayBeLeaf = true;
/* Ok: in array context we need to skip reporting field names. But what's the best way
* to find next token?
*/
return (_currToken = JsonToken.FIELD_NAME);
}
// Ok; beyond start element, what do we get?
switch (token) {
case XmlTokenStream.XML_END_ELEMENT:
// Simple, except that if this is a leaf, need to suppress end:
if (_mayBeLeaf) {
_mayBeLeaf = false;
return (_currToken = JsonToken.VALUE_NULL);
}
_currToken = _parsingContext.inArray() ? JsonToken.END_ARRAY : JsonToken.END_OBJECT;
_parsingContext = _parsingContext.getParent();
_namesToWrap = _parsingContext.getNamesToWrap();
return _currToken;
case XmlTokenStream.XML_ATTRIBUTE_NAME:
// If there was a chance of leaf node, no more...
if (_mayBeLeaf) {
_mayBeLeaf = false;
_nextToken = JsonToken.FIELD_NAME;
_currText = _xmlTokens.getText();
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
return (_currToken = JsonToken.START_OBJECT);
}
_parsingContext.setCurrentName(_xmlTokens.getLocalName());
return (_currToken = JsonToken.FIELD_NAME);
case XmlTokenStream.XML_ATTRIBUTE_VALUE:
_currText = _xmlTokens.getText();
return (_currToken = JsonToken.VALUE_STRING);
case XmlTokenStream.XML_TEXT:
_currText = _xmlTokens.getText();
if (_mayBeLeaf) {
_mayBeLeaf = false;
// Also: must skip following END_ELEMENT
_xmlTokens.skipEndElement();
/* One more refinement (pronunced like "hack") is that if
* we had an empty String (or all white space), and we are
* deserializing an array, we better just hide the text
* altogether.
*/
if (_parsingContext.inArray()) {
if (_isEmpty(_currText)) {
_currToken = JsonToken.END_ARRAY;
_parsingContext = _parsingContext.getParent();
_namesToWrap = _parsingContext.getNamesToWrap();
return _currToken;
}
}
return (_currToken = JsonToken.VALUE_STRING);
}
// If not a leaf, need to transform into property...
_parsingContext.setCurrentName(_cfgNameForTextElement);
_nextToken = JsonToken.VALUE_STRING;
return (_currToken = JsonToken.FIELD_NAME);
case XmlTokenStream.XML_END:
return (_currToken = null);
}
// should never get here
_throwInternal();
return null;
}
/*
/**********************************************************
/* Overrides of specialized nextXxx() methods
/**********************************************************
*/
/**
* Method overridden to support more reliable deserialization of
* String collections.
*/
@Override
public String nextTextValue() throws IOException
{
_binaryValue = null;
if (_nextToken != null) {
JsonToken t = _nextToken;
_currToken = t;
_nextToken = null;
// expected case; yes, got a String
if (t == JsonToken.VALUE_STRING) {
return _currText;
}
_updateState(t);
return null;
}
int token = _xmlTokens.next();
// mostly copied from 'nextToken()'
while (token == XmlTokenStream.XML_START_ELEMENT) {
if (_mayBeLeaf) {
_nextToken = JsonToken.FIELD_NAME;
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
_currToken = JsonToken.START_OBJECT;
return null;
}
if (_parsingContext.inArray()) {
token = _xmlTokens.next();
_mayBeLeaf = true;
continue;
}
String name = _xmlTokens.getLocalName();
_parsingContext.setCurrentName(name);
if (_namesToWrap != null && _namesToWrap.contains(name)) {
_xmlTokens.repeatStartElement();
}
_mayBeLeaf = true;
_currToken = JsonToken.FIELD_NAME;
return null;
}
// Ok; beyond start element, what do we get?
switch (token) {
case XmlTokenStream.XML_END_ELEMENT:
if (_mayBeLeaf) {
// NOTE: this is different from nextToken() -- produce "", NOT null
_mayBeLeaf = false;
_currToken = JsonToken.VALUE_STRING;
return (_currText = "");
}
_currToken = _parsingContext.inArray() ? JsonToken.END_ARRAY : JsonToken.END_OBJECT;
_parsingContext = _parsingContext.getParent();
_namesToWrap = _parsingContext.getNamesToWrap();
break;
case XmlTokenStream.XML_ATTRIBUTE_NAME:
// If there was a chance of leaf node, no more...
if (_mayBeLeaf) {
_mayBeLeaf = false;
_nextToken = JsonToken.FIELD_NAME;
_currText = _xmlTokens.getText();
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
_currToken = JsonToken.START_OBJECT;
} else {
_parsingContext.setCurrentName(_xmlTokens.getLocalName());
_currToken = JsonToken.FIELD_NAME;
}
break;
case XmlTokenStream.XML_ATTRIBUTE_VALUE:
_currText = _xmlTokens.getText();
_currToken = JsonToken.VALUE_STRING;
break;
case XmlTokenStream.XML_TEXT:
_currText = _xmlTokens.getText();
if (_mayBeLeaf) {
_mayBeLeaf = false;
// Also: must skip following END_ELEMENT
_xmlTokens.skipEndElement();
// NOTE: this is different from nextToken() -- NO work-around
// for otherwise empty List/array
_currToken = JsonToken.VALUE_STRING;
return _currText;
}
// If not a leaf, need to transform into property...
_parsingContext.setCurrentName(_cfgNameForTextElement);
_nextToken = JsonToken.VALUE_STRING;
_currToken = JsonToken.FIELD_NAME;
break;
case XmlTokenStream.XML_END:
_currToken = null;
}
return null;
}
private void _updateState(JsonToken t)
{
switch (t) {
case START_OBJECT:
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
break;
case START_ARRAY:
_parsingContext = _parsingContext.createChildArrayContext(-1, -1);
break;
case END_OBJECT:
case END_ARRAY:
_parsingContext = _parsingContext.getParent();
_namesToWrap = _parsingContext.getNamesToWrap();
break;
case FIELD_NAME:
_parsingContext.setCurrentName(_xmlTokens.getLocalName());
break;
default:
}
}
/*
/**********************************************************
/* Public API, access to token information, text
/**********************************************************
*/
@Override
public String getText() throws IOException, JsonParseException
{
if (_currToken == null) {
return null;
}
switch (_currToken) {
case FIELD_NAME:
return getCurrentName();
case VALUE_STRING:
return _currText;
default:
return _currToken.asString();
}
}
// @since 2.1
@Override
public final String getValueAsString() throws IOException, JsonParseException {
return getValueAsString(null);
}
@Override
public String getValueAsString(String defValue) throws IOException, JsonParseException
{
JsonToken t = _currToken;
if (t == null) {
return null;
}
switch (t) {
case FIELD_NAME:
return getCurrentName();
case VALUE_STRING:
return _currText;
case START_OBJECT:
// the interesting case; may be able to convert certain kinds of
// elements (specifically, ones with attributes, CDATA only content)
// into VALUE_STRING
{
String str = _xmlTokens.convertToString();
if (str != null) {
// need to convert token, as well as "undo" START_OBJECT
// note: Should NOT update context, because we will still be getting
// matching END_OBJECT, which will undo contexts properly
_parsingContext = _parsingContext.getParent();
_namesToWrap = _parsingContext.getNamesToWrap();
_currToken = JsonToken.VALUE_STRING;
_nextToken = null;
/* One more thing: must explicitly skip the END_OBJECT that
* would follow.
*/
_xmlTokens.skipEndElement();
return (_currText = str);
}
}
return null;
default:
if (_currToken.isScalarValue()) {
return _currToken.asString();
}
}
return defValue;
}
@Override
public char[] getTextCharacters() throws IOException, JsonParseException {
String text = getText();
return (text == null) ? null : text.toCharArray();
}
@Override
public int getTextLength() throws IOException, JsonParseException {
String text = getText();
return (text == null) ? 0 : text.length();
}
@Override
public int getTextOffset() throws IOException, JsonParseException {
return 0;
}
/**
* XML input actually would offer access to character arrays; but since
* we must coalesce things it cannot really be exposed.
*/
@Override
public boolean hasTextCharacters()
{
return false;
}
/*
/**********************************************************
/* Public API, access to token information, binary
/**********************************************************
*/
@Override
public Object getEmbeddedObject() throws IOException, JsonParseException {
// no way to embed POJOs for now...
return null;
}
@Override
public byte[] getBinaryValue(Base64Variant b64variant)
throws IOException, JsonParseException
{
if (_currToken != JsonToken.VALUE_STRING &&
(_currToken != JsonToken.VALUE_EMBEDDED_OBJECT || _binaryValue == null)) {
_reportError("Current token ("+_currToken+") not VALUE_STRING or VALUE_EMBEDDED_OBJECT, can not access as binary");
}
/* To ensure that we won't see inconsistent data, better clear up
* state...
*/
if (_binaryValue == null) {
try {
_binaryValue = _decodeBase64(b64variant);
} catch (IllegalArgumentException iae) {
throw _constructError("Failed to decode VALUE_STRING as base64 ("+b64variant+"): "+iae.getMessage());
}
}
return _binaryValue;
}
protected byte[] _decodeBase64(Base64Variant b64variant) throws IOException
{
ByteArrayBuilder builder = _getByteArrayBuilder();
final String str = getText();
_decodeBase64(str, builder, b64variant);
return builder.toByteArray();
}
/*
/**********************************************************
/* Numeric accessors
/**********************************************************
*/
@Override
public BigInteger getBigIntegerValue() throws IOException {
// TODO Auto-generated method stub
return null;
}
@Override
public BigDecimal getDecimalValue() throws IOException {
// TODO Auto-generated method stub
return null;
}
@Override
public double getDoubleValue() throws IOException {
// TODO Auto-generated method stub
return 0;
}
@Override
public float getFloatValue() throws IOException {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getIntValue() throws IOException {
// TODO Auto-generated method stub
return 0;
}
@Override
public long getLongValue() throws IOException {
// TODO Auto-generated method stub
return 0;
}
@Override
public NumberType getNumberType() throws IOException {
// TODO Auto-generated method stub
return null;
}
@Override
public Number getNumberValue() throws IOException {
// TODO Auto-generated method stub
return null;
}
/*
/**********************************************************
/* Abstract method impls for stuff from JsonParser
/**********************************************************
*/
/**
* Method called when an EOF is encountered between tokens.
* If so, it may be a legitimate EOF, but only iff there
* is no open non-root context.
*/
@Override
protected void _handleEOF() throws JsonParseException
{
if (!_parsingContext.inRoot()) {
_reportInvalidEOF(": expected close marker for "+_parsingContext.getTypeDesc()+" (from "+_parsingContext.getStartLocation(_ioContext.getSourceReference())+")");
}
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
/**
* Method called to release internal buffers owned by the base
* parser.
*/
protected void _releaseBuffers() throws IOException {
// anything we can/must release? Underlying parser should do all of it, for now?
}
protected ByteArrayBuilder _getByteArrayBuilder()
{
if (_byteArrayBuilder == null) {
_byteArrayBuilder = new ByteArrayBuilder();
} else {
_byteArrayBuilder.reset();
}
return _byteArrayBuilder;
}
protected boolean _isEmpty(String str)
{
int len = (str == null) ? 0 : str.length();
if (len > 0) {
for (int i = 0; i < len; ++i) {
if (str.charAt(i) > ' ') {
return false;
}
}
}
return true;
}
}
WrapperHandlingDeserializer.java 0000664 0000000 0000000 00000013735 12516567542 0043570 0 ustar 00root root 0000000 0000000 jackson-dataformat-xml-jackson-dataformat-xml-2.5.3/src/main/java/com/fasterxml/jackson/dataformat/xml/deser package com.fasterxml.jackson.dataformat.xml.deser;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.*;
import com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.dataformat.xml.util.TypeUtil;
/**
* Delegating deserializer whose only function is to handle case of
* "unwrapped" List/array deserialization from XML.
*/
public class WrapperHandlingDeserializer
extends DelegatingDeserializer
{
private static final long serialVersionUID = 1L;
/**
* (Simple) Names of properties, for which virtual wrapping is needed
* to compensate: these are so-called 'unwrapped' XML lists where property
* name is used for elements, and not as List markers.
*/
protected final Set _namesToWrap;
protected final JavaType _type;
/*
/**********************************************************************
/* Construction
/**********************************************************************
*/
public WrapperHandlingDeserializer(BeanDeserializerBase delegate) {
this(delegate, null);
}
public WrapperHandlingDeserializer(BeanDeserializerBase delegate, Set namesToWrap)
{
super(delegate);
_namesToWrap = namesToWrap;
_type = delegate.getValueType();
}
/*
/**********************************************************************
/* Abstract method implementations
/**********************************************************************
*/
@Override
protected JsonDeserializer> newDelegatingInstance(JsonDeserializer> newDelegatee0) {
// default not enough, as we may need to create a new wrapping deserializer
// even if delegatee does not change
throw new IllegalStateException("Internal error: should never get called");
}
@Override
public JsonDeserializer> createContextual(DeserializationContext ctxt,
BeanProperty property)
throws JsonMappingException
{
// !!! 16-Jan-2015, tatu: TODO: change to be like so in 2.6.0 -- leaving
// out for 2.5 just to increase compatibility slightly with 2.4 databind
/*
JavaType vt = _type;
if (vt == null) {
vt = ctxt.constructType(_delegatee.handledType());
}
JsonDeserializer> del = ctxt.handleSecondaryContextualization(_delegatee, property, vt);
*/
JsonDeserializer> del = ctxt.handleSecondaryContextualization(_delegatee, property);
BeanDeserializerBase newDelegatee = _verifyDeserType(del);
// Let's go through the properties now...
Iterator it = newDelegatee.properties();
HashSet unwrappedNames = null;
while (it.hasNext()) {
SettableBeanProperty prop = it.next();
/* First things first: only consider array/Collection types
* (not perfect check, but simplest reasonable check)
*/
JavaType type = prop.getType();
if (!TypeUtil.isIndexedType(type)) {
continue;
}
PropertyName wrapperName = prop.getWrapperName();
// skip anything with wrapper (should work as is)
if (wrapperName != null && wrapperName != PropertyName.NO_NAME) {
continue;
}
if (unwrappedNames == null) {
unwrappedNames = new HashSet();
}
// not optimal; should be able to use PropertyName...
unwrappedNames.add(prop.getName());
}
// Ok: if nothing to take care of, just return the delegatee...
if (unwrappedNames == null) {
return newDelegatee;
}
// Otherwise, create the thing that can deal with virtual wrapping
return new WrapperHandlingDeserializer(newDelegatee, unwrappedNames);
}
/*
/**********************************************************************
/* Overridden deserialization methods
/**********************************************************************
*/
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
_configureParser(jp);
return _delegatee.deserialize(jp, ctxt);
}
@SuppressWarnings("unchecked")
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt,
Object intoValue) throws IOException
{
_configureParser(jp);
return ((JsonDeserializer