pax_global_header00006660000000000000000000000064131474563300014520gustar00rootroot0000000000000052 comment=2f3f5823230a8fbaef4240e9212718d7aef0e6d0 jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/000077500000000000000000000000001314745633000261665ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/.gitattributes000066400000000000000000000001371314745633000310620ustar00rootroot00000000000000# Do not merge `pom.xml` from older version, as it will typically conflict pom.xml merge=ours jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/.gitignore000066400000000000000000000002351314745633000301560ustar00rootroot00000000000000# use glob syntax. syntax: glob *.class *~ *.bak *.off *.old .DS_Store # building target # Eclipse .classpath .project .settings # IDEA *.iml *.ipr *.iws jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/.travis.yml000066400000000000000000000001531314745633000302760ustar00rootroot00000000000000language: java jdk: - oraclejdk7 - oraclejdk8 # whitelist branches: only: - master - "2.7" jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/README.md000066400000000000000000000035141314745633000274500ustar00rootroot00000000000000**NOTE**: This module has become part of [Jackson Base Modules](../../../jackson-modules-base) repo. as of Jackson 2.9 This repo still exists to allow release of patch versions of older versions; it will be hidden (made private) in near future. ----- ## Overview This Jackson extension module provides support for using JAXB (`javax.xml.bind`) annotations as an alternative to native Jackson annotations. It is most often used to make it easier to reuse existing data beans that used with JAXB framework to read and write XML. ## Maven dependency To use this extension on Maven-based projects, use following dependency: ```xml com.fasterxml.jackson.module jackson-module-jaxb-annotations 2.4.0 ``` (or whatever version is most up-to-date at the moment) ## Usage To enable use of JAXB annotations, one must add `JaxbAnnotationIntrospector` provided by this module. There are two ways to do this: * Register `JaxbAnnotationModule`, or * Directly add `JaxbAnnotationIntrospector` Module registration works in standard way: ```java JaxbAnnotationModule module = new JaxbAnnotationModule(); // configure as necessary objectMapper.registerModule(module); ``` and the alternative -- explicit configuration is done as: ```java AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); // if ONLY using JAXB annotations: mapper.setAnnotationIntrospector(introspector); // if using BOTH JAXB annotations AND Jackson annotations: AnnotationIntrospector secondary = new JacksonAnnotationIntrospector(); mapper.setAnnotationIntrospector(new AnnotationIntrospector.Pair(introspector, secondary); ``` Note that by default Module version will use JAXB annotations as the primary, and Jackson annotations as secondary source; but you can change this behavior jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/create-test-report.sh000077500000000000000000000000501314745633000322510ustar00rootroot00000000000000#!/bin/sh mvn surefire-report:report jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/pom.xml000066400000000000000000000066301314745633000275100ustar00rootroot00000000000000 4.0.0 com.fasterxml.jackson jackson-bom 2.8.10 com.fasterxml.jackson.module jackson-module-jaxb-annotations 2.8.10 Jackson module: JAXB-annotations bundle Support for using JAXB annotations as an alternative to "native" Jackson annotations, for configuring data binding. http://github.com/FasterXML/jackson-module-jaxb-annotations scm:git:git@github.com:FasterXML/jackson-module-jaxb-annotations.git scm:git:git@github.com:FasterXML/jackson-module-jaxb-annotations.git http://github.com/FasterXML/jackson-module-jaxb-annotations jackson-module-jaxb-annotations-2.8.10 com/fasterxml/jackson/module/jaxb ${project.groupId}.jaxb com.fasterxml.jackson.core jackson-core com.fasterxml.jackson.core jackson-annotations com.fasterxml.jackson.core jackson-databind javax.xml.bind jaxb-api 2.2 provided junit junit test javax.ws.rs jsr311-api 1.1.1 test org.apache.maven.plugins maven-surefire-plugin ${version.plugin.surefire} com/fasterxml/jackson/**/failing/*.java com.google.code.maven-replacer-plugin replacer process-packageVersion process-sources jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/release-notes/000077500000000000000000000000001314745633000307345ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/release-notes/CREDITS000066400000000000000000000005151314745633000317550ustar00rootroot00000000000000Here are people who have contributed to development Jackson JSON processor JAXB annotation support component. (version numbers in brackets indicate release in which the problem was fixed) Ryan Heaton: author, submitted code first version was based on Tatu Saloranta, tatu.saloranta@iki.fi: author (all code since initial version) jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/release-notes/VERSION000066400000000000000000000107031314745633000320050ustar00rootroot00000000000000Project: jackson-module-jaxb-annotations ------------------------------------------------------------------------ === Releases === ------------------------------------------------------------------------ 2.9.0 (not yet released) 2.8.10 (24-Aug-2017) 2.8.9 (12-Jun-2017) 2.8.8 (05-Apr-2017) 2.8.7 (21-Feb-2017) 2.8.6 (12-Jan-2017) 2.8.5 (14-Nov-2016) 2.8.4 (14-Oct-2016) No changes since 2.8.3 2.8.3 (17-Sep-2016) #61: Transient fields serialized when @XmlAccessorType(XmlAccessType.FIELD) is present (reported by dsharp1@github) 2.8.2 (30-Aug-2016) 2.8.1 (20-Jul-2016) 2.8.0 (04-Jul-2016) No changes since 2.7 2.7.9 (not yet released) #63: Error in type resolution of reference type (`Optional`) (reported by adrianriley@github) 2.7.8 (26-Sep-2016) 2.7.7 (27-Aug-2016) 2.7.6 (23-Jul-2016) 2.7.5 (11-Jun-2016) 2.7.4 (29-Apr-2016) No changes since 2.7.3 2.7.3 (16-Mar-2016) - Minor changes to `JaxbAnnotationIntrospector.findEnumValues()` to help with proper merging of explicit name overrides. 2.7.2 (26-Feb-2016) - Change build to produce JDK6-compatible jar, to allow use on JDK6 runtime 2.7.1 (02-Feb-2016) No change since 2.7.0. 2.7.0 (09-Jan-2016) #52: Add a feature in `JaxbAnnotationIntrospector` to define meaning of `nillable=false` as "JsonInclude.NON_EMPTY" 2.6.6 (05-Apr-2016) 2.6.5 (19-Jan-2016) 2.6.4 (07-Dec-2015) 2.6.3 (12-Oct-2015) No changes since 2.6.2 2.6.2 (15-Sep-2015) #47: JaxbAnnotationIntrospector does not pick up 'required' property of @XmlAttribute (reported by phantomjinx@github) 2.6.1 (09-Aug-2015) 2.6.0 (19-Jul-2015) No changes since 2.5. 2.5.4 (09-Jun-2015) No changes since 2.5.3 2.5.3 (24-Apr-2015) #40: XmlElementRef ignored if inside XmlElementWrapper (reported by gkresic@github) 2.5.2 (29-Mar-2015) No changes since 2.5.1. 2.5.1 (06-Feb-2015) #39: JaxbAnnotationIntrospector does not honor JsonInclude.Include.NON_EMPTY set on ObjectMapper (reported by jdmichal@github) 2.5.0 (01-Jan-2015) #31: Add a way to configure name to use for `@XmlValue` annotated properties #31 2.4.4 (24-Nov-2014) #32: fix deserialization of Collection with @XmlJavaTypeAdapter on method (contributed by Andy C, q3aiml@github) #33: Using @XmlEnum to generate an enum of type Integer in json schema (requested by jesse8888@github) - Fixes to handling of `@XmlValue` provided name (problem with #30 fix) 2.4.3 (03-Oct-2014) No changes. 2.4.2 (14-Aug-2014) #30: Need a way to override name @XmlValue induces when not doing XML 2.4.1 (17-Jun-2014) No changes since 2.4.0. 2.4.0 (02-Jun-2014) No functional changes. 2.3.3 (10-Apr-2014) 2.3.2 (01-Mar-2014) 2.3.1 (28-Dec-2013) No functional changes. 2.3.0 (14-Nov-2013) #25: @XmlElementWrapper() should work wrt USE_WRAPPER_NAME_AS_PROPERTY_NAME, use underlying "default" property name 2.2.3 (23-Aug-2013) #21: Add LICENSE, NOTICE in jar 2.2.2 (27-May-2013) 2.2.1 (03-May-2013) No changes. 2.2.0 (22-Apr-2013) * Fixed last problems with identity adapters resolved * Improved handling of adapters for Map types 2.1.2 (04-Dec-2012) * [Issue#16]: Problems with XmlAdapters for deserialization contents of Collection types (reported by rcpoison@github) * Changed JaxbAnnotationIntrospector to force access if need be (mostly needed for constructing Adapter instances) 2.1.1 (11-Nov-2012) No functional changes. 2.1.0 (08-Oct-2012) Improvements: * [Issue#1]: Support @XmlSeeAlso for specifying subtypes * [Issue#10]: (partial) support for "identity" adapters, for property adapters (but not yet for class-annotated) * [Issue#11]: Add 'JaxbAnnotationModule.setFirstAsId()' to support alternative Object Id serialization ("always-as-id" instead of "first-as-POJO-then-as-id") 2.0.5 (27-Jul-2012) Fixes: * [Issue-9]: Problems with multiple @XmlID, @XmlIDREF properties 2.0.4 (26-Jun-2012) No fixes or changes, released along with other core components 2.0.3 (15-Jun-2012) Fixes: * [Issue-7] Handling of @XmlElementWrapper incorrect wrt @XmlElement (wrong precedence), when used with Jackon XML backend * [Issue-8] Incorrect matching of XmlAdapter/@XmlJavaTypeAdapter, Collection types (reported by @stoyarchukav) 2.0.2 (14-May-2012) No fixes; updated core dependencies to 2.0.2. 2.0.1 (23-Apr-2012) * Made compilation target 1.5; should now work on JDK 1.5 2.0.0 (25-Mar-2012) Fixes: * [JACKSON-722]: Ability to use @XmlJavaTypeAdapter for List/Map values New features: * [Issue#2]: Support @XmlID, @XmlIDREF [entries for versions 1.x and earlier not retained; refer to earlier releases) jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/000077500000000000000000000000001314745633000267555ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/000077500000000000000000000000001314745633000277015ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/000077500000000000000000000000001314745633000306225ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/000077500000000000000000000000001314745633000314005ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/000077500000000000000000000000001314745633000334055ustar00rootroot00000000000000jackson/000077500000000000000000000000001314745633000347565ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxmlmodule/000077500000000000000000000000001314745633000362435ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jacksonjaxb/000077500000000000000000000000001314745633000371675ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/moduleAdapterConverter.java000066400000000000000000000026061314745633000433060ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxbpackage com.fasterxml.jackson.module.jaxb; import javax.xml.bind.annotation.adapters.XmlAdapter; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.StdConverter; public class AdapterConverter extends StdConverter { protected final JavaType _inputType, _targetType; protected final XmlAdapter _adapter; protected final boolean _forSerialization; @SuppressWarnings("unchecked") public AdapterConverter(XmlAdapter adapter, JavaType inType, JavaType outType, boolean ser) { _adapter = (XmlAdapter) adapter; _inputType = inType; _targetType = outType; _forSerialization = ser; } @Override public Object convert(Object value) { try { if (_forSerialization) { return _adapter.marshal(value); } return _adapter.unmarshal(value); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public JavaType getInputType(TypeFactory typeFactory) { return _inputType; } @Override public JavaType getOutputType(TypeFactory typeFactory) { return _targetType; } } JaxbAnnotationIntrospector.java000066400000000000000000002005101314745633000453630ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxbpackage com.fasterxml.jackson.module.jaxb; import java.beans.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.*; import java.util.*; import javax.xml.bind.*; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.*; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.BeanUtil; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.Converter; import com.fasterxml.jackson.module.jaxb.deser.DataHandlerJsonDeserializer; import com.fasterxml.jackson.module.jaxb.ser.DataHandlerJsonSerializer; /** * Annotation introspector that leverages JAXB annotations where applicable to JSON mapping. * As of Jackson 2.0, most JAXB annotations are supported at least to some degree. * Ones that are NOT yet supported are: *
    *
  • {@link XmlAnyAttribute} not yet used (as of 1.5) but may be in future (as an alias for @JsonAnySetter?) *
  • {@link XmlAnyElement} not yet used, may be as per [JACKSON-253] *
  • {@link javax.xml.bind.annotation.XmlAttachmentRef}: JSON does not support external attachments *
  • {@link XmlElementDecl} *
  • {@link XmlElementRefs} because Jackson doesn't have any support for 'named' collection items -- however, * this may become partially supported as per [JACKSON-253]. *
  • {@link javax.xml.bind.annotation.XmlInlineBinaryData} since the underlying concepts * (like XOP) do not exist in JSON -- Jackson will always use inline base64 encoding as the method *
  • {@link javax.xml.bind.annotation.XmlList} because JSON does have (or necessarily need) * method of serializing list of values as space-separated Strings *
  • {@link javax.xml.bind.annotation.XmlMimeType} *
  • {@link javax.xml.bind.annotation.XmlMixed} since JSON has no concept of mixed content *
  • {@link XmlRegistry} *
  • {@link XmlSchema} not used, unlikely to be used *
  • {@link XmlSchemaType} not used, unlikely to be used *
  • {@link XmlSchemaTypes} not used, unlikely to be used *
  • {@link XmlSeeAlso} not yet supported, but [ISSUE-1] filed to use it, so may be supported. *
* * Note also the following limitations: * *
    *
  • Any property annotated with {@link XmlValue} will have implicit property named 'value' on * its JSON object; although (as of 2.4) it should be possible to override this name *
  • *
*

* A note on compatibility with Jackson XML module: since this module does not depend * on Jackson XML module, it is bit difficult to make sure we will properly expose * all information. But effort is made (as of version 2.3.3) to expose this information, * even without using a specific sub-class from that project. * * @author Ryan Heaton * @author Tatu Saloranta */ public class JaxbAnnotationIntrospector extends AnnotationIntrospector implements Versioned { private static final long serialVersionUID = -1L; protected final static String DEFAULT_NAME_FOR_XML_VALUE = "value"; protected final static boolean DEFAULT_IGNORE_XMLIDREF = false; protected final static String MARKER_FOR_DEFAULT = "##default"; // @since 2.5 protected final static JsonFormat.Value FORMAT_STRING = new JsonFormat.Value().withShape(JsonFormat.Shape.STRING); // @since 2.5 protected final static JsonFormat.Value FORMAT_INT = new JsonFormat.Value().withShape(JsonFormat.Shape.NUMBER_INT); protected final String _jaxbPackageName; protected final JsonSerializer _dataHandlerSerializer; protected final JsonDeserializer _dataHandlerDeserializer; protected final TypeFactory _typeFactory; protected final boolean _ignoreXmlIDREF; /** * When using {@link XmlValue} annotation, a placeholder name is assigned * to property (unless overridden by explicit name); this configuration * value specified what that name is. */ protected String _xmlValueName = DEFAULT_NAME_FOR_XML_VALUE; /** * Inclusion value to return for properties annotated with * {@link XmlElement} and {@link XmlElementWrapper}, in case nillable * property is left as false. Default setting is * null; this is typically changed to either * {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_NULL} * or {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_EMPTY}. * * @since 2.7 */ protected JsonInclude.Include _nonNillableInclusion = null; /** * @deprecated Since 2.1, use constructor that takes TypeFactory. */ @Deprecated public JaxbAnnotationIntrospector() { this(TypeFactory.defaultInstance()); } public JaxbAnnotationIntrospector(MapperConfig config) { this(config.getTypeFactory()); } public JaxbAnnotationIntrospector(TypeFactory typeFactory) { this(typeFactory, DEFAULT_IGNORE_XMLIDREF); } /** * @param typeFactory Type factory used for resolving type information * @param ignoreXmlIDREF Whether {@link XmlIDREF} annotation should be processed * JAXB style (meaning that references are always serialized using id), or * not (first reference as full POJO, others as ids) */ public JaxbAnnotationIntrospector(TypeFactory typeFactory, boolean ignoreXmlIDREF) { _typeFactory = (typeFactory == null)? TypeFactory.defaultInstance() : typeFactory; _ignoreXmlIDREF = ignoreXmlIDREF; _jaxbPackageName = XmlElement.class.getPackage().getName(); JsonSerializer dataHandlerSerializer = null; JsonDeserializer dataHandlerDeserializer = null; /* Data handlers included dynamically, to try to prevent issues on platforms * with less than complete support for JAXB API */ try { dataHandlerSerializer = (JsonSerializer) DataHandlerJsonSerializer.class.newInstance(); dataHandlerDeserializer = (JsonDeserializer) DataHandlerJsonDeserializer.class.newInstance(); } catch (Throwable e) { //dataHandlers not supported... } _dataHandlerSerializer = dataHandlerSerializer; _dataHandlerDeserializer = dataHandlerDeserializer; } /** * Method that will return version information stored in and read from jar * that contains this class. */ @Override public Version version() { return PackageVersion.VERSION; } /* /********************************************************** /* Configuration /********************************************************** */ /** * Configuration method that can be used to change default name * ("value") used for properties annotated with {@link XmlValue}; * note that setting it to null will actually avoid * name override, and name will instead be derived from underlying * method name using standard bean name introspection. * * @since 2.5 */ public void setNameUsedForXmlValue(String name) { _xmlValueName = name; } /** * Accessor for getting currently configured placeholder named * used for property annotated with {@link XmlValue}. */ public String getNameUsedForXmlValue() { return _xmlValueName; } /** * Method to call to change inclusion criteria used for property annotated * with {@link XmlElement} or {@link XmlElementWrapper}, with nillable * set as false. * * @since 2.7 */ public JaxbAnnotationIntrospector setNonNillableInclusion(JsonInclude.Include incl) { _nonNillableInclusion = incl; return this; } /** * @since 2.7 */ public JsonInclude.Include getNonNillableInclusion() { return _nonNillableInclusion; } /* /********************************************************** /* Extended API (XmlAnnotationIntrospector) /********************************************************** */ // From XmlAnnotationIntrospector // @Override public String findNamespace(Annotated ann) { String ns = null; if (ann instanceof AnnotatedClass) { // For classes, it must be @XmlRootElement. Also, we do // want to use defaults from package, base class XmlRootElement elem = findRootElementAnnotation((AnnotatedClass) ann); if (elem != null) { ns = elem.namespace(); } } else { // For others, XmlElement or XmlAttribute work (anything else?) XmlElement elem = findAnnotation(XmlElement.class, ann, false, false, false); if (elem != null) { ns = elem.namespace(); } if (ns == null || MARKER_FOR_DEFAULT.equals(ns)) { XmlAttribute attr = findAnnotation(XmlAttribute.class, ann, false, false, false); if (attr != null) { ns = attr.namespace(); } } } // JAXB uses marker for "not defined" if (MARKER_FOR_DEFAULT.equals(ns)) { ns = null; } return ns; } // From XmlAnnotationIntrospector // @Override /** * Here we assume fairly simple logic; if there is XmlAttribute to be found, * we consider it an attribute; if XmlElement, not-an-attribute; and otherwise * we will consider there to be no information. * Caller is likely to default to considering things as elements. */ public Boolean isOutputAsAttribute(Annotated ann) { XmlAttribute attr = findAnnotation(XmlAttribute.class, ann, false, false, false); if (attr != null) { return Boolean.TRUE; } XmlElement elem = findAnnotation(XmlElement.class, ann, false, false, false); if (elem != null) { return Boolean.FALSE; } return null; } // From XmlAnnotationIntrospector // @Override public Boolean isOutputAsText(Annotated ann) { XmlValue attr = findAnnotation(XmlValue.class, ann, false, false, false); if (attr != null) { return Boolean.TRUE; } return null; } /* /********************************************************** /* General annotations (for classes, properties) /********************************************************** */ @Override public ObjectIdInfo findObjectIdInfo(Annotated ann) { /* To work in the way that works with JAXB and Jackson, * we need to do things in bit of round-about way, starting * with AnnotatedClass, locating @XmlID property, if any. */ if (!(ann instanceof AnnotatedClass)) { return null; } AnnotatedClass ac = (AnnotatedClass) ann; /* Ideally, should not have to infer settings for class from * individual fields and/or methods; but for now this * has to do ... */ PropertyName idPropName = null; method_loop: for (AnnotatedMethod m : ac.memberMethods()) { XmlID idProp = m.getAnnotation(XmlID.class); if (idProp == null) { continue; } switch (m.getParameterCount()) { case 0: // getter idPropName = findJaxbPropertyName(m, m.getRawType(), BeanUtil.okNameForGetter(m, true)); break method_loop; case 1: // setter idPropName = findJaxbPropertyName(m, m.getRawType(), BeanUtil.okNameForSetter(m, true)); break method_loop; } } if (idPropName == null) { for (AnnotatedField f : ac.fields()) { XmlID idProp = f.getAnnotation(XmlID.class); if (idProp != null) { idPropName = findJaxbPropertyName(f, f.getRawType(), f.getName()); break; } } } if (idPropName != null) { /* Scoping... hmmh. Could XML requires somewhat global scope, n'est pas? * The alternative would be to use declared type of this class. */ Class scope = Object.class; // alternatively would use 'ac.getRawType()' // and we will assume that there exists property thus named... return new ObjectIdInfo(idPropName, scope, ObjectIdGenerators.PropertyGenerator.class, // should we customize Object Id resolver somehow? SimpleObjectIdResolver.class); } return null; } @Override public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo base) { if (!_ignoreXmlIDREF) { XmlIDREF idref = ann.getAnnotation(XmlIDREF.class); /* JAXB makes XmlIDREF mean "always as id", as far as I know. * May need to make it configurable in future, but for not that * is fine... */ if (idref != null) { if (base == null) { base = ObjectIdInfo.empty(); } base = base.withAlwaysAsId(true); } } return base; } /* /********************************************************** /* General class annotations /********************************************************** */ @Override public PropertyName findRootName(AnnotatedClass ac) { XmlRootElement elem = findRootElementAnnotation(ac); if (elem != null) { return _combineNames(elem.name(), elem.namespace(), ""); } return null; } /* @Override public String[] findPropertiesToIgnore(Annotated a) { // nothing in JAXB for this? return null; } */ /* 08-Nov-2009, tatus: This is bit trickier: by default JAXB * does actually ignore all unknown properties. * But since there is no annotation to * specify or change this, it seems wrong to claim such setting * is in effect. May need to revisit this issue in future */ /* @Override public Boolean findIgnoreUnknownProperties(AnnotatedClass ac); @Override public JsonIgnoreProperties.Value findPropertyIgnorals(Annotated ac); */ @Override public Boolean isIgnorableType(AnnotatedClass ac) { // Does JAXB have any such indicators? No? return null; } /* /********************************************************** /* General member (field, method/constructor) annotations /********************************************************** */ @Override public boolean hasIgnoreMarker(AnnotatedMember m) { return m.getAnnotation(XmlTransient.class) != null; } //(ryan) JAXB has @XmlAnyAttribute and @XmlAnyElement annotations, but they're not applicable in this case // because JAXB says those annotations are only applicable to methods with specific signatures // that Jackson doesn't support (Jackson's any setter needs 2 arguments, name and value, whereas // JAXB expects use of Map // 28-May-2016, tatu: While `@XmlAnyAttribute` looks ALMOST like applicable (esp. // assuming Jackson could use `Map` field, not just setter/getter), it is alas not. // The reason is that key is expected to be `QNmae`, XML/JAXB specific name and // something Jackson does not require or use /* @Override public boolean hasAnySetterAnnotation(AnnotatedMethod am) { } @Override public boolean hasAnySetterAnnotation(AnnotatedMethod am) */ @Override public Boolean hasRequiredMarker(AnnotatedMember m) { XmlElement elem = m.getAnnotation(XmlElement.class); if ((elem != null) && elem.required()) { return Boolean.TRUE; } XmlAttribute attr = m.getAnnotation(XmlAttribute.class); if ((attr != null) && attr.required()) { return Boolean.TRUE; } // 09-Sep-2015, tatu: Not 100% sure that we should ever return `false` // here (as it blocks calls to secondary introspector), but since that // was the existing behavior before 2.6, is retained for now. if ((elem != null) || (attr != null)) { return null; } return Boolean.FALSE; } @Override public PropertyName findWrapperName(Annotated ann) { XmlElementWrapper w = findAnnotation(XmlElementWrapper.class, ann, false, false, false); if (w != null) { /* 18-Sep-2013, tatu: As per [jaxb-annotations#24], need to take special care with empty * String, as that should indicate here "use underlying unmodified * property name" (that is, one NOT overridden by @JsonProperty) */ PropertyName name = _combineNames(w.name(), w.namespace(), ""); // clumsy, yes, but has to do: if (!name.hasSimpleName()) { if (ann instanceof AnnotatedMethod) { AnnotatedMethod am = (AnnotatedMethod) ann; String str; if (am.getParameterCount() == 0) { str = BeanUtil.okNameForGetter(am, true); } else { str = BeanUtil.okNameForSetter(am, true); } if (str != null) { return name.withSimpleName(str); } } return name.withSimpleName(ann.getName()); } return name; } return null; } // since 2.4 @Override public String findImplicitPropertyName(AnnotatedMember m) { XmlValue valueInfo = m.getAnnotation(XmlValue.class); if (valueInfo != null) { return _xmlValueName; } return null; } @Override public JsonFormat.Value findFormat(Annotated m) { /* [jaxb-annotations#33]: Use @XmlEnum value (Class) to indicate format, * iff it makes sense */ if (m instanceof AnnotatedClass) { XmlEnum ann = m.getAnnotation(XmlEnum.class); if (ann != null) { Class type = ann.value(); if (type == String.class || type.isEnum()) { return FORMAT_STRING; } if (Number.class.isAssignableFrom(type)) { return FORMAT_INT; } } } return null; } /* /********************************************************** /* Property auto-detection /********************************************************** */ @Override public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, VisibilityChecker checker) { XmlAccessType at = findAccessType(ac); if (at == null) { /* JAXB default is "PUBLIC_MEMBER"; however, here we should not * override settings if there is no annotation -- that would mess * up global baseline. Fortunately Jackson defaults are very close * to JAXB 'PUBLIC_MEMBER' settings (considering that setters and * getters must come in pairs) */ return checker; } // Note: JAXB does not do creator auto-detection, can (and should) ignore switch (at) { case FIELD: // all fields, independent of visibility; no methods return checker.withFieldVisibility(Visibility.ANY) .withSetterVisibility(Visibility.NONE) .withGetterVisibility(Visibility.NONE) .withIsGetterVisibility(Visibility.NONE) ; case NONE: // no auto-detection return checker.withFieldVisibility(Visibility.NONE) .withSetterVisibility(Visibility.NONE) .withGetterVisibility(Visibility.NONE) .withIsGetterVisibility(Visibility.NONE) ; case PROPERTY: return checker.withFieldVisibility(Visibility.NONE) .withSetterVisibility(Visibility.PUBLIC_ONLY) .withGetterVisibility(Visibility.PUBLIC_ONLY) .withIsGetterVisibility(Visibility.PUBLIC_ONLY) ; case PUBLIC_MEMBER: return checker.withFieldVisibility(Visibility.PUBLIC_ONLY) .withSetterVisibility(Visibility.PUBLIC_ONLY) .withGetterVisibility(Visibility.PUBLIC_ONLY) .withIsGetterVisibility(Visibility.PUBLIC_ONLY) ; } return checker; } /** * Method for locating JAXB {@link XmlAccessType} annotation value * for given annotated entity, if it has one, or inherits one from * its ancestors (in JAXB sense, package etc). Returns null if * nothing has been explicitly defined. */ protected XmlAccessType findAccessType(Annotated ac) { XmlAccessorType at = findAnnotation(XmlAccessorType.class, ac, true, true, true); return (at == null) ? null : at.value(); } /* /********************************************************** /* Class annotations for PM type handling (1.5+) /********************************************************** */ @Override public TypeResolverBuilder findTypeResolver(MapperConfig config, AnnotatedClass ac, JavaType baseType) { // no per-class type resolvers, right? return null; } @Override public TypeResolverBuilder findPropertyTypeResolver(MapperConfig config, AnnotatedMember am, JavaType baseType) { /* First: @XmlElements and @XmlElementRefs only applies type for immediate property, if it * is NOT a structured type. */ if (baseType.isContainerType()) return null; return _typeResolverFromXmlElements(am); } @Override public TypeResolverBuilder findPropertyContentTypeResolver(MapperConfig config, AnnotatedMember am, JavaType containerType) { /* First: let's ensure property is a container type: caller should have * verified but just to be sure */ if (containerType.getContentType() == null) { throw new IllegalArgumentException("Must call method with a container or reference type (got "+containerType+")"); } return _typeResolverFromXmlElements(am); } protected TypeResolverBuilder _typeResolverFromXmlElements(AnnotatedMember am) { /* If simple type, @XmlElements and @XmlElementRefs are applicable. * Note: @XmlElement and @XmlElementRef are NOT handled here, since they * are handled specifically as non-polymorphic indication * of the actual type */ XmlElements elems = findAnnotation(XmlElements.class, am, false, false, false); XmlElementRefs elemRefs = findAnnotation(XmlElementRefs.class, am, false, false, false); if (elems == null && elemRefs == null) { return null; } TypeResolverBuilder b = new StdTypeResolverBuilder(); // JAXB always uses type name as id b = b.init(JsonTypeInfo.Id.NAME, null); // and let's consider WRAPPER_OBJECT to be canonical inclusion method b = b.inclusion(JsonTypeInfo.As.WRAPPER_OBJECT); return b; } @Override public List findSubtypes(Annotated a) { // No package/superclass defaulting (only used with fields, methods) XmlElements elems = findAnnotation(XmlElements.class, a, false, false, false); ArrayList result = null; if (elems != null) { result = new ArrayList(); for (XmlElement elem : elems.value()) { String name = elem.name(); if (MARKER_FOR_DEFAULT.equals(name)) name = null; result.add(new NamedType(elem.type(), name)); } } else { XmlElementRefs elemRefs = findAnnotation(XmlElementRefs.class, a, false, false, false); if (elemRefs != null) { result = new ArrayList(); for (XmlElementRef elemRef : elemRefs.value()) { Class refType = elemRef.type(); // only good for types other than JAXBElement (which is XML based) if (!JAXBElement.class.isAssignableFrom(refType)) { // first consider explicit name declaration String name = elemRef.name(); if (name == null || MARKER_FOR_DEFAULT.equals(name)) { XmlRootElement rootElement = (XmlRootElement) refType.getAnnotation(XmlRootElement.class); if (rootElement != null) { name = rootElement.name(); } } if (name == null || MARKER_FOR_DEFAULT.equals(name)) { name = Introspector.decapitalize(refType.getSimpleName()); } result.add(new NamedType(refType, name)); } } } } // Check @XmlSeeAlso as well. /* 17-Aug-2012, tatu: But wait! For structured type, what we really is * value (content) type! * If code below does not make full (or any) sense, do not despair -- it * is wrong. Yet it works. The call sequence before we get here is mangled, * its logic twisted... but as Dire Straits put it: "That ain't working -- * that's The Way You Do It!" */ XmlSeeAlso ann = a.getAnnotation(XmlSeeAlso.class); if (ann != null) { if (result == null) { result = new ArrayList(); } for (Class cls : ann.value()) { result.add(new NamedType(cls)); } } return result; } @Override public String findTypeName(AnnotatedClass ac) { XmlType type = findAnnotation(XmlType.class, ac, false, false, false); if (type != null) { String name = type.name(); if (!MARKER_FOR_DEFAULT.equals(name)) return name; } return null; } /* /********************************************************** /* Serialization: general annotations /********************************************************** */ @Override public JsonSerializer findSerializer(Annotated am) { final Class type = _rawSerializationType(am); /* // As per [JACKSON-722], more checks for structured types XmlAdapter adapter = findAdapter(am, true, type); if (adapter != null) { boolean fromClass = !(am instanceof AnnotatedMember); // Ugh. Must match to see if adapter's bounded type (result to map to) matches property type if (isContainerType(type)) { Class bt = findAdapterBoundType(adapter); if (bt.isAssignableFrom(type)) { return new XmlAdapterJsonSerializer(adapter, fromClass); } // Note: if used for value type, handled in different place } else { return new XmlAdapterJsonSerializer(adapter, fromClass); } } */ // Add support for additional core XML types needed by JAXB if (type != null) { if (_dataHandlerSerializer != null && isDataHandler(type)) { return _dataHandlerSerializer; } } return null; } /** * Determines whether the type is assignable to class javax.activation.DataHandler without requiring that class * to be on the classpath. * * @param type The type. * @return Whether the type is assignable to class javax.activation.DataHandler */ private boolean isDataHandler(Class type) { return type != null && (Object.class != type) && (("javax.activation.DataHandler".equals(type.getName()) || isDataHandler(type.getSuperclass()))); } @Override public Object findContentSerializer(Annotated a) { return null; } @Override @Deprecated // since 2.7 public Class findSerializationType(Annotated a) { Class allegedType = _getTypeFromXmlElement(a); if (allegedType != null){ Class rawPropType = _rawSerializationType(a); if (!isContainerType(rawPropType)) { return allegedType; } } return null; } /** * Implementation of this method is slightly tricky, given that JAXB defaults differ * from Jackson defaults. As of version 1.5 and above, this is resolved by honoring * Jackson defaults (which are configurable), and only using JAXB explicit annotations. */ @Override @Deprecated // since 2.7; remove from 2.8 public JsonInclude.Include findSerializationInclusion(Annotated a, JsonInclude.Include defValue) { XmlElementWrapper w = a.getAnnotation(XmlElementWrapper.class); if (w != null) { if (w.nillable()) { return JsonInclude.Include.ALWAYS; } // [jaxb-annotations#52]: Allow specifying inclusion for `nillable=false` too if (_nonNillableInclusion != null) { return _nonNillableInclusion; } } XmlElement e = a.getAnnotation(XmlElement.class); if (e != null) { if (e.nillable()) { return JsonInclude.Include.ALWAYS; } // [jaxb-annotations#52]: Allow specifying inclusion for `nillable=false` too if (_nonNillableInclusion != null) { return _nonNillableInclusion; } } //better pass default value through, if no explicit direction indicating otherwise return defValue; } @Override // @since 2.7 public JsonInclude.Value findPropertyInclusion(Annotated a) { JsonInclude.Include incl = findSerializationInclusion(a, null); if (incl == null) { return JsonInclude.Value.empty(); } return JsonInclude.Value.construct(incl, null); } @Override // @since 2.7 public JavaType refineSerializationType(final MapperConfig config, final Annotated a, final JavaType baseType) throws JsonMappingException { Class serClass = _getTypeFromXmlElement(a); if (serClass == null) { return baseType; } // First, JAXB has no annotations for key type, so can skip that part (wrt std annotations) // But the meaning of main annotation(s) varies between container/non-container types final TypeFactory tf = config.getTypeFactory(); if (baseType.getContentType() == null) { // non-container/-structured types, usually scalar: // 27-Nov-2015, tatu: Since JAXB has just one annotation, must ignore it in // one direction, typically serialization (but not always): if (!serClass.isAssignableFrom(baseType.getRawClass())) { return baseType; } if (baseType.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way return baseType.withStaticTyping(); } try { return tf.constructGeneralizedType(baseType, serClass); } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", baseType, serClass.getName(), a.getName(), iae.getMessage()), iae); } } else { // Otherwise, structured type: JavaType contentType = baseType.getContentType(); if (contentType != null) { // collection[like], map[like], array, reference // as per earlier, may need to ignore annotation meant for deserialization if (!serClass.isAssignableFrom(contentType.getRawClass())) { return baseType; } // And then value types for all containers: if (contentType.hasRawClass(serClass)) { contentType = contentType.withStaticTyping(); } else { try { contentType = tf.constructGeneralizedType(contentType, serClass); } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen value type of %s with concrete-type annotation (value %s), from '%s': %s", baseType, serClass.getName(), a.getName(), iae.getMessage()), iae); } } return baseType.withContentType(contentType); } } return baseType; } /* /********************************************************** /* Serialization: class annotations /********************************************************** */ @Override public String[] findSerializationPropertyOrder(AnnotatedClass ac) { // @XmlType.propOrder fits the bill here: XmlType type = findAnnotation(XmlType.class, ac, true, true, true); if (type == null) { return null; } String[] order = type.propOrder(); if (order == null || order.length == 0) { return null; } return order; } @Override public Boolean findSerializationSortAlphabetically(Annotated ann) { return _findAlpha(ann); } private final Boolean _findAlpha(Annotated ann) { XmlAccessorOrder order = findAnnotation(XmlAccessorOrder.class, ann, true, true, true); return (order == null) ? null : (order.value() == XmlAccessOrder.ALPHABETICAL); } @Override public Object findSerializationConverter(Annotated a) { Class serType = _rawSerializationType(a); // Can apply to both container and regular type; no difference yet here XmlAdapter adapter = findAdapter(a, true, serType); if (adapter != null) { return _converter(adapter, true); } return null; } @Override public Object findSerializationContentConverter(AnnotatedMember a) { // But this one only applies to structured (container) types: Class serType = _rawSerializationType(a); if (isContainerType(serType)) { XmlAdapter adapter = _findContentAdapter(a, true); if (adapter != null) { return _converter(adapter, true); } } return null; } /* /********************************************************** /* Serialization: property annotations /********************************************************** */ @Override public PropertyName findNameForSerialization(Annotated a) { // need bit of delegation (note: copy of super-class functionality) if (a instanceof AnnotatedMethod) { AnnotatedMethod am = (AnnotatedMethod) a; if (!isVisible(am)) { return null; } return findJaxbPropertyName(am, am.getRawType(), BeanUtil.okNameForGetter(am, true)); } if (a instanceof AnnotatedField) { AnnotatedField af = (AnnotatedField) a; if (!isVisible(af)) { return null; } // Hmmh. As per [jaxb-annotations#61], looks like we must do one more thing to // avoid accidentally exposing transient fields: this is necessary because later on // our returning of "" suggests explicit annotation, which is NOT true, but may be // necessary to indicate that visibility level is satisfied. That works ok except // for specific case of transient fields that we must suppress now if (af.isTransient()) { return null; } PropertyName name = findJaxbPropertyName(af, af.getRawType(), null); /* This may seem wrong, but since JAXB field auto-detection * needs to find even non-public fields (if enabled by * JAXB access type), we need to return name like so: */ // 31-Oct-2014, tatu: As per [jaxb-annotations#31], need to be careful to indicate "use default" // and NOT to force use of specific name; latter would establish explicit name // and what we want is implicit (unless there is real explicitly annotated name) if (name == null) { return PropertyName.USE_DEFAULT; } return name; } return null; } @Override public boolean hasAsValueAnnotation(AnnotatedMethod am) { //since jaxb says @XmlValue can exist with attributes, this won't map as a JSON value. return false; } /** *

* This is very slow implementation, but as of Jackson 2.7, should not be called any more; * instead, {@link #findEnumValues} should be called which has less overhead. */ @Deprecated // since 2.8, remove from 2.9? @Override public String findEnumValue(Enum e) { Class enumClass = e.getDeclaringClass(); String enumValue = e.name(); try { XmlEnumValue xmlEnumValue = enumClass.getDeclaredField(enumValue).getAnnotation(XmlEnumValue.class); return (xmlEnumValue != null) ? xmlEnumValue.value() : enumValue; } catch (NoSuchFieldException e1) { throw new IllegalStateException("Could not locate Enum entry '"+enumValue+"' (Enum class "+enumClass.getName()+")", e1); } } @Override // since 2.7 public String[] findEnumValues(Class enumType, Enum[] enumValues, String[] names) { HashMap expl = null; for (Field f : ClassUtil.getDeclaredFields(enumType)) { if (!f.isEnumConstant()) { continue; } XmlEnumValue enumValue = f.getAnnotation(XmlEnumValue.class); if (enumValue == null) { continue; } String n = enumValue.value(); if (n.isEmpty()) { continue; } if (expl == null) { expl = new HashMap(); } expl.put(f.getName(), n); } // and then stitch them together if and as necessary if (expl != null) { for (int i = 0, end = enumValues.length; i < end; ++i) { String defName = enumValues[i].name(); String explValue = expl.get(defName); if (explValue != null) { names[i] = explValue; } } } return names; } /* /********************************************************** /* Deserialization: general annotations /********************************************************** */ @Override public Object findDeserializer(Annotated am) { final Class type = _rawDeserializationType(am); /* // As per [JACKSON-722], more checks for structured types XmlAdapter adapter = findAdapter(am, true, type); if (adapter != null) { // Ugh. Must match to see if adapter's bounded type (result to map to) matches property type if (isContainerType(type)) { if (adapterTypeMatches(adapter, type)) { return new XmlAdapterJsonDeserializer(adapter); } } else { return new XmlAdapterJsonDeserializer(adapter); } } */ // [JACKSON-150]: add support for additional core XML types needed by JAXB if (type != null) { if (_dataHandlerDeserializer != null && isDataHandler(type)) { return _dataHandlerDeserializer; } } return null; } @Override public Object findKeyDeserializer(Annotated am) { // Is there something like this in JAXB? return null; } @Override public Object findContentDeserializer(Annotated a) { return null; } /** * JAXB does allow specifying (more) concrete class for * deserialization by using \@XmlElement annotation. */ @Override @Deprecated // since 2.7 public Class findDeserializationType(Annotated a, JavaType baseType) { // First: only applicable for non-structured types (yes, JAXB annotations are tricky) if (!baseType.isContainerType()) { return _doFindDeserializationType(a, baseType); } return null; } //public Class findDeserializationKeyType(Annotated am, JavaType baseKeyType) @Override @Deprecated // since 2.7 public Class findDeserializationContentType(Annotated a, JavaType baseContentType) { /* 15-Feb-2010, tatus: JAXB usage of XmlElement/XmlElements is really * confusing: sometimes it's for type (non-container types), sometimes for * contents (container) types. I guess it's frugal to reuse these... but * I think it's rather short-sighted. Whatever, it is what it is, and here * we are being given content type explicitly. */ return _doFindDeserializationType(a, baseContentType); } protected Class _doFindDeserializationType(Annotated a, JavaType baseType) { /* As per [JACKSON-288], @XmlJavaTypeAdapter will complicate handling of type * information; basically we better just ignore type we might find here altogether * in that case */ if (a.hasAnnotation(XmlJavaTypeAdapter.class)) { return null; } /* false for class, package, super-class, since annotation can * only be attached to fields and methods */ XmlElement annotation = findAnnotation(XmlElement.class, a, false, false, false); if (annotation != null) { Class type = annotation.type(); if (type != XmlElement.DEFAULT.class) { return type; } } return null; } // @since 2.7 @Override public JavaType refineDeserializationType(final MapperConfig config, final Annotated a, final JavaType baseType) throws JsonMappingException { Class deserClass = _getTypeFromXmlElement(a); if (deserClass == null) { return baseType; } final TypeFactory tf = config.getTypeFactory(); if (baseType.getContentType() == null) { // non-container/-structured types, usually scalar: if (baseType.hasRawClass(deserClass)) { // no change return baseType; } // 27-Nov-2015, tatu: Since JAXB has just one annotation, must ignore it in // one direction, typically serialization (but not always): if (!baseType.getRawClass().isAssignableFrom(deserClass)) { return baseType; } try { return tf.constructSpecializedType(baseType, deserClass); } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to narrow type %s with annotation (value %s), from '%s': %s", baseType, deserClass.getName(), a.getName(), iae.getMessage()), iae); } } else { // Otherwise, structured type: JavaType contentType = baseType.getContentType(); if (contentType != null) { // collection[like], map[like], array, reference // as per earlier, may need to ignore annotation meant for deserialization if (!contentType.getRawClass().isAssignableFrom(deserClass)) { return baseType; } // And then value types for all containers: try { contentType = tf.constructSpecializedType(contentType, deserClass); return baseType.withContentType(contentType); } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to narrow type %s with annotation (value %s), from '%s': %s", baseType, deserClass.getName(), a.getName(), iae.getMessage()), iae); } } } return baseType; } /* /********************************************************** /* Deserialization: property annotations /********************************************************** */ @Override public PropertyName findNameForDeserialization(Annotated a) { // need bit of delegation -- note: copy from super-class // TODO: should simplify, messy. if (a instanceof AnnotatedMethod) { AnnotatedMethod am = (AnnotatedMethod) a; if (!isVisible((AnnotatedMethod) a)) { return null; } Class rawType = am.getRawParameterType(0); return findJaxbPropertyName(am, rawType, BeanUtil.okNameForSetter(am, true)); } if (a instanceof AnnotatedField) { AnnotatedField af = (AnnotatedField) a; if (!isVisible(af)) { return null; } // As per [jaxb-annotations#61] need to do explicit suppress (see // `findNameForSerialization` for details) if (af.isTransient()) { return null; } PropertyName name = findJaxbPropertyName(af, af.getRawType(), null); /* This may seem wrong, but since JAXB field auto-detection * needs to find even non-public fields (if enabled by * JAXB access type), we need to return name like so: */ // 31-Oct-2014, tatu: As per [jaxb-annotations#31], need to be careful to indicate "use default" // and NOT to force use of specific name; latter would establish explicit name // and what we want is implicit (unless there is real explicitly annotated name) if (name == null) { return PropertyName.USE_DEFAULT; } return name; } return null; } @Override public boolean hasCreatorAnnotation(Annotated am) { return false; } @Override public Object findDeserializationConverter(Annotated a) { // One limitation: for structured types this is done later on Class deserType = _rawDeserializationType(a); if (isContainerType(deserType)) { XmlAdapter adapter = findAdapter(a, true, deserType); if (adapter != null) { return _converter(adapter, false); } } else { XmlAdapter adapter = findAdapter(a, true, deserType); if (adapter != null) { return _converter(adapter, false); } } return null; } @Override public Object findDeserializationContentConverter(AnnotatedMember a) { // conversely, here we only apply this to container types: Class deserType = _rawDeserializationType(a); if (isContainerType(deserType)) { XmlAdapter adapter = _findContentAdapter(a, false); if (adapter != null) { return _converter(adapter, false); } } return null; } /* /********************************************************** /* Helper methods (non-API) /********************************************************** */ /** * Whether the specified field is invisible, per the JAXB visibility rules. * * @param f The field. * @return Whether the field is invisible. */ private boolean isVisible(AnnotatedField f) { // TODO: use AnnotatedField's annotations directly for (Annotation annotation : f.getAnnotated().getDeclaredAnnotations()) { if (isJAXBAnnotation(annotation)) { return true; } } XmlAccessType accessType = XmlAccessType.PUBLIC_MEMBER; XmlAccessorType at = findAnnotation(XmlAccessorType.class, f, true, true, true); if (at != null) { accessType = at.value(); } if (accessType == XmlAccessType.FIELD) { return true; } if (accessType == XmlAccessType.PUBLIC_MEMBER) { return Modifier.isPublic(f.getAnnotated().getModifiers()); } return false; } private boolean isVisible(AnnotatedMethod m) { // TODO: use AnnotatedField's annotations directly for (Annotation annotation : m.getAnnotated().getDeclaredAnnotations()) { if (isJAXBAnnotation(annotation)) { return true; } } XmlAccessType accessType = XmlAccessType.PUBLIC_MEMBER; XmlAccessorType at = findAnnotation(XmlAccessorType.class, m, true, true, true); if (at != null) { accessType = at.value(); } if (accessType == XmlAccessType.PROPERTY || accessType == XmlAccessType.PUBLIC_MEMBER) { return Modifier.isPublic(m.getModifiers()); } return false; } /** * Finds an annotation associated with given annotatable thing; or if * not found, a default annotation it may have (from super class, package * and so on) * * @param annotationClass the annotation class. * @param annotated The annotated element. * @param includePackage Whether the annotation can be found on the package of the annotated element. * @param includeClass Whether the annotation can be found on the class of the annotated element. * @param includeSuperclasses Whether the annotation can be found on any superclasses of the class of the annotated element. * @return The annotation, or null if not found. */ private A findAnnotation(Class annotationClass, Annotated annotated, boolean includePackage, boolean includeClass, boolean includeSuperclasses) { A annotation = annotated.getAnnotation(annotationClass); if (annotation != null) { return annotation; } Class memberClass = null; /* 13-Feb-2011, tatu: [JACKSON-495] - need to handle AnnotatedParameter * bit differently, since there is no JDK counterpart. We can still * access annotations directly, just using different calls. */ if (annotated instanceof AnnotatedParameter) { memberClass = ((AnnotatedParameter) annotated).getDeclaringClass(); } else { AnnotatedElement annType = annotated.getAnnotated(); if (annType instanceof Member) { memberClass = ((Member) annType).getDeclaringClass(); if (includeClass) { annotation = (A) memberClass.getAnnotation(annotationClass); if (annotation != null) { return annotation; } } } else if (annType instanceof Class) { memberClass = (Class) annType; } else { throw new IllegalStateException("Unsupported annotated member: " + annotated.getClass().getName()); } } if (memberClass != null) { if (includeSuperclasses) { Class superclass = memberClass.getSuperclass(); while (superclass != null && superclass != Object.class) { annotation = (A) superclass.getAnnotation(annotationClass); if (annotation != null) { return annotation; } superclass = superclass.getSuperclass(); } } if (includePackage) { Package pkg = memberClass.getPackage(); if (pkg != null) { return memberClass.getPackage().getAnnotation(annotationClass); } } } return null; } /* /********************************************************** /* Helper methods for bean property introspection /********************************************************** */ /** * An annotation is handled if it's in the same package as @XmlElement, including subpackages. * * @param ann The annotation. * @return Whether the annotation is in the JAXB package. */ protected boolean isJAXBAnnotation(Annotation ann) { /* note: class we want is the annotation class, not instance * (since annotation instances, like enums, may be of different * physical type!) */ Class cls = ann.annotationType(); Package pkg = cls.getPackage(); String pkgName = (pkg != null) ? pkg.getName() : cls.getName(); if (pkgName.startsWith(_jaxbPackageName)) { return true; } return false; } private static PropertyName findJaxbPropertyName(Annotated ae, Class aeType, String defaultName) { XmlAttribute attribute = ae.getAnnotation(XmlAttribute.class); if (attribute != null) { return _combineNames(attribute.name(), attribute.namespace(), defaultName); } XmlElement element = ae.getAnnotation(XmlElement.class); if (element != null) { return _combineNames(element.name(), element.namespace(), defaultName); } XmlElementRef elementRef = ae.getAnnotation(XmlElementRef.class); boolean hasAName = (elementRef != null); if (hasAName) { if (!MARKER_FOR_DEFAULT.equals(elementRef.name())) { return _combineNames(elementRef.name(), elementRef.namespace(), defaultName); } if (aeType != null) { XmlRootElement rootElement = (XmlRootElement) aeType.getAnnotation(XmlRootElement.class); if (rootElement != null) { String name = rootElement.name(); if (!MARKER_FOR_DEFAULT.equals(name)) { return _combineNames(name, rootElement.namespace(), defaultName); } // Is there a namespace there to use? Probably not? return new PropertyName(Introspector.decapitalize(aeType.getSimpleName())); } } } if (!hasAName) { hasAName = ae.hasAnnotation(XmlElementWrapper.class); } // 09-Aug-2014, tatu: Note: prior to 2.4.2, we used to give explicit name "value" // if there was "@XmlValue" annotation; since then, only implicit name. // One more thing: return hasAName ? PropertyName.USE_DEFAULT : null; } private static PropertyName _combineNames(String localName, String namespace, String defaultName) { if (MARKER_FOR_DEFAULT.equals(localName)) { if (MARKER_FOR_DEFAULT.equals(namespace)) { return new PropertyName(defaultName); } return new PropertyName(defaultName, namespace); } if (MARKER_FOR_DEFAULT.equals(namespace)) { return new PropertyName(localName); } return new PropertyName(localName, namespace); } private XmlRootElement findRootElementAnnotation(AnnotatedClass ac) { // Yes, check package, no class (already included), yes superclasses return findAnnotation(XmlRootElement.class, ac, true, false, true); } /** * Finds the XmlAdapter for the specified annotation. * * @param am The annotated element. * @param forSerialization If true, adapter for serialization; if false, for deserialization * @param type * * @return The adapter, or null if none. */ private XmlAdapter findAdapter(Annotated am, boolean forSerialization, Class type) { // First of all, are we looking for annotations for class? if (am instanceof AnnotatedClass) { return findAdapterForClass((AnnotatedClass) am, forSerialization); } // Otherwise for a member. First, let's figure out type of property XmlJavaTypeAdapter adapterInfo = findAnnotation(XmlJavaTypeAdapter.class, am, true, false, false); if (adapterInfo != null) { XmlAdapter adapter = checkAdapter(adapterInfo, type, forSerialization); if (adapter != null) { return adapter; } } XmlJavaTypeAdapters adapters = findAnnotation(XmlJavaTypeAdapters.class, am, true, false, false); if (adapters != null) { for (XmlJavaTypeAdapter info : adapters.value()) { XmlAdapter adapter = checkAdapter(info, type, forSerialization); if (adapter != null) { return adapter; } } } return null; } @SuppressWarnings("unchecked") private final XmlAdapter checkAdapter(XmlJavaTypeAdapter adapterInfo, Class typeNeeded, boolean forSerialization) { // if annotation has no type, it's applicable; if it has, must match Class adaptedType = adapterInfo.type(); if (adaptedType == XmlJavaTypeAdapter.DEFAULT.class) { JavaType type = _typeFactory.constructType(adapterInfo.value()); JavaType[] params = _typeFactory.findTypeParameters(type, XmlAdapter.class); adaptedType = params[1].getRawClass(); } if (adaptedType.isAssignableFrom(typeNeeded)) { @SuppressWarnings("rawtypes") Class cls = adapterInfo.value(); // true -> yes, force access if need be return ClassUtil.createInstance(cls, true); } return null; } @SuppressWarnings("unchecked") private XmlAdapter findAdapterForClass(AnnotatedClass ac, boolean forSerialization) { /* As per [JACKSON-411], XmlJavaTypeAdapter should not be inherited from super-class. * It would still be nice to be able to use mix-ins; but unfortunately we seem to lose * knowledge of class that actually declared the annotation. Thus, we'll only accept * declaration from specific class itself. */ XmlJavaTypeAdapter adapterInfo = ac.getAnnotated().getAnnotation(XmlJavaTypeAdapter.class); if (adapterInfo != null) { // should we try caching this? @SuppressWarnings("rawtypes") Class cls = adapterInfo.value(); // true -> yes, force access if need be return ClassUtil.createInstance(cls, true); } return null; } protected final TypeFactory getTypeFactory() { return _typeFactory; } /** * Helper method used to distinguish structured types (arrays, Lists, Maps), * which with JAXB use different rules for defining content types. */ private boolean isContainerType(Class raw) { return raw.isArray() || Collection.class.isAssignableFrom(raw) || Map.class.isAssignableFrom(raw); } private boolean adapterTypeMatches(XmlAdapter adapter, Class targetType) { return findAdapterBoundType(adapter).isAssignableFrom(targetType); } private Class findAdapterBoundType(XmlAdapter adapter) { TypeFactory tf = getTypeFactory(); JavaType adapterType = tf.constructType(adapter.getClass()); JavaType[] params = tf.findTypeParameters(adapterType, XmlAdapter.class); // should not happen, except if our type resolution has a flaw, but: if (params == null || params.length < 2) { return Object.class; } return params[1].getRawClass(); } protected XmlAdapter _findContentAdapter(Annotated ann, boolean forSerialization) { Class rawType = forSerialization ? _rawSerializationType(ann) : _rawDeserializationType(ann); // and let's assume this only applies as member annotation: if (isContainerType(rawType) && (ann instanceof AnnotatedMember)) { AnnotatedMember member = (AnnotatedMember) ann; JavaType fullType = forSerialization ? _fullSerializationType(member) : _fullDeserializationType(member); Class contentType = fullType.getContentType().getRawClass(); XmlAdapter adapter = findAdapter(member, forSerialization, contentType); if (adapter != null && adapterTypeMatches(adapter, contentType)) { return adapter; } } return null; } protected String _propertyNameToString(PropertyName n) { return (n == null) ? null : n.getSimpleName(); } protected Class _rawDeserializationType(Annotated a) { if (a instanceof AnnotatedMethod) { AnnotatedMethod am = (AnnotatedMethod) a; // 27-Nov-2012, tatu: Bit nasty, as we are assuming // things about method signatures here... but has to do if (am.getParameterCount() == 1) { return am.getRawParameterType(0); } } return a.getRawType(); } protected JavaType _fullDeserializationType(AnnotatedMember am) { if (am instanceof AnnotatedMethod) { AnnotatedMethod method = (AnnotatedMethod) am; // 27-Nov-2012, tatu: Bit nasty, as we are assuming // things about method signatures here... but has to do if (method.getParameterCount() == 1) { return ((AnnotatedMethod) am).getParameterType(0); } } return am.getType(); } protected Class _rawSerializationType(Annotated a) { // 27-Nov-2012, tatu: No work-arounds needed yet... return a.getRawType(); } protected JavaType _fullSerializationType(AnnotatedMember am) { return am.getType(); } protected Converter _converter(XmlAdapter adapter, boolean forSerialization) { TypeFactory tf = getTypeFactory(); JavaType adapterType = tf.constructType(adapter.getClass()); JavaType[] pt = tf.findTypeParameters(adapterType, XmlAdapter.class); // Order of type parameters for Converter is reverse between serializer, deserializer, // whereas JAXB just uses single ordering if (forSerialization) { return new AdapterConverter(adapter, pt[1], pt[0], forSerialization); } return new AdapterConverter(adapter, pt[0], pt[1], forSerialization); } protected Class _getTypeFromXmlElement(Annotated a) { XmlElement annotation = findAnnotation(XmlElement.class, a, false, false, false); if (annotation != null) { // Further, JAXB has peculiar notion of declaring intermediate (and, for the // most part, useless) type... So basically we betterjust ignore type if there // is adapter annotation (we could check to see if intermediate type is compatible, // but let's not yet bother) if (a.getAnnotation(XmlJavaTypeAdapter.class) != null) { return null; } Class type = annotation.type(); if (type != XmlElement.DEFAULT.class) { return type; } } return null; } } JaxbAnnotationModule.java000066400000000000000000000101251314745633000441160ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxbpackage com.fasterxml.jackson.module.jaxb; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.Module; /** * Module that can be registered to add support for JAXB annotations. * It does basically equivalent of *

 *   objectMapper.setAnnotationIntrospector(...);
 *
* with combination of {@link JaxbAnnotationIntrospector} and existing * default introspector(s) (if any), depending on configuration * (by default, JAXB annotations are used as {@link Priority#PRIMARY} * annotations). */ public class JaxbAnnotationModule extends Module { /** * Enumeration that defines how we use JAXB Annotations: either * as "primary" annotations (before any other already configured * introspector -- most likely default JacksonAnnotationIntrospector) or * as "secondary" annotations (after any other already configured * introspector(s)). *

* Default choice is PRIMARY *

* Note that if you want to use JAXB annotations as the only annotations, * you must directly set annotation introspector by calling * {@link com.fasterxml.jackson.databind.ObjectMapper#setAnnotationIntrospector}. */ public enum Priority { PRIMARY, SECONDARY; } /** * Priority to use when registering annotation introspector: default * value is {@link Priority#PRIMARY}. */ protected Priority _priority = Priority.PRIMARY; /** * If the introspector is explicitly set or passed, we'll hold on to that * until registration. * * @since 2.7 */ protected JaxbAnnotationIntrospector _introspector; /** * Value to pass to * {@link JaxbAnnotationIntrospector#setNonNillableInclusion} * if defined and non-null. * * @since 2.7 */ protected JsonInclude.Include _nonNillableInclusion; /* /********************************************************** /* Life cycle /********************************************************** */ public JaxbAnnotationModule() { } /** * @since 2.7 */ public JaxbAnnotationModule(JaxbAnnotationIntrospector intr) { _introspector = intr; } @Override public String getModuleName() { return getClass().getSimpleName(); } @Override public Version version() { return PackageVersion.VERSION; } @Override public void setupModule(SetupContext context) { JaxbAnnotationIntrospector intr = _introspector; if (intr == null) { intr = new JaxbAnnotationIntrospector(context.getTypeFactory()); if (_nonNillableInclusion != null) { intr.setNonNillableInclusion(_nonNillableInclusion); } } switch (_priority) { case PRIMARY: context.insertAnnotationIntrospector(intr); break; case SECONDARY: context.appendAnnotationIntrospector(intr); break; } } /* /********************************************************** /* Configuration /********************************************************** */ /** * Method for defining whether JAXB annotations should be added * as primary or secondary annotations (compared to already registered * annotations). *

* NOTE: method MUST be called before registering the module -- calling * afterwards will not have any effect on previous registrations. */ public JaxbAnnotationModule setPriority(Priority p) { _priority = p; return this; } public Priority getPriority() { return _priority; } /** * @since 2.7 */ public JaxbAnnotationModule setNonNillableInclusion(JsonInclude.Include incl) { _nonNillableInclusion = incl; if (_introspector != null) { _introspector.setNonNillableInclusion(incl); } return this; } /** * @since 2.7 */ public JsonInclude.Include getNonNillableInclusion() { return _nonNillableInclusion; } } PackageVersion.java.in000066400000000000000000000011071314745633000433370ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxbpackage @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; } } deser/000077500000000000000000000000001314745633000402715ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxbDataHandlerJsonDeserializer.java000066400000000000000000000030351314745633000465010ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxb/deserpackage com.fasterxml.jackson.module.jaxb.deser; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayInputStream; import javax.activation.DataHandler; import javax.activation.DataSource; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer; /** * @author Ryan Heaton */ public class DataHandlerJsonDeserializer extends StdScalarDeserializer { private static final long serialVersionUID = 1L; public DataHandlerJsonDeserializer() { super(DataHandler.class); } @Override public DataHandler deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { final byte[] value = jp.getBinaryValue(); return new DataHandler(new DataSource() { @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(value); } @Override public OutputStream getOutputStream() throws IOException { throw new IOException(); } @Override public String getContentType() { return "application/octet-stream"; } @Override public String getName() { return "json-binary-data"; } }); } } DomElementJsonDeserializer.java000066400000000000000000000067461314745633000463770ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxb/deserpackage com.fasterxml.jackson.module.jaxb.deser; import java.io.IOException; import java.util.Iterator; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.node.ArrayNode; /** * @author Ryan Heaton */ public class DomElementJsonDeserializer extends StdDeserializer { private static final long serialVersionUID = 1L; private final DocumentBuilder builder; public DomElementJsonDeserializer() { super(Element.class); try { DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance(); bf.setNamespaceAware(true); builder = bf.newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new RuntimeException(); } } public DomElementJsonDeserializer(DocumentBuilder builder) { super(Element.class); this.builder = builder; } @Override public Element deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { Document document = builder.newDocument(); JsonNode n = p.readValueAsTree(); return fromNode(p, document, n); } protected Element fromNode(JsonParser p, Document document, JsonNode jsonNode) throws IOException { String ns = jsonNode.get("namespace") != null ? jsonNode.get("namespace").asText() : null; String name = jsonNode.get("name") != null ? jsonNode.get("name").asText() : null; if (name == null) { throw JsonMappingException.from(p, "No name for DOM element was provided in the JSON object."); } Element element = document.createElementNS(ns, name); JsonNode attributesNode = jsonNode.get("attributes"); if (attributesNode != null && attributesNode instanceof ArrayNode) { Iterator atts = attributesNode.elements(); while (atts.hasNext()) { JsonNode node = atts.next(); ns = node.get("namespace") != null ? node.get("namespace").asText() : null; name = node.get("name") != null ? node.get("name").asText() : null; String value = node.get("$") != null ? node.get("$").asText() : null; if (name != null) { element.setAttributeNS(ns, name, value); } } } JsonNode childsNode = jsonNode.get("children"); if (childsNode != null && childsNode instanceof ArrayNode) { Iterator els = childsNode.elements(); while (els.hasNext()) { JsonNode node = els.next(); name = node.get("name") != null ? node.get("name").asText() : null; String value = node.get("$") != null ? node.get("$").asText() : null; if (value != null) { element.appendChild(document.createTextNode(value)); } else if (name != null) { element.appendChild(fromNode(p, document, node)); } } } return element; } } package-info.java000066400000000000000000000005671314745633000423660ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxb/** * Package that contains support for using JAXB annotations for * configuring Jackson data-binding aspects. *

* Usage is by registering {@link com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule}: *

 *  ObjectMapper mapper = new ObjectMapper();
 *  mapper.registerModule(new JaxbAnnotationModule());
 *
*/ package com.fasterxml.jackson.module.jaxb; ser/000077500000000000000000000000001314745633000377605ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxbDataHandlerJsonSerializer.java000066400000000000000000000050761314745633000456660ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxb/serpackage com.fasterxml.jackson.module.jaxb.ser; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; import javax.activation.DataHandler; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.node.ObjectNode; public class DataHandlerJsonSerializer extends StdSerializer { private static final long serialVersionUID = 1L; public DataHandlerJsonSerializer() { super(DataHandler.class); } @Override public void serialize(DataHandler value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { final ByteArrayOutputStream out = new ByteArrayOutputStream(); /* for copy-through, a small buffer should suffice: ideally * we might want to reuse a generic byte buffer, but for now * there's no serializer context to hold them. * * Also: it'd be nice not to have buffer all data, but use a * streaming output. But currently JsonGenerator won't allow * that. */ byte[] buffer = new byte[1024 * 4]; InputStream in = value.getInputStream(); int len = in.read(buffer); while (len > 0) { out.write(buffer, 0, len); len = in.read(buffer); } in.close(); jgen.writeBinary(out.toByteArray()); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor != null) { JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint); if (v2 != null) { v2.itemsFormat(JsonFormatTypes.STRING); } } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("array", true); ObjectNode itemSchema = createSchemaNode("string"); //binary values written as strings? o.set("items", itemSchema); return o; } } DomElementJsonSerializer.java000066400000000000000000000063111314745633000455410ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/java/com/fasterxml/jackson/module/jaxb/serpackage com.fasterxml.jackson.module.jaxb.ser; import java.io.IOException; import java.lang.reflect.Type; import org.w3c.dom.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; public class DomElementJsonSerializer extends StdSerializer { private static final long serialVersionUID = 1L; public DomElementJsonSerializer() { super(Element.class); } @Override public void serialize(Element value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeStartObject(); jgen.writeStringField("name", value.getTagName()); if (value.getNamespaceURI() != null) { jgen.writeStringField("namespace", value.getNamespaceURI()); } NamedNodeMap attributes = value.getAttributes(); if (attributes != null && attributes.getLength() > 0) { jgen.writeArrayFieldStart("attributes"); for (int i = 0; i < attributes.getLength(); i++) { Attr attribute = (Attr) attributes.item(i); jgen.writeStartObject(); jgen.writeStringField("$", attribute.getValue()); jgen.writeStringField("name", attribute.getName()); String ns = attribute.getNamespaceURI(); if (ns != null) { jgen.writeStringField("namespace", ns); } jgen.writeEndObject(); } jgen.writeEndArray(); } NodeList children = value.getChildNodes(); if (children != null && children.getLength() > 0) { jgen.writeArrayFieldStart("children"); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); switch (child.getNodeType()) { case Node.CDATA_SECTION_NODE: case Node.TEXT_NODE: jgen.writeStartObject(); jgen.writeStringField("$", child.getNodeValue()); jgen.writeEndObject(); break; case Node.ELEMENT_NODE: serialize((Element) child, jgen, provider); break; } } jgen.writeEndArray(); } jgen.writeEndObject(); } // Improved in 2.3; was missing from 2.2 @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor != null) { visitor.expectStringFormat(typeHint); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { // Since 2.3: should be more like String type really, not structure return createSchemaNode("string", true); } } jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/resources/000077500000000000000000000000001314745633000317135ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/resources/META-INF/000077500000000000000000000000001314745633000330535ustar00rootroot00000000000000LICENSE000066400000000000000000000005011314745633000337750ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/resources/META-INFThis copy of Jackson JSON processor databind module is licensed under the Apache (Software) License, version 2.0 ("the License"). See the License for details about distribution rights, and the specific rights regarding derivate works. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 NOTICE000066400000000000000000000014711314745633000337030ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/resources/META-INF# Jackson JSON processor Jackson is a high-performance, Free/Open Source JSON processing library. It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has been in development since 2007. It is currently developed by a community of developers, as well as supported commercially by FasterXML.com. ## Licensing Jackson core and extension components may be licensed under different licenses. To find the details that apply to this artifact see the accompanying LICENSE file. For more information, including possible other licensing options, contact FasterXML.com (http://fasterxml.com). ## Credits A list of contributors may be found from CREDITS file, which is included in some artifacts (usually source distributions); but is always available from the source code management (SCM) system project uses. services/000077500000000000000000000000001314745633000346175ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/resources/META-INFcom.fasterxml.jackson.databind.Module000066400000000000000000000000671314745633000437470ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/main/resources/META-INF/servicescom.fasterxml.jackson.module.jaxb.JaxbAnnotationModule jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/000077500000000000000000000000001314745633000277345ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/000077500000000000000000000000001314745633000306555ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/000077500000000000000000000000001314745633000314335ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/000077500000000000000000000000001314745633000334405ustar00rootroot00000000000000jackson/000077500000000000000000000000001314745633000350115ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxmlmodule/000077500000000000000000000000001314745633000362765ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jacksonjaxb/000077500000000000000000000000001314745633000372225ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/moduleBaseJaxbTest.java000066400000000000000000000050441314745633000424070ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbpackage com.fasterxml.jackson.module.jaxb; import java.io.IOException; import java.util.Map; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; public abstract class BaseJaxbTest extends junit.framework.TestCase { protected BaseJaxbTest() { } /* /********************************************************************** /* Factory methods /********************************************************************** */ protected ObjectMapper getJaxbMapper() { ObjectMapper mapper = new ObjectMapper(); AnnotationIntrospector intr = new JaxbAnnotationIntrospector(mapper.getTypeFactory()); mapper.setAnnotationIntrospector(intr); return mapper; } protected ObjectMapper getJaxbAndJacksonMapper() { ObjectMapper mapper = new ObjectMapper(); AnnotationIntrospector intr = new AnnotationIntrospectorPair(new JaxbAnnotationIntrospector( mapper.getTypeFactory()), new JacksonAnnotationIntrospector()); mapper.setAnnotationIntrospector(intr); return mapper; } protected ObjectMapper getJacksonAndJaxbMapper() { ObjectMapper mapper = new ObjectMapper(); AnnotationIntrospector intr = new AnnotationIntrospectorPair(new JacksonAnnotationIntrospector(), new JaxbAnnotationIntrospector(mapper.getTypeFactory()) ); mapper.setAnnotationIntrospector(intr); return mapper; } /* /********************************************************************** /* Helper methods /********************************************************************** */ @SuppressWarnings("unchecked") protected Map writeAndMap(ObjectMapper m, Object value) throws IOException { String str = m.writeValueAsString(value); return (Map) m.readValue(str, Map.class); } protected Map writeAndMap(Object value) throws IOException { return writeAndMap(new ObjectMapper(), value); } protected String serializeAsString(ObjectMapper m, Object value) throws IOException { return m.writeValueAsString(value); } protected String serializeAsString(Object value) throws IOException { return serializeAsString(new ObjectMapper(), value); } } TestVersions.java000066400000000000000000000016451314745633000425430ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbpackage com.fasterxml.jackson.module.jaxb; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.core.Versioned; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; public class TestVersions extends BaseJaxbTest { public void testVersions() { assertVersion(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance())); } /* /********************************************************** /* Helper methods /********************************************************** */ private void assertVersion(Versioned vers) { Version v = vers.version(); assertFalse("Should find version information (got "+v+")", v.isUnknownVersion()); Version exp = PackageVersion.VERSION; assertEquals(exp.toFullString(), v.toFullString()); assertEquals(exp, v); } } adapters/000077500000000000000000000000001314745633000410255ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbEntryType.java000066400000000000000000000007341314745633000436370ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/adapterspackage com.fasterxml.jackson.module.jaxb.adapters; /** * @author Ryan Heaton */ public class EntryType { private K key; private V value; public EntryType() { } public EntryType(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public void setKey(K key) { this.key = key; } public V getValue() { return value; } public void setValue(V value) { this.value = value; } } MapAdapter.java000066400000000000000000000016311314745633000437070ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/adapterspackage com.fasterxml.jackson.module.jaxb.adapters; import javax.xml.bind.annotation.adapters.XmlAdapter; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public class MapAdapter extends XmlAdapter, Map> { @Override public MapType marshal(Map v) throws Exception { final List> theEntries = new LinkedList>(); for (final Map.Entry anEntry : v.entrySet()) { theEntries.add(new EntryType(anEntry.getKey(), anEntry.getValue())); } return new MapType(theEntries); } @Override public Map unmarshal(MapType v) throws Exception { final Map theMap = new HashMap(); for (final EntryType anEntry : v.getEntries()) { theMap.put(anEntry.getKey(), anEntry.getValue()); } return theMap; } }MapType.java000066400000000000000000000010061314745633000432440ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/adapterspackage com.fasterxml.jackson.module.jaxb.adapters; import com.fasterxml.jackson.module.jaxb.adapters.EntryType; import java.util.List; /** * @author Ryan Heaton */ public class MapType { public List> entries; public MapType() { } public MapType(List> theEntries) { this.entries = theEntries; } public List> getEntries() { return entries; } public void setEntries(List> entries) { this.entries = entries; } } TestAdaptedMapType.java000066400000000000000000000060711314745633000453760ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/adapterspackage com.fasterxml.jackson.module.jaxb.adapters; import java.io.*; import java.util.*; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Tests for verifying JAXB adapter handling for {@link java.util.Map} * types. */ public class TestAdaptedMapType extends BaseJaxbTest { static class ObjectContainingAMap { private Map myMap; @XmlJavaTypeAdapter(MapAdapter.class) public Map getMyMap() { return myMap; } public void setMyMap(Map myMap) { this.myMap = myMap; } } static class StringMapWrapper { @XmlJavaTypeAdapter(StringMapAdapter.class) public Map values = new LinkedHashMap(); } static class StringMapAdapter extends XmlAdapter, Map> { @Override public Map marshal(Map input) { LinkedHashMap result = new LinkedHashMap(); for (Map.Entry entry : input.entrySet()) { result.put(entry.getKey(), "M-"+entry.getValue()); } return result; } @Override public Map unmarshal(Map input) { LinkedHashMap result = new LinkedHashMap(); for (Map.Entry entry : input.entrySet()) { result.put(entry.getKey(), "U-"+entry.getValue()); } return result; } } /* /********************************************************** /* Tests /********************************************************** */ public void testJacksonAdaptedMapType() throws IOException { ObjectContainingAMap obj = new ObjectContainingAMap(); obj.setMyMap(new LinkedHashMap()); obj.getMyMap().put("this", "that"); obj.getMyMap().put("how", "here"); ObjectMapper mapper = getJaxbMapper(); // Ok, first serialize: String json = mapper.writeValueAsString(obj); obj = mapper.readValue(json, ObjectContainingAMap.class); Map map = obj.getMyMap(); assertNotNull(map); assertEquals(2, map.size()); assertEquals("here", map.get("how")); } public void testStringMaps() throws IOException { ObjectMapper mapper = getJaxbMapper(); StringMapWrapper map = mapper.readValue("{\"values\":{\"a\":\"b\"}}", StringMapWrapper.class); assertNotNull(map.values); assertEquals(1, map.values.size()); assertEquals("U-b", map.values.get("a")); // and then out again String json = mapper.writeValueAsString(map); assertEquals("{\"values\":{\"a\":\"M-U-b\"}}", json); } } TestAdapters.java000066400000000000000000000126401314745633000442760ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/adapterspackage com.fasterxml.jackson.module.jaxb.adapters; import java.util.*; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Unit tests for checking that JAXB type adapters work (to some * degree, anyway). * Related to issues [JACKSON-288], [JACKSON-411] * * @author tatu */ public class TestAdapters extends BaseJaxbTest { public static class SillyAdapter extends XmlAdapter { public SillyAdapter() { } @Override public Date unmarshal(String date) throws Exception { return new Date(29L); } @Override public String marshal(Date date) throws Exception { return "XXX"; } } static class Bean { @XmlJavaTypeAdapter(SillyAdapter.class) public Date value; public Bean() { } public Bean(long l) { value = new Date(l); } } // For [JACKSON-288] static class Bean288 { public List persons; public Bean288() { } public Bean288(String str) { persons = new ArrayList(); persons.add(new Person(str)); } } static class Person { public String name; @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(DateAdapter.class) protected Calendar date; public Person() { } public Person(String n) { name = n; date = Calendar.getInstance(); date.setTime(new Date(0L)); } } public static class DateAdapter extends XmlAdapter { public DateAdapter() { } @Override public Calendar unmarshal(String value) { return (javax.xml.bind.DatatypeConverter.parseDateTime(value)); } @Override public String marshal(Calendar value) { if (value == null) { return null; } return (javax.xml.bind.DatatypeConverter.printDateTime(value)); } } // [JACKSON-656] @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "Paging", propOrder = { "numFound" }) public static class Bean656 { @XmlElement(type = String.class) @XmlJavaTypeAdapter(Adapter1.class) @XmlSchemaType(name = "long") protected Long numFound; public Long getNumFound() { return numFound; } public void setNumFound(Long value) { this.numFound = value; } } public static class Adapter1 extends XmlAdapter { @Override public Long unmarshal(String value) { return ((long) javax.xml.bind.DatatypeConverter.parseLong(value)); } @Override public String marshal(Long value) { if (value == null) { return null; } return (javax.xml.bind.DatatypeConverter.printLong((long) (long) value)); } } // [Issue-10]: Infinite recursion in "self" adapters public static class IdentityAdapter extends XmlAdapter { @Override public IdentityAdapterBean unmarshal(IdentityAdapterBean b) { b.value += "U"; return b; } @Override public IdentityAdapterBean marshal(IdentityAdapterBean b) { if (b != null) { b.value += "M"; } return b; } } @XmlJavaTypeAdapter(IdentityAdapter.class) static class IdentityAdapterBean { public String value; public IdentityAdapterBean() { } public IdentityAdapterBean(String s) { value = s; } } static class IdentityAdapterPropertyBean { @XmlJavaTypeAdapter(IdentityAdapter.class) public String value; public IdentityAdapterPropertyBean() { } public IdentityAdapterPropertyBean(String s) { value = s; } } /* /********************************************************** /* Unit tests /********************************************************** */ public void testSimpleAdapterSerialization() throws Exception { Bean bean = new Bean(123L); assertEquals("{\"value\":\"XXX\"}", getJaxbMapper().writeValueAsString(bean)); } public void testSimpleAdapterDeserialization() throws Exception { Bean bean = getJaxbMapper().readValue("{\"value\":\"abc\"}", Bean.class); assertNotNull(bean.value); assertEquals(29L, bean.value.getTime()); } // [JACKSON-288] public void testDateAdapter() throws Exception { Bean288 input = new Bean288("test"); ObjectMapper mapper = getJaxbMapper(); String json = mapper.writeValueAsString(input); Bean288 output = mapper.readValue(json, Bean288.class); assertNotNull(output); } // [JACKSON-656] public void testJackson656() throws Exception { Bean656 bean = new Bean656(); bean.setNumFound(3232l); ObjectMapper mapper = getJaxbMapper(); String json = mapper.writeValueAsString(bean); assertEquals("{\"numFound\":\"3232\"}", json); } } TestAdaptersForContainers.java000066400000000000000000000127331314745633000467760ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/adapterspackage com.fasterxml.jackson.module.jaxb.adapters; import java.util.*; import java.util.Map.Entry; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.introspect.TestJaxbAnnotationIntrospector.KeyValuePair; /** * Unit tests to check that {@link XmlAdapter}s also work with * container types (Lists, Maps) */ public class TestAdaptersForContainers extends BaseJaxbTest { // Support for Maps @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public static class ParentJAXBBean { @XmlJavaTypeAdapter(JAXBMapAdapter.class) private Map params = new HashMap(); public Map getParams() { return params; } public void setParams(Map params) { this.params = params; } } public static class JAXBMapAdapter extends XmlAdapter,Map> { @Override public List marshal(Map arg0) throws Exception { List keyValueList = new ArrayList(); for(Entry entry : arg0.entrySet()) { KeyValuePair keyValuePair = new KeyValuePair(); keyValuePair.setKey(entry.getKey()); keyValuePair.setValue(entry.getValue()); keyValueList.add(keyValuePair); } return keyValueList; } @Override public Map unmarshal(List arg0) throws Exception { HashMap hashMap = new HashMap(); for (int i = 0; i < arg0.size(); i++) { hashMap.put(arg0.get(i).getKey(), arg0.get(i).getValue()); } return hashMap; } } // [JACKSON-722] public static class SillyAdapter extends XmlAdapter { public SillyAdapter() { } @Override public Date unmarshal(String date) throws Exception { return new Date(29L); } @Override public String marshal(Date date) throws Exception { return "XXX"; } } static class Wrapper { @XmlJavaTypeAdapter(SillyAdapter.class) public List values; public Wrapper() { } public Wrapper(long l) { values = new ArrayList(); values.add(new Date(l)); } } static class WrapperWithGetterAndSetter { private List values; public WrapperWithGetterAndSetter() { } public WrapperWithGetterAndSetter(long l) { values = new ArrayList(); values.add(new Date(l)); } @XmlJavaTypeAdapter(SillyAdapter.class) public List getValues() { return values; } public void setValues(List values) { this.values = values; } } /* /********************************************************** /* Unit tests, Lists /********************************************************** */ public void testAdapterForList() throws Exception { Wrapper w = new Wrapper(123L); assertEquals("{\"values\":[\"XXX\"]}", getJaxbMapper().writeValueAsString(w)); } public void testSimpleAdapterDeserialization() throws Exception { Wrapper w = getJaxbMapper().readValue("{\"values\":[\"abc\"]}", Wrapper.class); assertNotNull(w); assertNotNull(w.values); assertEquals(1, w.values.size()); assertEquals(29L, w.values.get(0).getTime()); } public void testAdapterOnGetterSerialization() throws Exception { WrapperWithGetterAndSetter w = new WrapperWithGetterAndSetter(123L); assertEquals("{\"values\":[\"XXX\"]}", getJaxbMapper().writeValueAsString(w)); } public void testAdapterOnGetterDeserialization() throws Exception { WrapperWithGetterAndSetter w = getJaxbMapper().readValue("{\"values\":[\"abc\"]}", WrapperWithGetterAndSetter.class); assertNotNull(w); assertNotNull(w.values); assertEquals(1, w.values.size()); assertEquals(29L, w.values.get(0).getTime()); } /* /********************************************************** /* Unit tests, Map-related /********************************************************** */ public void testAdapterForBeanWithMap() throws Exception { ObjectMapper mapper = getJaxbMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); ParentJAXBBean parentJaxbBean = new ParentJAXBBean(); HashMap params = new HashMap(); params.put("sampleKey", "sampleValue"); parentJaxbBean.setParams(params); String json = mapper.writeValueAsString(parentJaxbBean); // uncomment to see what the json looks like. //System.out.println(json); //now make sure it gets deserialized correctly. ParentJAXBBean readEx = mapper.readValue(json, ParentJAXBBean.class); assertEquals("sampleValue", readEx.getParams().get("sampleKey")); } } TestIdentityAdapters.java000066400000000000000000000053311314745633000460070ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/adapterspackage com.fasterxml.jackson.module.jaxb.adapters; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Failing unit tests related to Adapter handling. */ public class TestIdentityAdapters extends BaseJaxbTest { // [Issue-10]: Infinite recursion in "self" adapters public static class IdentityAdapter extends XmlAdapter { @Override public IdentityAdapterBean unmarshal(IdentityAdapterBean b) { return new IdentityAdapterBean(b.value + "U"); } @Override public IdentityAdapterBean marshal(IdentityAdapterBean b) { return new IdentityAdapterBean(b.value + "M"); } } public static class IdentityStringAdapter extends XmlAdapter { @Override public String unmarshal(String b) { return b + "U"; } @Override public String marshal(String b) { return b + "M"; } } @XmlJavaTypeAdapter(IdentityAdapter.class) static class IdentityAdapterBean { public String value; protected IdentityAdapterBean() { } public IdentityAdapterBean(String s) { value = s; } } static class IdentityAdapterPropertyBean { @XmlJavaTypeAdapter(IdentityStringAdapter.class) public String value; public IdentityAdapterPropertyBean() { } public IdentityAdapterPropertyBean(String s) { value = s; } } /* /********************************************************** /* Unit tests /********************************************************** */ // [Issue-10] public void testIdentityAdapterForClass() throws Exception { IdentityAdapterBean input = new IdentityAdapterBean("A"); ObjectMapper mapper = getJaxbMapper(); String json = mapper.writeValueAsString(input); assertEquals("{\"value\":\"AM\"}", json); IdentityAdapterBean result = mapper.readValue(json, IdentityAdapterBean.class); assertEquals("AMU", result.value); } // [Issue-10] public void testIdentityAdapterForProperty() throws Exception { IdentityAdapterPropertyBean input = new IdentityAdapterPropertyBean("B"); ObjectMapper mapper = getJaxbMapper(); String json = mapper.writeValueAsString(input); assertEquals("{\"value\":\"BM\"}", json); IdentityAdapterPropertyBean result = mapper.readValue(json, IdentityAdapterPropertyBean.class); assertEquals("BMU", result.value); } } failing/000077500000000000000000000000001314745633000406335ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbTestUnwrapping.java000066400000000000000000000041001314745633000444630ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/failingpackage com.fasterxml.jackson.module.jaxb.failing; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; public class TestUnwrapping extends BaseJaxbTest { @XmlRootElement static class Bean { @JsonUnwrapped @XmlAnyElement(lax = true) @XmlElementRefs( { @XmlElementRef(name = "a", type = A.class), @XmlElementRef(name = "b", type = B.class) }) public R r; public String name; public Bean() { } } static class A { public int count; public A() { } public A(int count) { this.count = count; } } static class B { public String type; public B() { } public B(String type) { this.type = type; } } /* /********************************************************** /* Unit tests /********************************************************** */ // not asserting anything public void testXmlElementAndXmlElementRefs() throws Exception { Bean
bean = new Bean(); bean.r = new A(12); bean.name = "test"; ObjectMapper mapper = new ObjectMapper(); AnnotationIntrospector pair = new AnnotationIntrospectorPair( new JacksonAnnotationIntrospector(), new JaxbAnnotationIntrospector(mapper.getTypeFactory()) ); mapper.setAnnotationIntrospector(pair); // mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector()); // mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector()); String json = mapper.writeValueAsString(bean); // !!! TODO: verify assertNotNull(json); } } id/000077500000000000000000000000001314745633000376165ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbTestXmlID.java000066400000000000000000000067021314745633000423030ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/idpackage com.fasterxml.jackson.module.jaxb.id; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Simple testing to verify that XmlID and XMLIDREF handling works * to degree we can make it work. */ public class TestXmlID extends BaseJaxbTest { // From sample used in [http://blog.bdoughan.com/2010/10/jaxb-and-shared-references-xmlid-and.html] @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) static class Company { @XmlElement(name="employee") protected List employees; public Company() { employees = new ArrayList(); } } @XmlAccessorType(XmlAccessType.FIELD) static class Employee { @XmlAttribute @XmlID protected String id; @XmlAttribute protected String name; @XmlIDREF protected Employee manager; @XmlElement(name="report") @XmlIDREF protected List reports; public Employee() { reports = new ArrayList(); } } /* /********************************************************** /* Test methods /********************************************************** */ public void testSimpleRefs() throws Exception { final ObjectMapper mapper = getJaxbMapper(); Company company = new Company(); Employee employee1 = new Employee(); employee1.id = "1"; employee1.name = "Jane Doe"; company.employees.add(employee1); Employee employee2 = new Employee(); employee2.id = "2"; employee2.name = "John Smith"; employee2.manager = employee1; employee1.reports.add(employee2); company.employees.add(employee2); Employee employee3 = new Employee(); employee3.id = "3"; employee3.name = "Anne Jones"; employee3.manager = employee1; employee1.reports.add(employee3); company.employees.add(employee3); String json = mapper.writeValueAsString(company); // this is the easy part actually... assertNotNull(json); // then try bringing back Company result = mapper.readValue(json, Company.class); assertNotNull(result); assertEquals(3, company.employees.size()); assertEquals("Jane Doe", company.employees.get(0).name); assertEquals("1", company.employees.get(0).id); assertEquals("John Smith", company.employees.get(1).name); assertEquals("2", company.employees.get(1).id); assertEquals("Anne Jones", company.employees.get(2).name); assertEquals("3", company.employees.get(2).id); // then actual references: final Employee resEmpl1 = company.employees.get(0); final Employee resEmpl2 = company.employees.get(1); final Employee resEmpl3 = company.employees.get(2); assertEquals(2, resEmpl1.reports.size()); // Jane has John and Anne as reports: assertSame(resEmpl2, resEmpl1.reports.get(0)); assertSame(resEmpl3, resEmpl1.reports.get(1)); assertEquals(0, resEmpl2.reports.size()); assertEquals(0, resEmpl3.reports.size()); // and they have her as manager assertSame(resEmpl1, resEmpl2.manager); assertSame(resEmpl1, resEmpl3.manager); } } TestXmlID2.java000066400000000000000000000112361314745633000423630ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/idpackage com.fasterxml.jackson.module.jaxb.id; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; // Reproduction of [Issue-9] public class TestXmlID2 extends BaseJaxbTest { @XmlRootElement(name = "department") @XmlAccessorType(XmlAccessType.FIELD) static class Department { @XmlElement @XmlID public Long id; public String name; @XmlIDREF public List employees = new ArrayList(); protected Department() { } public Department(Long id) { this.id = id; } public void setId(Long id) { this.id = id; } public void setName(String name) { this.name = name; } public void setEmployees(List employees) { this.employees = employees; } } @XmlRootElement(name = "user") @XmlAccessorType(XmlAccessType.FIELD) static class User { @XmlElement @XmlID public Long id; public String username; public String email; @XmlIDREF public Department department; protected User() { } public User(Long id) { this.id = id; } public void setId(Long id) { this.id = id; } public void setUsername(String username) { this.username = username; } public void setEmail(String email) { this.email = email; } public void setDepartment(Department department) { this.department = department; } } private List getUserList() { List resultList = new ArrayList(); List users = new java.util.ArrayList(); User user1, user2, user3; Department dep; user1 = new User(11L); user1.setUsername("11"); user1.setEmail("11@test.com"); user2 = new User(22L); user2.setUsername("22"); user2.setEmail("22@test.com"); user3 = new User(33L); user3.setUsername("33"); user3.setEmail("33@test.com"); dep = new Department(9L); dep.setName("department9"); user1.setDepartment(dep); users.add(user1); user2.setDepartment(dep); users.add(user2); dep.setEmployees(users); resultList.clear(); resultList.add(user1); resultList.add(user2); resultList.add(user3); return resultList; } public void testIdWithJacksonRules() throws Exception { String expected = "[{\"id\":11,\"username\":\"11\",\"email\":\"11@test.com\"," +"\"department\":{\"id\":9,\"name\":\"department9\",\"employees\":[" +"11,{\"id\":22,\"username\":\"22\",\"email\":\"22@test.com\"," +"\"department\":9}]}},22,{\"id\":33,\"username\":\"33\",\"email\":\"33@test.com\",\"department\":null}]"; ObjectMapper mapper = new ObjectMapper(); // true -> ignore XmlIDREF annotation mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(mapper.getTypeFactory(), true)); // first, with default settings (first NOT as id) List users = getUserList(); String json = mapper.writeValueAsString(users); assertEquals(expected, json); List result = mapper.readValue(json, new TypeReference>() { }); assertEquals(3, result.size()); assertEquals(Long.valueOf(11), result.get(0).id); assertEquals(Long.valueOf(22), result.get(1).id); assertEquals(Long.valueOf(33), result.get(2).id); } public void testIdWithJaxbRules() throws Exception { ObjectMapper mapper = new ObjectMapper(); // but then also variant where ID is ALWAYS used for XmlID / XmlIDREF mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(mapper.getTypeFactory())); List users = getUserList(); final String json = mapper.writeValueAsString(users); String expected = "[{\"id\":11,\"username\":\"11\",\"email\":\"11@test.com\",\"department\":9}" +",{\"id\":22,\"username\":\"22\",\"email\":\"22@test.com\",\"department\":9}" +",{\"id\":33,\"username\":\"33\",\"email\":\"33@test.com\",\"department\":null}]"; assertEquals(expected, json); // However, there is no way to resolve those back, without some external mechanism... } } introspect/000077500000000000000000000000001314745633000414145ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbContent.java000066400000000000000000000117121314745633000436730ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ws.rs.core.MediaType; import javax.xml.bind.annotation.*; import org.w3c.dom.Element; /** *

Represents an atom:content element.

*

*

Per RFC4287:

*

*

 *  The "atom:content" element either contains or links to the content of
 *  the entry.  The content of atom:content is Language-Sensitive.
 * 

* atomInlineTextContent = * element atom:content { * atomCommonAttributes, * attribute type { "text" | "html" }?, * (text)* * } *

* atomInlineXHTMLContent = * element atom:content { * atomCommonAttributes, * attribute type { "xhtml" }, * xhtmlDiv * } * atomInlineOtherContent = * element atom:content { * atomCommonAttributes, * attribute type { atomMediaType }?, * (text|anyElement)* * } *

* atomOutOfLineContent = * element atom:content { * atomCommonAttributes, * attribute type { atomMediaType }?, * attribute src { atomUri }, * empty * } *

* atomContent = atomInlineTextContent * | atomInlineXHTMLContent * | atomInlineOtherContent * | atomOutOfLineContent *

*

* * @author
Bill Burke * @version $Revision: 1666 $ */ @XmlRootElement(name = "content") @XmlAccessorType(XmlAccessType.PROPERTY) class Content extends CommonAttributes { private String type; private MediaType mediaType; private String text; private Element element; private URI src; private List value; protected Object jaxbObject; @XmlAnyElement @XmlMixed public List getValue() { return value; } public void setValue(List value) { this.value = value; } @XmlAttribute public URI getSrc() { return src; } public void setSrc(URI src) { this.src = src; } /** * Mime type of the content */ @XmlTransient public MediaType getType() { if (mediaType == null) { if (type.equals("html")) mediaType = MediaType.TEXT_HTML_TYPE; else if (type.equals("text")) mediaType = MediaType.TEXT_PLAIN_TYPE; else if (type.equals("xhtml")) mediaType = MediaType.APPLICATION_XHTML_XML_TYPE; else mediaType = MediaType.valueOf(type); } return mediaType; } public void setType(MediaType type) { mediaType = type; if (type.equals(MediaType.TEXT_PLAIN_TYPE)) this.type = "text"; else if (type.equals(MediaType.TEXT_HTML_TYPE)) this.type = "html"; else if (type.equals(MediaType.APPLICATION_XHTML_XML_TYPE)) this.type = "xhtml"; else this.type = type.toString(); } @XmlAttribute(name = "type") public String getRawType() { return type; } public void setRawType(String type) { this.type = type; } @XmlTransient public String getText() { if (value == null) return null; if (value.size() == 0) return null; if (text != null) return text; StringBuffer buf = new StringBuffer(); for (Object obj : value) { if (obj instanceof String) buf.append(obj.toString()); } text = buf.toString(); return text; } public void setText(String text) { if (value == null) value = new ArrayList(); if (this.text != null && value != null) value.clear(); this.text = text; value.add(text); } /** * Get content as an XML Element if the content is XML. Otherwise, this will just return null. */ @XmlTransient public Element getElement() { if (value == null) return null; if (element != null) return element; for (Object obj : value) { if (obj instanceof Element) { element = (Element) obj; return element; } } return null; } /** * Set the content to an XML Element * * @param element */ public void setElement(Element element) { if (value == null) value = new ArrayList(); if (this.element != null && value != null) value.clear(); this.element = element; value.add(element); } } @XmlAccessorType(XmlAccessType.PROPERTY) class CommonAttributes { private String language; private URI base; private Map extensionAttributes = new HashMap(); @XmlAttribute(name = "lang", namespace = "http://www.w3.org/XML/1998/namespace") public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } @XmlAttribute(namespace = "http://www.w3.org/XML/1998/namespace") public URI getBase() { return base; } public void setBase(URI base) { this.base = base; } @XmlAnyAttribute public Map getExtensionAttributes() { return extensionAttributes; } } TestAccessType.java000066400000000000000000000070731314745633000451710ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.util.*; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Unit test(s) written for [JACKSON-303]; we should be able to detect setter * even though it is not annotated, because there is matching annotated getter. */ public class TestAccessType extends BaseJaxbTest { @XmlRootElement(name = "model") @XmlAccessorType(XmlAccessType.NONE) public static class SimpleNamed { protected String name; @XmlElement public String getName() { return name; } public void setName(String name) { this.name = name; } } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "LoggedActivity") public static class Bean288 { @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(MyAdapter.class) @XmlSchemaType(name = "date") public Date date; } public static class MyAdapter extends XmlAdapter { @Override public String marshal(Date arg) throws Exception { return "String="+arg.getTime(); } @Override public Date unmarshal(String arg0) throws Exception { return new Date(Long.parseLong(arg0)); } } // [jaxb-annotations#40]: Need to recognize more marker annotations @XmlAccessorType(XmlAccessType.NONE) public class Bean40 { @XmlElement public int getA() { return 1; } @XmlElementWrapper(name="b") public int getX() { return 2; } @XmlElementRef public int getC() { return 3; } } /* /********************************************************** /* Unit tests /********************************************************** */ public void testXmlElementTypeDeser() throws Exception { ObjectMapper mapper = getJaxbMapper(); SimpleNamed originalModel = new SimpleNamed(); originalModel.setName("Foobar"); String json = mapper.writeValueAsString(originalModel); SimpleNamed result = null; try { result = mapper.readValue(json, SimpleNamed.class); } catch (Exception ie) { fail("Failed to deserialize '"+json+"': "+ie.getMessage()); } if (!"Foobar".equals(result.name)) { fail("Failed, JSON == '"+json+"')"); } } public void testForJackson288() throws Exception { final long TIMESTAMP = 12345678L; ObjectMapper mapper = getJaxbMapper(); Bean288 bean = mapper.readValue("{\"date\":"+TIMESTAMP+"}", Bean288.class); assertNotNull(bean); Date d = bean.date; assertNotNull(d); assertEquals(TIMESTAMP, d.getTime()); } public void testInclusionIssue40() throws Exception { ObjectMapper mapper = getJaxbMapper(); mapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME); String json = mapper.writeValueAsString(new Bean40()); @SuppressWarnings("unchecked") Map map = mapper.readValue(json, Map.class); Map exp = new LinkedHashMap(); exp.put("a", Integer.valueOf(1)); exp.put("b", Integer.valueOf(2)); exp.put("c", Integer.valueOf(3)); assertEquals(exp, map); } } TestAnnotationPriority.java000066400000000000000000000027701314745633000470010ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import javax.xml.bind.annotation.XmlElement; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Unit test(s) to verify that annotations from super classes and * interfaces are properly used (for example, wrt [JACKSON-450]) */ public class TestAnnotationPriority extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ public interface Identifiable { public String getId(); public void setId(String i); } static abstract class IdBase { protected String id; protected IdBase(String id) { this.id = id; } @XmlElement(name="name") public String getId() { return id; } public void setId(String id) { this.id = id; } } static class IdBean extends IdBase implements Identifiable { public IdBean(String id) { super(id); } } /* /********************************************************** /* Unit tests /********************************************************** */ public void testInterfacesAndClasses() throws Exception { ObjectMapper mapper = getJaxbMapper(); String json = mapper.writeValueAsString(new IdBean("foo")); assertEquals("{\"name\":\"foo\"}", json); } } TestIntrospectorPair.java000066400000000000000000000240441314745633000464320ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.AnnotatedClass; import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; /** * Simple testing that AnnotationIntrospector.Pair works as * expected, when used with Jackson and JAXB-based introspector. * * @author Tatu Saloranta */ public class TestIntrospectorPair extends BaseJaxbTest { final static AnnotationIntrospector _jacksonAI = new JacksonAnnotationIntrospector(); final static AnnotationIntrospector _jaxbAI = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); /* /********************************************************** /* Helper beans /********************************************************** */ /** * Simple test bean for verifying basic field detection and property * naming annotation handling */ @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) static class NamedBean { @JsonProperty private String jackson = "1"; @XmlElement(name="jaxb") protected String jaxb = "2"; @JsonProperty("bothJackson") @XmlElement(name="bothJaxb") private String bothString = "3"; public String notAGetter() { return "xyz"; } } /** * Another bean for verifying details of property naming */ @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) static class NamedBean2 { @JsonProperty("") @XmlElement(name="jaxb") public String foo = "abc"; @JsonProperty("jackson") @XmlElement() public String getBar() { return "123"; } // JAXB, alas, requires setters for all properties too public void setBar(String v) { } } /** * And a bean to check how "ignore" annotations work with * various combinations of annotation introspectors */ @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) static class IgnoreBean { @JsonIgnore public int getNumber() { return 13; } @XmlTransient public String getText() { return "abc"; } public boolean getAny() { return true; } } @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) static class IgnoreFieldBean { @JsonIgnore public int number = 7; @XmlTransient public String text = "123"; public boolean any = true; } @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) @XmlRootElement(name="test", namespace="urn:whatever") static class NamespaceBean { public String string; } // Testing [JACKSON-495] static class CreatorBean { @JsonCreator public CreatorBean(@JsonProperty("name") String name) { ; } } /* /********************************************************** /* Unit tests /********************************************************** */ public void testSimple() throws Exception { ObjectMapper mapper; AnnotationIntrospector pair; Map result; mapper = new ObjectMapper(); // first: test with Jackson/Jaxb pair (jackson having precedence) pair = new AnnotationIntrospectorPair(_jacksonAI, _jaxbAI); mapper.setAnnotationIntrospector(pair); result = writeAndMap(mapper, new NamedBean()); assertEquals(3, result.size()); assertEquals("1", result.get("jackson")); assertEquals("2", result.get("jaxb")); // jackson one should have priority assertEquals("3", result.get("bothJackson")); mapper = new ObjectMapper(); pair = new AnnotationIntrospectorPair(_jaxbAI, _jacksonAI); mapper.setAnnotationIntrospector(pair); result = writeAndMap(mapper, new NamedBean()); assertEquals(3, result.size()); assertEquals("1", result.get("jackson")); assertEquals("2", result.get("jaxb")); // JAXB one should have priority assertEquals("3", result.get("bothJaxb")); } public void testNaming() throws Exception { ObjectMapper mapper; AnnotationIntrospector pair; Map result; mapper = new ObjectMapper(); // first: test with Jackson/Jaxb pair (jackson having precedence) pair = new AnnotationIntrospectorPair(_jacksonAI, _jaxbAI); mapper.setAnnotationIntrospector(pair); result = writeAndMap(mapper, new NamedBean2()); assertEquals(2, result.size()); // order shouldn't really matter here... assertEquals("123", result.get("jackson")); assertEquals("abc", result.get("jaxb")); mapper = new ObjectMapper(); pair = new AnnotationIntrospectorPair(_jaxbAI, _jacksonAI); mapper.setAnnotationIntrospector(pair); result = writeAndMap(mapper, new NamedBean2()); /* Hmmh. Not 100% sure what JAXB would dictate.... thus... */ assertEquals(2, result.size()); assertEquals("abc", result.get("jaxb")); //assertEquals("123", result.get("jackson")); } public void testSimpleIgnore() throws Exception { // first: only Jackson introspector (default) ObjectMapper mapper = new ObjectMapper(); Map result = writeAndMap(mapper, new IgnoreBean()); assertEquals(2, result.size()); assertEquals("abc", result.get("text")); assertEquals(Boolean.TRUE, result.get("any")); // Then JAXB only mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(_jaxbAI); // jackson one should have priority result = writeAndMap(mapper, new IgnoreBean()); assertEquals(2, result.size()); assertEquals(Integer.valueOf(13), result.get("number")); assertEquals(Boolean.TRUE, result.get("any")); // then both, Jackson first mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(_jacksonAI, _jaxbAI)); result = writeAndMap(mapper, new IgnoreBean()); assertEquals(1, result.size()); assertEquals(Boolean.TRUE, result.get("any")); // then both, JAXB first mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(_jaxbAI, _jacksonAI)); result = writeAndMap(mapper, new IgnoreBean()); assertEquals(1, result.size()); assertEquals(Boolean.TRUE, result.get("any")); } public void testSimpleFieldIgnore() throws Exception { ObjectMapper mapper; // first: only Jackson introspector (default) mapper = new ObjectMapper(); Map result = writeAndMap(mapper, new IgnoreFieldBean()); assertEquals(2, result.size()); assertEquals("123", result.get("text")); assertEquals(Boolean.TRUE, result.get("any")); // Then JAXB only mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(_jaxbAI); // jackson one should have priority result = writeAndMap(mapper, new IgnoreFieldBean()); assertEquals(2, result.size()); assertEquals(Integer.valueOf(7), result.get("number")); assertEquals(Boolean.TRUE, result.get("any")); // then both, Jackson first mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(_jacksonAI, _jaxbAI)); result = writeAndMap(mapper, new IgnoreFieldBean()); assertEquals(1, result.size()); assertEquals(Boolean.TRUE, result.get("any")); // then both, JAXB first mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(_jaxbAI, _jacksonAI)); result = writeAndMap(mapper, new IgnoreFieldBean()); assertEquals(1, result.size()); assertEquals(Boolean.TRUE, result.get("any")); } public void testRootName() throws Exception { // first: test with Jackson/Jaxb pair (jackson having precedence) AnnotationIntrospector pair = new AnnotationIntrospectorPair(_jacksonAI, _jaxbAI); ObjectMapper mapper = new ObjectMapper() .setAnnotationIntrospector(pair); TypeFactory tf = mapper.getTypeFactory(); assertNull(pair.findRootName(AnnotatedClass.construct(tf.constructType(NamedBean.class), mapper.getSerializationConfig(), null))); PropertyName name = pair.findRootName(AnnotatedClass.construct(tf.constructType(NamespaceBean.class), mapper.getSerializationConfig(), null)); assertNotNull(name); assertEquals("test", name.getSimpleName()); assertEquals("urn:whatever", name.getNamespace()); // then reverse; should make no difference pair = new AnnotationIntrospectorPair(_jaxbAI, _jacksonAI); name = pair.findRootName(AnnotatedClass.construct(tf.constructType(NamedBean.class), mapper.getSerializationConfig(), null)); assertNull(name); name = pair.findRootName(AnnotatedClass.construct(tf.constructType(NamespaceBean.class), mapper.getSerializationConfig(), null)); assertEquals("test", name.getSimpleName()); assertEquals("urn:whatever", name.getNamespace()); } /** * Test that will just use Jackson annotations, but did trigger [JACKSON-495] due to a bug * in JAXB annotation introspector. */ public void testIssue495() throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(_jacksonAI, _jaxbAI)); CreatorBean bean = mapper.readValue("{\"name\":\"foo\"}", CreatorBean.class); assertNotNull(bean); } } TestJaxbAnnotationIntrospector.java000066400000000000000000000246641314745633000504660ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.util.*; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.namespace.QName; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.AnnotatedClass; import com.fasterxml.jackson.databind.introspect.AnnotatedField; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; /** * Tests for verifying that JAXB annotation based introspector * implementation works as expected * * @author Ryan Heaton * @author Tatu Saloranta */ public class TestJaxbAnnotationIntrospector extends BaseJaxbTest { /* /**************************************************** /* Helper beans /**************************************************** */ public static enum EnumExample { @XmlEnumValue("Value One") VALUE1 } public static class JaxbExample { protected String attributeProperty; protected String elementProperty; protected List wrappedElementProperty; protected EnumExample enumProperty; protected QName qname; protected QName qname1; protected String propertyToIgnore; @XmlJavaTypeAdapter(QNameAdapter.class) public QName getQname() { return qname; } public void setQname(QName qname) { this.qname = qname; } public QName getQname1() { return qname1; } public void setQname1(QName qname1) { this.qname1 = qname1; } @XmlAttribute(name="myattribute") public String getAttributeProperty() { return attributeProperty; } public void setAttributeProperty(String attributeProperty) { this.attributeProperty = attributeProperty; } @XmlElement(name="myelement") public String getElementProperty() { return elementProperty; } public void setElementProperty(String elementProperty) { this.elementProperty = elementProperty; } @XmlElementWrapper(name="mywrapped") public List getWrappedElementProperty() { return wrappedElementProperty; } public void setWrappedElementProperty(List wrappedElementProperty) { this.wrappedElementProperty = wrappedElementProperty; } public EnumExample getEnumProperty() { return enumProperty; } public void setEnumProperty(EnumExample enumProperty) { this.enumProperty = enumProperty; } @XmlTransient public String getPropertyToIgnore() { return propertyToIgnore; } public void setPropertyToIgnore(String propertyToIgnore) { this.propertyToIgnore = propertyToIgnore; } } public static class QNameAdapter extends XmlAdapter { @Override public QName unmarshal(String v) throws Exception { return QName.valueOf(v); } @Override public String marshal(QName v) throws Exception { return (v == null) ? null : v.toString(); } } @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) public static class SimpleBean { @XmlElement protected String jaxb = "1"; @XmlElement protected String jaxb2 = "2"; @XmlElement(name="jaxb3") private String oddName = "3"; public String notAGetter() { return "xyz"; } @XmlTransient public int foobar = 3; } @SuppressWarnings("unused") @XmlAccessorType(XmlAccessType.FIELD) public static class SimpleBean2 { protected String jaxb = "1"; private String jaxb2 = "2"; @XmlElement(name="jaxb3") private String oddName = "3"; } @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) @XmlRootElement(namespace="urn:class") static class NamespaceBean { @XmlElement(namespace="urn:method") public String string; } @XmlRootElement(name="test") static class RootNameBean { } @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL) public static class AlphaBean { public int c = 3; public int a = 1; public int b = 2; } public static class KeyValuePair { private String key; private String value; public KeyValuePair() {} public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } /* /**************************************************** /* Unit tests /**************************************************** */ private final ObjectMapper MAPPER = getJaxbMapper(); public void testDetection() throws Exception { Map result = writeAndMap(MAPPER, new SimpleBean()); assertEquals(3, result.size()); assertEquals("1", result.get("jaxb")); assertEquals("2", result.get("jaxb2")); assertEquals("3", result.get("jaxb3")); result = writeAndMap(MAPPER, new SimpleBean2()); assertEquals(3, result.size()); assertEquals("1", result.get("jaxb")); assertEquals("2", result.get("jaxb2")); assertEquals("3", result.get("jaxb3")); } /** * tests getting serializer/deserializer instances. */ public void testSerializeDeserializeWithJaxbAnnotations() throws Exception { ObjectMapper mapper = getJaxbMapper(); // test expects that wrapper name be used... mapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME); mapper.enable(SerializationFeature.INDENT_OUTPUT); JaxbExample ex = new JaxbExample(); QName qname = new QName("urn:hi", "hello"); ex.setQname(qname); QName qname1 = new QName("urn:hi", "hello1"); ex.setQname1(qname1); ex.setAttributeProperty("attributeValue"); ex.setElementProperty("elementValue"); ex.setWrappedElementProperty(Arrays.asList("wrappedElementValue")); ex.setEnumProperty(EnumExample.VALUE1); ex.setPropertyToIgnore("ignored"); String json = mapper.writeValueAsString(ex); // uncomment to see what the JSON looks like. // System.out.println(json); //make sure the json is written out correctly. JsonNode node = mapper.readValue(json, JsonNode.class); assertEquals(qname.toString(), node.get("qname").asText()); JsonNode attr = node.get("myattribute"); assertNotNull(attr); assertEquals("attributeValue", attr.asText()); assertEquals("elementValue", node.get("myelement").asText()); assertTrue(node.has("mywrapped")); assertEquals(1, node.get("mywrapped").size()); assertEquals("wrappedElementValue", node.get("mywrapped").get(0).asText()); assertEquals("Value One", node.get("enumProperty").asText()); assertNull(node.get("propertyToIgnore")); //now make sure it gets deserialized correctly. JaxbExample readEx = mapper.readValue(json, JaxbExample.class); assertEquals(ex.qname, readEx.qname); assertEquals(ex.qname1, readEx.qname1); assertEquals(ex.attributeProperty, readEx.attributeProperty); assertEquals(ex.elementProperty, readEx.elementProperty); assertEquals(ex.wrappedElementProperty, readEx.wrappedElementProperty); assertEquals(ex.enumProperty, readEx.enumProperty); assertNull(readEx.propertyToIgnore); } public void testRootNameAccess() throws Exception { final TypeFactory tf = TypeFactory.defaultInstance(); AnnotationIntrospector ai = new JaxbAnnotationIntrospector(tf); // If no @XmlRootElement, should get null (unless pkg has etc) assertNull(ai.findRootName(AnnotatedClass.construct(tf.constructType(SimpleBean.class), MAPPER.getSerializationConfig(), null))); // With @XmlRootElement, but no name, empty String PropertyName rootName = ai.findRootName(AnnotatedClass.construct(tf.constructType(NamespaceBean.class), MAPPER.getSerializationConfig(), null)); assertNotNull(rootName); assertEquals("", rootName.getSimpleName()); assertEquals("urn:class", rootName.getNamespace()); // and otherwise explicit name rootName = ai.findRootName(AnnotatedClass.construct(tf.constructType(RootNameBean.class), MAPPER.getSerializationConfig(), null)); assertNotNull(rootName); assertEquals("test", rootName.getSimpleName()); assertNull(rootName.getNamespace()); } // JAXB can specify that properties are to be written in alphabetic order... public void testSerializationAlphaOrdering() throws Exception { assertEquals("{\"a\":1,\"b\":2,\"c\":3}", MAPPER.writeValueAsString(new AlphaBean())); } /** * Additional simple tests to ensure we will retain basic namespace information * now that it can be included * * @since 2.1 */ public void testNamespaces() throws Exception { final TypeFactory tf = TypeFactory.defaultInstance(); JaxbAnnotationIntrospector ai = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); AnnotatedClass ac = AnnotatedClass.construct(tf.constructType(NamespaceBean.class), MAPPER.getSerializationConfig(), null); AnnotatedField af = _findField(ac, "string"); assertNotNull(af); PropertyName pn = ai.findNameForDeserialization(af); assertNotNull(pn); // JAXB seems to assert field name instead of giving "use default"... assertEquals("", pn.getSimpleName()); assertEquals("urn:method", pn.getNamespace()); } private AnnotatedField _findField(AnnotatedClass ac, String name) { for (AnnotatedField af : ac.fields()) { if (name.equals(af.getName())) { return af; } } return null; } } TestJaxbAutoDetect.java000066400000000000000000000117741314745633000457770ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.io.*; import java.math.BigDecimal; import java.util.Map; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; /** * Tests for verifying auto-detection settings with JAXB annotations. * * @author Tatu Saloranta */ public class TestJaxbAutoDetect extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ /* Bean for testing problem [JACKSON-183]: with normal * auto-detect enabled, 2 fields visible; if disabled, just 1. * NOTE: should NOT include "XmlAccessorType", since it will * have priority over global defaults */ static class Jackson183Bean { public String getA() { return "a"; } @XmlElement public String getB() { return "b"; } // JAXB (or Bean introspection) mandates use of matching setters... public void setA(String str) { } public void setB(String str) { } } static class Identified { Object id; @XmlAttribute(name="id") public Object getIdObject() { return id; } public void setId(Object id) { this.id = id; } } @XmlRootElement(name="bah") public static class JaxbAnnotatedObject { private BigDecimal number; public JaxbAnnotatedObject() { } public JaxbAnnotatedObject(String number) { this.number = new BigDecimal(number); } @XmlElement public void setNumber(BigDecimal number) { this.number = number; } @XmlTransient public BigDecimal getNumber() { return number; } @XmlElement(name = "number") public BigDecimal getNumberString() { return number; } } @SuppressWarnings("serial") public static class DualAnnotationObjectMapper extends ObjectMapper { public DualAnnotationObjectMapper() { super(); AnnotationIntrospector primary = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); AnnotationIntrospector secondary = new JacksonAnnotationIntrospector(); // make de/serializer use JAXB annotations first, then jackson ones AnnotationIntrospector pair = new AnnotationIntrospectorPair(primary, secondary); setAnnotationIntrospector(pair); } } /* /********************************************************** /* Unit tests /********************************************************** */ public void testAutoDetectDisable() throws IOException { ObjectMapper mapper = getJaxbMapper(); Jackson183Bean bean = new Jackson183Bean(); Map result; // Ok: by default, should see 2 fields: result = writeAndMap(mapper, bean); assertEquals(2, result.size()); assertEquals("a", result.get("a")); assertEquals("b", result.get("b")); // But when disabling auto-detection, just one mapper = getJaxbMapper(); mapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false); result = writeAndMap(mapper, bean); assertEquals(1, result.size()); assertNull(result.get("a")); assertEquals("b", result.get("b")); } public void testIssue246() throws IOException { ObjectMapper mapper = getJaxbMapper(); Identified id = new Identified(); id.id = "123"; assertEquals("{\"id\":\"123\"}", mapper.writeValueAsString(id)); } // [JACKSON-556] public void testJaxbAnnotatedObject() throws Exception { JaxbAnnotatedObject original = new JaxbAnnotatedObject("123"); ObjectMapper mapper = new DualAnnotationObjectMapper(); String json = mapper.writeValueAsString(original); assertFalse("numberString field in JSON", json.contains("numberString")); // kinda hack-y :) JaxbAnnotatedObject result = mapper.readValue(json, JaxbAnnotatedObject.class); assertEquals(new BigDecimal("123"), result.number); } /* public void testJaxbAnnotatedObjectXML() throws Exception { JAXBContext ctxt = JAXBContext.newInstance(JaxbAnnotatedObject.class); JaxbAnnotatedObject original = new JaxbAnnotatedObject("123"); StringWriter sw = new StringWriter(); ctxt.createMarshaller().marshal(original, sw); String xml = sw.toString(); JaxbAnnotatedObject result = (JaxbAnnotatedObject) ctxt.createUnmarshaller().unmarshal(new StringReader(xml)); assertEquals(new BigDecimal("123"), result.number); } */ } TestJaxbFieldAccess.java000066400000000000000000000024101314745633000460660ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.io.IOException; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; public class TestJaxbFieldAccess extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ @XmlAccessorType(XmlAccessType.FIELD) static class Fields { protected int x; public Fields() { } Fields(int x) { this.x = x; } } /* /********************************************************** /* Unit tests /********************************************************** */ // Verify serialization wrt [JACKSON-202] public void testFieldSerialization() throws IOException { ObjectMapper mapper = getJaxbMapper(); assertEquals("{\"x\":3}", serializeAsString(mapper, new Fields(3))); } // Verify deserialization wrt [JACKSON-202] public void testFieldDeserialization() throws IOException { ObjectMapper mapper = getJaxbMapper(); Fields result = mapper.readValue("{ \"x\":3 }", Fields.class); assertEquals(3, result.x); } } TestPropertyOrdering.java000066400000000000000000000053271314745633000464440ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; public class TestPropertyOrdering extends BaseJaxbTest { @XmlType(propOrder = {"cparty", "contacts"}) @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL) public class BeanFor268 { private String cpartyDto = "dto"; private int[] contacts = new int[] { 1, 2, 3 }; @XmlElement(name="cparty") public String getCpartyDto() { return cpartyDto; } public void setCpartyDto(String cpartyDto) { this.cpartyDto = cpartyDto; } @XmlElement(name="contacts") public int[] getContact() { return contacts; } public void setContact(int[] contacts) { this.contacts = contacts; } } /* Also, considering that JAXB actually seems to expect original * names for property ordering, let's see that alternative * annotation also works * (see [JACKSON-268] for more details) */ @XmlType(propOrder = {"cpartyDto", "contacts"}) @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL) public class BeanWithImplicitNames { private String cpartyDto = "dto"; private int[] contacts = new int[] { 1, 2, 3 }; @XmlElement(name="cparty") public String getCpartyDto() { return cpartyDto; } public void setCpartyDto(String cpartyDto) { this.cpartyDto = cpartyDto; } @XmlElement(name="contacts") public int[] getContact() { return contacts; } public void setContact(int[] contacts) { this.contacts = contacts; } } @XmlType(propOrder={"b", "a", "c"}) public static class AlphaBean2 { public int c = 3; public int a = 1; public int b = 2; } /* /********************************************************** /* Tests /********************************************************** */ public void testSerializationExplicitOrdering() throws Exception { ObjectMapper mapper = getJaxbMapper(); assertEquals("{\"b\":2,\"a\":1,\"c\":3}", serializeAsString(mapper, new AlphaBean2())); } // Trying to reproduce [JACKSON-268] public void testOrderingWithRename() throws Exception { ObjectMapper mapper = getJaxbMapper(); assertEquals("{\"cparty\":\"dto\",\"contacts\":[1,2,3]}", mapper.writeValueAsString(new BeanFor268())); } public void testOrderingWithOriginalPropName() throws Exception { ObjectMapper mapper = getJaxbMapper(); assertEquals("{\"cparty\":\"dto\",\"contacts\":[1,2,3]}", mapper.writeValueAsString(new BeanWithImplicitNames())); } } TestPropertyVisibility.java000066400000000000000000000046471314745633000470260ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.io.IOException; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; public class TestPropertyVisibility extends BaseJaxbTest { @XmlAccessorType(XmlAccessType.NONE) protected static class Bean354 { protected String name = "foo"; @XmlElement protected String getName() { return name; } public void setName(String s) { name = s; } } // Note: full example would be "Content"; but let's use simpler demonstration here, easier to debug @XmlAccessorType(XmlAccessType.PROPERTY) static class Jackson539Bean { protected int type; @XmlTransient public String getType() { throw new UnsupportedOperationException(); } public void setType(String type) { throw new UnsupportedOperationException(); } @XmlAttribute(name = "type") public int getRawType() { return type; } public void setRawType(int type) { this.type = type; } } /* /********************************************************** /* Unit tests /********************************************************** */ // Verify serialization wrt [JACKSON-354] // // NOTE: fails currently because we use Bean Introspector which only sees public methods -- need to rewrite public void testJackson354Serialization() throws IOException { ObjectMapper mapper = getJaxbMapper(); assertEquals("{\"name\":\"foo\"}", mapper.writeValueAsString(new Bean354())); } // For [JACKSON-539] public void testJacksonSerialization() throws Exception { /* Earlier Content content = new Content(); content.setRawType("application/json"); String json = mapper.writeValueAsString(content); Content content2 = mapper.readValue(json, Content.class); // deserialize assertNotNull(content2); */ Jackson539Bean input = new Jackson539Bean(); input.type = 123; ObjectMapper mapper = getJaxbMapper(); String json = mapper.writeValueAsString(input); Jackson539Bean result = mapper.readValue(json, Jackson539Bean.class); assertNotNull(result); assertEquals(123, result.type); } } TestXmlValue.java000066400000000000000000000037161314745633000446630ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/introspectpackage com.fasterxml.jackson.module.jaxb.introspect; import java.io.IOException; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; public class TestXmlValue extends BaseJaxbTest { static class WithXmlValueNoOverride { @XmlValue public int getFoobar() { return 13; } } static class WithXmlValueAndOverride { @XmlValue @JsonProperty("number") public int getFoobar() { return 13; } } // [Issue#31] static class Query { @XmlValue protected String query; public String getQuery() { return query; } public void setQuery(final String pQuery) { query = pQuery; } } /* /********************************************************** /* Unit tests /********************************************************** */ // For [Issue#30] public void testXmlValueDefault() throws IOException { ObjectMapper mapper = getJaxbAndJacksonMapper(); // default is 'value' assertEquals("{\"value\":13}", mapper.writeValueAsString(new WithXmlValueNoOverride())); } // For [Issue#30] public void testXmlValueOverride() throws IOException { ObjectMapper mapper = getJaxbAndJacksonMapper(); // default is 'value' assertEquals("{\"number\":13}", mapper.writeValueAsString(new WithXmlValueAndOverride())); } // For [Issue#31] public void testXmlValueDefault2() throws IOException { ObjectMapper mapper = getJaxbAndJacksonMapper(); Query q2 = new Query(); q2.query = "foo"; // default is 'value' Query q = mapper.readValue("{\"value\":\"some stuff\"}", Query.class); assertEquals("some stuff", q.getQuery()); } } misc/000077500000000000000000000000001314745633000401555ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbTestDeserializerCaching.java000066400000000000000000000051611314745633000455620ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.BeanDeserializer; import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Unit test(s) for [JACKSON-472] */ public class TestDeserializerCaching extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ static class MyBeanModule extends Module { @Override public String getModuleName() { return "MyBeanModule"; } @Override public Version version() { return Version.unknownVersion(); } @Override public void setupModule(SetupContext context) { context.addBeanDeserializerModifier(new MyBeanDeserializerModifier()); } } @SuppressWarnings("serial") static class MyBeanDeserializer extends BeanDeserializer { public MyBeanDeserializer(BeanDeserializer src) { super(src); } } static class MyBean { public MyType value1; public MyType value2; public MyType value3; } static class MyType { public String name; public String value; } static class MyBeanDeserializerModifier extends BeanDeserializerModifier { static int count = 0; @Override public JsonDeserializer modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer deserializer) { if (MyType.class.isAssignableFrom(beanDesc.getBeanClass())) { count++; return new MyBeanDeserializer((BeanDeserializer)deserializer); } return super.modifyDeserializer(config, beanDesc, deserializer); } } /* /********************************************************** /* Unit tests /********************************************************** */ public void testCaching() throws Exception { final String JSON = "{\"value1\" : {\"name\" : \"fruit\", \"value\" : \"apple\"},\n" +"\"value2\" : {\"name\" : \"color\", \"value\" : \"red\"},\n" +"\"value3\" : {\"name\" : \"size\", \"value\" : \"small\"}}" ; ObjectMapper mapper = getJaxbMapper(); mapper.registerModule(new MyBeanModule()); mapper.readValue(JSON, MyBean.class); assertEquals(1, MyBeanDeserializerModifier.count); } } TestDomElementSerialization.java000066400000000000000000000067231314745633000464570ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.io.StringWriter; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.Serializers; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.deser.DomElementJsonDeserializer; import com.fasterxml.jackson.module.jaxb.ser.DomElementJsonSerializer; /** * @author Ryan Heaton */ public class TestDomElementSerialization extends BaseJaxbTest { /* /********************************************************** /* Helper classes /********************************************************** */ @SuppressWarnings("serial") private final static class DomModule extends SimpleModule { public DomModule() { super("DomModule", Version.unknownVersion()); addDeserializer(Element.class, new DomElementJsonDeserializer()); /* 19-Feb-2011, tatu: Note: since SimpleModule does not support "generic" * serializers, need to add bit more code here. */ //testModule.addSerializer(new DomElementJsonSerializer()); } @Override public void setupModule(SetupContext context) { super.setupModule(context); context.addSerializers(new DomSerializers()); } } private final static class DomSerializers extends Serializers.Base { @Override public JsonSerializer findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) { if (Element.class.isAssignableFrom(type.getRawClass())) { return new DomElementJsonSerializer(); } return null; } } /* /********************************************************** /* Test methods /********************************************************** */ public void testBasicDomElementSerializationDeserialization() throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new DomModule()); StringBuilder builder = new StringBuilder() .append("") .append("howdy") .append(""); DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance(); bf.setNamespaceAware(true); Document document = bf.newDocumentBuilder().parse(new ByteArrayInputStream(builder.toString().getBytes("utf-8"))); StringWriter jsonElement = new StringWriter(); mapper.writeValue(jsonElement, document.getDocumentElement()); Element el = mapper.readValue(jsonElement.toString(), Element.class); assertEquals(3, el.getAttributes().getLength()); assertEquals("value1", el.getAttributeNS(null, "att1")); assertEquals("value2", el.getAttributeNS(null, "att2")); assertEquals(1, el.getChildNodes().getLength()); assertEquals("childel", el.getChildNodes().item(0).getLocalName()); assertEquals("urn:hello", el.getChildNodes().item(0).getNamespaceURI()); assertEquals("howdy", el.getChildNodes().item(0).getTextContent()); } } TestElementWrapper.java000066400000000000000000000101031314745633000446050ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import java.util.*; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Unit tests to verify handling of @XmlElementWrapper annotation. */ public class TestElementWrapper extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ // Beans for [JACKSON-436] static class Person { @XmlElementWrapper(name="phones") @XmlElement(type=Phone.class) public Collection phone; } interface IPhone { public String getNumber(); } static class Phone implements IPhone { private String number; public Phone() { } public Phone(String number) { this.number = number; } @Override public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } // [Issue#13] static class Bean13 { @XmlElementWrapper(name="wrap") public int id; } // [Issue#25]: should also work with 'default' name static class Bean25 { @XmlElement(name="element") // This would work // @XmlElementWrapper(name="values") @XmlElementWrapper public List values; public Bean25() { } public Bean25(int... v0) { values = new ArrayList(); for (int v : v0) { values.add(v); } } } /* /********************************************************** /* Unit tests /********************************************************** */ // [JACKSON-436] public void testWrapperWithCollection() throws Exception { ObjectMapper mapper = getJaxbMapper(); // for fun, force renaming with wrapper annotation, even for JSON mapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME); Collection phones = new HashSet(); phones.add(new Phone("555-6666")); Person p = new Person(); p.phone = phones; String json = mapper.writeValueAsString(p); // as per assertEquals("{\"phones\":[{\"number\":\"555-6666\"}]}", json); // System.out.println("JSON == "+json); Person result = mapper.readValue(json, Person.class); assertNotNull(result.phone); assertEquals(1, result.phone.size()); assertEquals("555-6666", result.phone.iterator().next().getNumber()); } // [Issue#13] public void testWrapperRenaming() throws Exception { ObjectMapper mapper = getJaxbMapper(); // verify that by default feature is off: assertFalse(mapper.isEnabled(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME)); Bean13 input = new Bean13(); input.id = 3; assertEquals("{\"id\":3}", mapper.writeValueAsString(input)); // but if we create new instance, configure mapper = getJaxbMapper(); mapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME); assertEquals("{\"wrap\":3}", mapper.writeValueAsString(input)); } // [Issue#25] public void testWrapperDefaultName() throws Exception { ObjectMapper mapper = getJaxbMapper(); mapper = getJaxbMapper(); mapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME); Bean25 input = new Bean25(1, 2, 3); final String JSON = "{\"values\":[1,2,3]}"; assertEquals(JSON, mapper.writeValueAsString(input)); // plus needs to come back ok as well Bean25 result = mapper.readValue(JSON, Bean25.class); assertNotNull(result); assertNotNull(result.values); assertEquals(3, result.values.size()); // and finally verify roundtrip as well assertEquals(JSON, mapper.writeValueAsString(result)); } } TestEnums.java000066400000000000000000000013751314745633000427550ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import javax.xml.bind.annotation.XmlEnum; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; public class TestEnums extends BaseJaxbTest { enum Plain { A, B; } @XmlEnum(Integer.class) enum Numeric { A, B; } /* /********************************************************** /* Unit tests /********************************************************** */ // [JACKSON-436] public void testWrapperWithCollection() throws Exception { ObjectMapper mapper = getJaxbMapper(); assertEquals("\"B\"", mapper.writeValueAsString(Plain.B)); assertEquals("1", mapper.writeValueAsString(Numeric.B)); } } TestJaxbNullProperties.java000066400000000000000000000061041314745633000454550ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; /** * Unit tests to ensure that handling of writing of null properties (or not) * works when using JAXB annotation introspector. * Mostly to test out [JACKSON-309]. */ public class TestJaxbNullProperties extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ public static class Bean { public String empty; public String x = "y"; } @XmlRootElement static class BeanWithNillable { public Nillable X; } @XmlRootElement static class Nillable { @XmlElement (name="Z", nillable=true) Integer Z; public Nillable() { } public Nillable(int i) { Z = Integer.valueOf(i); } } @XmlRootElement static class NonNillableZ { @XmlElement(name="z", nillable=false) public Integer z; public NonNillableZ() { } public NonNillableZ(int i) { z = Integer.valueOf(i); } } /* /********************************************************** /* Unit tests /********************************************************** */ private final ObjectMapper MAPPER = getJaxbMapper(); public void testWriteNulls() throws Exception { BeanWithNillable bean = new BeanWithNillable(); bean.X = new Nillable(); assertEquals("{\"X\":{\"Z\":null}}", MAPPER.writeValueAsString(bean)); } public void testNullProps() throws Exception { ObjectMapper mapper = getJaxbMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); assertEquals("{\"x\":\"y\"}", mapper.writeValueAsString(new Bean())); } public void testNillability() throws Exception { ObjectMapper mapper = getJaxbMapper(); // by default, something not marked as nillable will still be written if null assertEquals("{\"z\":null}", mapper.writeValueAsString(new NonNillableZ())); assertEquals("{\"z\":3}", mapper.writeValueAsString(new NonNillableZ(3))); // but we can change that... mapper = new ObjectMapper() .registerModule(new JaxbAnnotationModule() .setNonNillableInclusion(JsonInclude.Include.NON_NULL) ); mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(mapper.getTypeFactory()) .setNonNillableInclusion(JsonInclude.Include.NON_NULL) ); assertEquals("{}", mapper.writeValueAsString(new NonNillableZ())); assertEquals("{\"z\":3}", mapper.writeValueAsString(new NonNillableZ(3))); } } TestRootName.java000066400000000000000000000020011314745633000433750ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import javax.xml.bind.annotation.XmlRootElement; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; public class TestRootName extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ @XmlRootElement(name="rooty") static class MyType { public int value = 37; } /* /********************************************************** /* Unit tests /********************************************************** */ public void testRootName() throws Exception { ObjectMapper mapper = getJaxbMapper(); mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true); assertEquals("{\"rooty\":{\"value\":37}}", mapper.writeValueAsString(new MyType())); } } TestSchemaGeneration.java000066400000000000000000000041231314745633000450740ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.jsonschema.JsonSchema; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Test(s) to see that JAXB annotations-based information is properly * accessible and used by JSON Schema generation * * @author tatu */ @SuppressWarnings("deprecation") public class TestSchemaGeneration extends BaseJaxbTest { @XmlAccessorType(XmlAccessType.FIELD) protected static class Person { public String firstName; public String lastName; @XmlElement(type=Address.class) public IAddress address; } protected interface IAddress { public String getCity(); public void setCity(String city); } protected static class Address implements IAddress { private String city; private String state; @Override public String getCity() { return city; } @Override public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } } /* /********************************************************** /* Tests /********************************************************** */ /** * Test for [JACKSON-415] * * @since 1.7 */ public void testWithJaxb() throws Exception { ObjectMapper mapper = getJaxbMapper(); JsonSchema jsonSchema = mapper.generateJsonSchema(Address.class); ObjectNode root = jsonSchema.getSchemaNode(); // should find two properties ("city", "state"), not just one... JsonNode itemsNode = root.findValue("properties"); assertNotNull("Missing 'state' field", itemsNode.get("state")); assertNotNull("Missing 'city' field", itemsNode.get("city")); assertEquals(2, itemsNode.size()); } } TestSerializationInclusion.java000066400000000000000000000025111314745633000463600ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import java.util.List; import javax.xml.bind.annotation.XmlElement; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; public class TestSerializationInclusion extends BaseJaxbTest { static class Data { private final List stuff = new java.util.ArrayList(); @XmlElement public List getStuff() { return stuff; } } public void testIssue39() throws Exception { // First: use plain JAXB introspector: _testInclusion(getJaxbMapper()); // and then combination ones _testInclusion(getJaxbAndJacksonMapper()); _testInclusion(getJacksonAndJaxbMapper()); // finally: verify using actual module ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JaxbAnnotationModule()); _testInclusion(mapper); } private void _testInclusion(ObjectMapper mapper) throws Exception { mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); String json = mapper.writeValueAsString(new Data()); assertEquals("{}", json); } } TestXmlAnyElementWithElementRef.java000066400000000000000000000033031314745633000472040ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/miscpackage com.fasterxml.jackson.module.jaxb.misc; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; public class TestXmlAnyElementWithElementRef extends BaseJaxbTest { static class Bean { @XmlAnyElement(lax=true) @XmlElementRefs({ @XmlElementRef(name="a", type=Name.class), @XmlElementRef(name="b", type=Count.class) }) public List others; public Bean() { } public Bean(Object ob) { others = new ArrayList(); others.add(ob); } } static class Name { public String name; } static class Count { public int count; } /* /********************************************************** /* Test methods /********************************************************** */ // [JACKSON-254]: verify that things do work public void testXmlAnyElementWithElementRef() throws Exception { ObjectMapper mapper = getJaxbMapper(); Count count = new Count(); count.count = 8; Bean value = new Bean(count); // typed handling should be triggered by annotation on property, so String json = mapper.writeValueAsString(value); assertEquals("{\"others\":[{\"b\":{\"count\":8}}]}", json); Bean result = mapper.readValue(json, Bean.class); assertNotNull(result); assertEquals(1, result.others.size()); Object resultOb = result.others.get(0); assertSame(Count.class, resultOb.getClass()); assertEquals(8, ((Count) resultOb).count); } } package-info.java000066400000000000000000000006271314745633000433510ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/misc/** * Package info can be used to add "package annotations", so here we are... */ @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters({ @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter( type = javax.xml.namespace.QName.class, value = com.fasterxml.jackson.module.jaxb.introspect.TestJaxbAnnotationIntrospector.QNameAdapter.class ) }) package com.fasterxml.jackson.module.jaxb.misc; types/000077500000000000000000000000001314745633000403665ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxbOptionalTypeRefinementTest.java000066400000000000000000000015471314745633000465440ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; // [jaxb-annotations#63] public class OptionalTypeRefinementTest extends BaseJaxbTest { static class Stuff63 { public AtomicReference value = new AtomicReference("abc"); } public void testWithReferenceType() throws Exception { final ObjectMapper mapper = getJaxbMapper(); String json = mapper.writeValueAsString(new Stuff63()); assertEquals("{\"value\":\"abc\"}", json); Stuff63 result = mapper.readValue("{\"value\":\"xyz\"}", Stuff63.class); assertNotNull(result); assertNotNull(result.value); assertEquals("xyz", result.value.get()); } } PolymorpicTestBase.java000066400000000000000000000024371314745633000450270ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import javax.xml.bind.annotation.XmlRootElement; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; abstract class PolymorpicTestBase extends BaseJaxbTest { static abstract class Animal { public String nickname; protected Animal(String n) { nickname = n; } } static class Buffalo extends Animal { public String hairColor; public Buffalo() { this(null, null); } public Buffalo(String name, String hc) { super(name); hairColor = hc; } } static class Whale extends Animal { public int weightInTons; public Whale() { this(null, 0); } public Whale(String n, int w) { super(n); weightInTons = w; } } @XmlRootElement static class Emu extends Animal { public String featherColor; public Emu() { this(null, null); } public Emu(String n, String w) { super(n); featherColor = w; } } @XmlRootElement (name="moo") static class Cow extends Animal { public int weightInPounds; public Cow() { this(null, 0); } public Cow(String n, int w) { super(n); weightInPounds = w; } } } TestCyclicTypes.java000066400000000000000000000033051314745633000443250ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Simple unit tests to verify that it is possible to handle * potentially cyclic structures, as long as object graph itself * is not cyclic. This is the case for directed hierarchies like * trees and DAGs. */ public class TestCyclicTypes extends BaseJaxbTest { /* /********************************************************** /* Helper bean classes /********************************************************** */ @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) static class Bean { private Bean _next; final String _name; public Bean(Bean next, String name) { _next = next; _name = name; } public Bean getNext() { return _next; } public String getName() { return _name; } public void assignNext(Bean n) { _next = n; } } /* /********************************************************** /* Types /********************************************************** */ /* Added to check for [JACKSON-171], i.e. that type its being * cyclic is not a problem (instances are). */ public void testWithJAXB() throws Exception { ObjectMapper mapper = getJaxbMapper(); Bean bean = new Bean(null, "abx"); Map results = writeAndMap(mapper, bean); assertEquals(2, results.size()); assertEquals("abx", results.get("name")); assertTrue(results.containsKey("next")); assertNull(results.get("next")); } } TestJaxbPolymorphic.java000066400000000000000000000131611314745633000452050ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; /** * Tests for handling of type-related JAXB annotations * * @author Tatu Saloranta * @author Ryan Heaton */ public class TestJaxbPolymorphic extends PolymorpicTestBase { /* /********************************************************** /* Helper beans /********************************************************** */ static class Bean { @XmlElements({ @XmlElement(type=Buffalo.class, name="beefalot"), @XmlElement(type=Whale.class, name="whale") }) public Animal animal; @XmlElementRefs({ @XmlElementRef(type=Emu.class), @XmlElementRef(type=Cow.class) }) public Animal other; public Bean() { } public Bean(Animal a) { animal = a; } } static class ArrayBean { @XmlElements({ @XmlElement(type=Buffalo.class, name="b"), @XmlElement(type=Whale.class, name="w") }) public Animal[] animals; @XmlElementRefs({ @XmlElementRef(type=Emu.class), @XmlElementRef(type=Cow.class) }) public Animal[] otherAnimals; public ArrayBean() { } public ArrayBean(Animal... a) { animals = a; } } @XmlSeeAlso({ BaseImpl.class }) abstract static class Base { } static class BaseImpl extends Base { public String name; public BaseImpl() { } public BaseImpl(String n) { name = n; } } static class ContainerForBase { @XmlElements({ }) // @XmlElement(type=BaseImpl.class, name="baseImpl"), public Base[] stuff; } /* /********************************************************** /* Test methods /********************************************************** */ private final ObjectMapper MAPPER = getJaxbMapper(); //First a simple test with non-collection field @SuppressWarnings("unchecked") public void testSinglePolymorphic() throws Exception { Bean input = new Bean(new Buffalo("Billy", "brown")); String str = MAPPER.writeValueAsString(input); // First: let's verify output looks like what we expect: Map map = MAPPER.readValue(str, Map.class); assertEquals(2, map.size()); Map map2 = (Map) map.get("animal"); assertNotNull(map2); // second level, should have type info as WRAPPER_OBJECT assertEquals(1, map2.size()); assertTrue(map2.containsKey("beefalot")); Map map3 = (Map) map2.get("beefalot"); assertEquals(2, map3.size()); // good enough, let's deserialize Bean result = MAPPER.readValue(str, Bean.class); Animal a = result.animal; assertNotNull(a); assertEquals(Buffalo.class, a.getClass()); assertEquals("Billy", a.nickname); assertEquals("brown", ((Buffalo) a).hairColor); } public void testPolymorphicArray() throws Exception { Animal a1 = new Buffalo("Bill", "grey"); Animal a2 = new Whale("moe", 3000); ArrayBean input = new ArrayBean(a1, null, a2); String str = MAPPER.writeValueAsString(input); ArrayBean result = MAPPER.readValue(str, ArrayBean.class); assertEquals(3, result.animals.length); a1 = result.animals[0]; assertNull(result.animals[1]); a2 = result.animals[2]; assertNotNull(a1); assertNotNull(a2); assertEquals(Buffalo.class, a1.getClass()); assertEquals(Whale.class, a2.getClass()); assertEquals("Bill", a1.nickname); assertEquals("grey", ((Buffalo) a1).hairColor); assertEquals("moe", a2.nickname); assertEquals(3000, ((Whale)a2).weightInTons); } public void testPolymorphicArrayElementRef() throws Exception { Animal a1 = new Emu("Bill", "grey"); Animal a2 = new Cow("moe", 3000); ArrayBean input = new ArrayBean(); input.otherAnimals = new Animal[]{a1, null, a2}; String str = MAPPER.writeValueAsString(input); ArrayBean result = MAPPER.readValue(str, ArrayBean.class); assertEquals(3, result.otherAnimals.length); a1 = result.otherAnimals[0]; assertNull(result.otherAnimals[1]); a2 = result.otherAnimals[2]; assertNotNull(a1); assertNotNull(a2); assertEquals(Emu.class, a1.getClass()); assertEquals(Cow.class, a2.getClass()); assertEquals("Bill", a1.nickname); assertEquals("grey", ((Emu) a1).featherColor); assertEquals("moe", a2.nickname); assertEquals(3000, ((Cow)a2).weightInPounds); } // For [Issue#1] public void testXmlSeeAlso() throws Exception { ContainerForBase input = new ContainerForBase(); input.stuff = new Base[] { new BaseImpl("xyz") }; String json = MAPPER.writeValueAsString(input); // so far so good. But can we read it back? ContainerForBase output = MAPPER.readValue(json, ContainerForBase.class); assertNotNull(output); assertNotNull(output.stuff); assertEquals(1, output.stuff.length); assertEquals(BaseImpl.class, output.stuff[0].getClass()); assertEquals("xyz", ((BaseImpl) output.stuff[0]).name); } } TestJaxbPolymorphicLists.java000066400000000000000000000077511314745633000462340ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; /** * Tests for handling of type-related JAXB annotations with collection (List) * types. */ public class TestJaxbPolymorphicLists extends PolymorpicTestBase { /* /********************************************************** /* Helper beans /********************************************************** */ static class ListBean { @XmlElements({ @XmlElement(type=Buffalo.class, name="beefalot"), @XmlElement(type=Whale.class, name="whale") }) public List animals; @XmlElementRefs({ @XmlElementRef(type=Emu.class), @XmlElementRef(type=Cow.class) }) public List otherAnimals; public ListBean() { } public ListBean(Animal... a) { animals = new ArrayList(); for (Animal an : a) { animals.add(an); } } } static class Leopard extends Animal { public Leopard() { super("Lez"); } } static class ShortListHolder { @XmlElement(name="id", type=Short.class) public List ids; } /* /********************************************************** /* Tests /********************************************************** */ /** * And then a test for collection types */ public void testPolymorphicList() throws Exception { ObjectMapper mapper = getJaxbMapper(); ListBean input = new ListBean(new Whale("bluey", 150), new Buffalo("Bob", "black") ); String str = mapper.writeValueAsString(input); // Let's assume it's ok, and try deserialize right away: ListBean result = mapper.readValue(str, ListBean.class); assertEquals(2, result.animals.size()); Animal a1 = result.animals.get(0); assertNotNull(a1); assertEquals(Whale.class, a1.getClass()); assertEquals("bluey", a1.nickname); assertEquals(150, ((Whale)a1).weightInTons); Animal a2 = result.animals.get(1); assertNotNull(a2); assertEquals(Buffalo.class, a2.getClass()); assertEquals("Bob", a2.nickname); assertEquals("black", ((Buffalo) a2).hairColor); } /** * And then a test for collection types using element ref(s) */ public void testPolymorphicListElementRef() throws Exception { ObjectMapper mapper = getJaxbMapper(); ListBean input = new ListBean(); input.otherAnimals = Arrays.asList( new Cow("bluey", 150), new Emu("Bob", "black") ); String str = mapper.writeValueAsString(input); // Let's assume it's ok, and try deserialize right away: ListBean result = mapper.readValue(str, ListBean.class); assertEquals(2, result.otherAnimals.size()); Animal a1 = result.otherAnimals.get(0); assertNotNull(a1); assertEquals(Cow.class, a1.getClass()); assertEquals("bluey", a1.nickname); assertEquals(150, ((Cow)a1).weightInPounds); Animal a2 = result.otherAnimals.get(1); assertNotNull(a2); assertEquals(Emu.class, a2.getClass()); assertEquals("Bob", a2.nickname); assertEquals("black", ((Emu) a2).featherColor); } // [JACKSON-348] public void testShortList() throws Exception { ShortListHolder holder = getJaxbMapper().readValue("{\"id\":[1,2,3]}", ShortListHolder.class); assertNotNull(holder.ids); assertEquals(3, holder.ids.size()); assertSame(Short.valueOf((short)1), holder.ids.get(0)); assertSame(Short.valueOf((short)2), holder.ids.get(1)); assertSame(Short.valueOf((short)3), holder.ids.get(2)); } } TestJaxbPolymorphicMaps.java000066400000000000000000000057201314745633000460300ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; /** * Tests for handling of type-related JAXB annotations */ public class TestJaxbPolymorphicMaps extends PolymorpicTestBase { /* /********************************************************** /* Helper beans /********************************************************** */ static class MapBean { @XmlElements({ @XmlElement(type=Buffalo.class, name="beefalot"), @XmlElement(type=Whale.class, name="whale") }) public Map animals; @XmlElementRefs({ @XmlElementRef(type=Emu.class), @XmlElementRef(type=Cow.class) }) public Map otherAnimals; public MapBean() { animals = new HashMap(); otherAnimals = new HashMap(); } public void add(Integer key, Animal value) { animals.put(key, value); } public void addOther(Integer key, Animal value) { otherAnimals.put(key, value); } } /* /********************************************************** /* Tests /********************************************************** */ public void testPolymorphicMap() throws Exception { ObjectMapper mapper = getJaxbMapper(); Animal a = new Whale("Jaska", 3000); Animal b = new Whale("Arska", 2000); Animal c = new Whale("Pena", 1500); MapBean input = new MapBean(); input.add(1, a); input.add(2, b); input.add(3, c); String str = mapper.writer().withDefaultPrettyPrinter().writeValueAsString(input); MapBean result = mapper.readValue(str, MapBean.class); Map map = result.animals; assertEquals(3, map.size()); assertEquals("Jaska", ((Whale) map.get(Integer.valueOf(1))).nickname); assertEquals("Arska", ((Whale) map.get(Integer.valueOf(2))).nickname); assertEquals("Pena", ((Whale) map.get(Integer.valueOf(3))).nickname); } public void testPolymorphicMapElementRefs() throws Exception { ObjectMapper mapper = getJaxbMapper(); Animal a = new Cow("Jaska", 3000); Animal b = new Cow("Arska", 2000); Animal c = new Cow("Pena", 1500); MapBean input = new MapBean(); input.addOther(1, a); input.addOther(2, b); input.addOther(3, c); String str = mapper.writeValueAsString(input); MapBean result = mapper.readValue(str, MapBean.class); Map map = result.otherAnimals; assertEquals(3, map.size()); assertEquals("Jaska", ((Cow) map.get(Integer.valueOf(1))).nickname); assertEquals("Arska", ((Cow) map.get(Integer.valueOf(2))).nickname); assertEquals("Pena", ((Cow) map.get(Integer.valueOf(3))).nickname); } } TestJaxbTypeCoercion1023.java000066400000000000000000000024471314745633000456160ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import javax.xml.bind.annotation.XmlElement; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; // Failing temporarily due to [databind#1023] public class TestJaxbTypeCoercion1023 extends BaseJaxbTest { /* /********************************************************** /* Helper beans /********************************************************** */ /** * Unit test related to [JACKSON-416] */ static class Jackson416Bean { @XmlElement(type=Jackson416Base.class) public Jackson416Base value = new Jackson416Sub(); } static class Jackson416Base { public String foo = "foo"; } static class Jackson416Sub extends Jackson416Base { public String bar = "bar"; } /* /********************************************************** /* Unit tests /********************************************************** */ public void testIssue416() throws Exception { ObjectMapper mapper = getJaxbAndJacksonMapper(); Jackson416Bean bean = new Jackson416Bean(); String json = mapper.writeValueAsString(bean); assertEquals("{\"value\":{\"foo\":\"foo\"}}", json); } } TestJaxbTypes.java000066400000000000000000000166441314745633000440150ustar00rootroot00000000000000jackson-module-jaxb-annotations-jackson-module-jaxb-annotations-2.8.10/src/test/java/com/fasterxml/jackson/module/jaxb/typespackage com.fasterxml.jackson.module.jaxb.types; import java.util.*; import javax.xml.bind.annotation.*; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.module.jaxb.BaseJaxbTest; /** * Tests for handling of type-related JAXB annotations */ public class TestJaxbTypes extends BaseJaxbTest { static class AbstractWrapper { @XmlElement(type=BeanImpl.class) public AbstractBean wrapped; public AbstractWrapper() { this(null); } public AbstractWrapper(AbstractBean bean) { wrapped = bean; } } interface AbstractBean { } @JsonPropertyOrder({ "a", "b" }) static class BeanImpl implements AbstractBean { public int a; protected String b; public BeanImpl() { this(0, null); } public BeanImpl(int a, String b) { this.a = a; this.b = b; } public String getB() { return b; } public void setB(String b) { this.b = b; } } static class ListBean { /* Note: here we rely on implicit linking between the field * and accessors. */ @XmlElement(type=BeanImpl.class) protected List beans; public ListBean() { } public ListBean(AbstractBean ... beans) { this.beans = Arrays.asList(beans); } public ListBean(List beans) { this.beans = beans; } public List getBeans() { return beans; } public void setBeans(List b) { beans = b; } public int size() { return beans.size(); } public BeanImpl get(int index) { return (BeanImpl) beans.get(index); } } /* And then mix'n match, to try end-to-end */ static class ComboBean { protected AbstractBean bean; public ListBean beans; public ComboBean() { } public ComboBean(AbstractBean bean, ListBean beans) { this.bean = bean; this.beans = beans; } @XmlElement(type=BeanImpl.class) public AbstractBean getBean() { return bean; } public void setBean(AbstractBean bean) { this.bean = bean; } } /** * Unit test for [JACKSON-250] */ @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.PROPERTY) @JsonTypeName("Name") @XmlType static class P2 { String id; public P2(String id) { this.id = id; } public P2() { } @XmlID @XmlAttribute(name="id") public String getId() { return id; } public void setId(String id) { this.id = id; } } /* /********************************************************** /* Unit tests /********************************************************** */ public void testXmlElementTypeDeser() throws Exception { ObjectMapper mapper = getJaxbMapper(); AbstractWrapper wrapper = mapper.readValue("{\"wrapped\":{\"a\":13,\"b\":\"...\"}}", AbstractWrapper.class); assertNotNull(wrapper); BeanImpl bean = (BeanImpl) wrapper.wrapped; assertEquals(13, bean.a); assertEquals("...", bean.b); } public void testXmlElementTypeSer() throws Exception { ObjectMapper mapper = getJaxbAndJacksonMapper(); AbstractWrapper wrapper = new AbstractWrapper(new BeanImpl(-3, "c")); assertEquals("{\"wrapped\":{\"a\":-3,\"b\":\"c\"}}", mapper.writeValueAsString(wrapper)); } public void testXmlElementListTypeDeser() throws Exception { ObjectMapper mapper = getJaxbMapper(); ListBean listBean = mapper.readValue ("{\"beans\": [{\"a\":1,\"b\":\"a\"}, {\"a\":7,\"b\":\"b\" }]}", ListBean.class); assertNotNull(listBean); List beans = listBean.beans; assertNotNull(beans); assertEquals(2, beans.size()); assertNotNull(beans.get(0)); assertNotNull(beans.get(1)); BeanImpl bean = (BeanImpl) beans.get(0); assertEquals(1, bean.a); assertEquals("a", bean.b); bean = (BeanImpl) beans.get(1); assertEquals(7, bean.a); assertEquals("b", bean.b); } public void testXmlElementListArrayDeser() throws Exception { ObjectMapper mapper = getJaxbMapper(); ListBean[] listBeans = mapper.readValue ("[{\"beans\": [{\"a\":1,\"b\":\"a\"}, {\"a\":7,\"b\":\"b\" }]}]", ListBean[].class); assertNotNull(listBeans); assertEquals(1, listBeans.length); List beans = listBeans[0].beans; assertNotNull(beans); assertEquals(2, beans.size()); BeanImpl bean = (BeanImpl) beans.get(0); assertEquals(1, bean.a); assertEquals("a", bean.b); bean = (BeanImpl) beans.get(1); assertEquals(7, bean.a); assertEquals("b", bean.b); } public void testXmlElementListTypeSer() throws Exception { // important: Jackson mapper so we can force ordering ObjectMapper mapper = getJaxbAndJacksonMapper(); ListBean bean = new ListBean(); List beans = new ArrayList(); beans.add(new BeanImpl(1, "a")); beans.add(new BeanImpl(2, "b")); bean.beans = beans; assertEquals("{\"beans\":[{\"a\":1,\"b\":\"a\"},{\"a\":2,\"b\":\"b\"}]}", mapper.writeValueAsString(bean)); } public void testRoundTrip() throws Exception { ComboBean input = new ComboBean(new BeanImpl(3, "abc"), new ListBean(new BeanImpl(1, "a"), new BeanImpl(2, "b"), new BeanImpl(3, "c"))); ObjectMapper mapper = getJaxbMapper(); String str = mapper.writeValueAsString(input); ComboBean result = mapper.readValue(str, ComboBean.class); assertEquals(3, ((BeanImpl)result.bean).a); assertEquals("abc", ((BeanImpl)result.bean).b); assertEquals(3, result.beans.size()); assertEquals(1, (result.beans.get(0)).a); assertEquals("a", (result.beans.get(0)).b); assertEquals(2, (result.beans.get(1)).a); assertEquals("b", (result.beans.get(1)).b); assertEquals(3, (result.beans.get(2)).a); assertEquals("c", (result.beans.get(2)).b); } public void testListWithDefaultTyping() throws Exception { Object input = new ListBean(new BeanImpl(1, "a")); ObjectMapper mapper = getJaxbMapper(); mapper.enableDefaultTyping(); String str = mapper.writeValueAsString(input); ListBean listBean = mapper.readValue(str, ListBean.class); assertNotNull(listBean); List beans = listBean.beans; assertNotNull(beans); assertEquals(1, beans.size()); assertNotNull(beans.get(0)); BeanImpl bean = (BeanImpl) beans.get(0); assertEquals(1, bean.a); assertEquals("a", bean.b); } public void testIssue250() throws Exception { ObjectMapper mapper = getJaxbAndJacksonMapper(); P2 bean = new P2("myId"); String str = mapper.writeValueAsString(bean); assertEquals("{\"@type\":\"Name\",\"id\":\"myId\"}", str); } }