Skip to content

Commit

Permalink
Minor fix related to #18
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Dec 16, 2020
1 parent 1c3565e commit 3ad3995
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 15 deletions.
1 change: 1 addition & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Project: jackson-dataformat-xml

#435: After upgrade to 2.12.0, NPE when deserializing an empty element to `ArrayList`
(reported by Francesco C)
- Minor improvement wrt #18 (use namespace annotation from supertype)

2.12.0 (29-Nov-2020)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,15 @@ protected QName _rootNameFromConfig()
protected ToXmlGenerator _asXmlGenerator(JsonGenerator gen)
throws JsonMappingException
{
// [dataformat-xml#71]: When converting, we actually get TokenBuffer, which is fine
if (!(gen instanceof ToXmlGenerator)) {
// but verify
if (!(gen instanceof TokenBuffer)) {
throw JsonMappingException.from(gen,
"XmlMapper does not with generators of type other than ToXmlGenerator; got: "+gen.getClass().getName());
// [dataformat-xml#71]: We sometimes get TokenBuffer, which is fine
if (gen instanceof TokenBuffer) {
return null;
}
return null;
// but verify
throw JsonMappingException.from(gen,
"XmlMapper does not work with generators of type other than `ToXmlGenerator`; got: `"
+gen.getClass().getName()+"`");
}
return (ToXmlGenerator) gen;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class XmlRootNameLookup
protected final transient LRUMap<ClassKey,QName> _rootNames = new LRUMap<ClassKey,QName>(40, 200);

public XmlRootNameLookup() { }

protected Object readResolve() {
// just need to make 100% sure it gets set to non-null, that's all
if (_rootNames == null) {
Expand Down Expand Up @@ -63,9 +63,7 @@ public QName findRootName(Class<?> rootType, MapperConfig<?> config)
}
return name;
}

// NOTE: needed to be synchronized in 2.6.4, but 2.7.0 adds a proper fix
// for annotation introspection hence not needed any more

protected QName _findRootName(Class<?> rootType, MapperConfig<?> config)
{
BeanDescription beanDesc = config.introspectClassAnnotations(rootType);
Expand All @@ -84,19 +82,23 @@ protected QName _findRootName(Class<?> rootType, MapperConfig<?> config)
// Should we strip out enclosing class tho? For now, nope:
// one caveat: array simple names end with "[]"; also, "$" needs replacing
localName = StaxUtil.sanitizeXmlTypeName(rootType.getSimpleName());
return new QName("", localName);
return _qname(ns, localName);
}
// Otherwise let's see if there's namespace, too (if we are missing it)
if (ns == null || ns.length() == 0) {
ns = findNamespace(intr, ac);
if (ns == null || ns.isEmpty()) {
ns = _findNamespace(intr, ac);
}
return _qname(ns, localName);
}

private QName _qname(String ns, String localName) {
if (ns == null) { // some QName impls barf on nulls...
ns = "";
}
return new QName(ns, localName);
}

private String findNamespace(AnnotationIntrospector ai, AnnotatedClass ann)
private String _findNamespace(AnnotationIntrospector ai, AnnotatedClass ann)
{
for (AnnotationIntrospector intr : ai.allIntrospectors()) {
if (intr instanceof XmlAnnotationIntrospector) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.fasterxml.jackson.dataformat.xml.jaxb;

import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.XmlTestBase;

import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

public class NamespaceViaJAXB18Test extends XmlTestBase
{
final static String TEST_NAMESPACE = "http://namespace-base";

@XmlRootElement(namespace = TEST_NAMESPACE)
interface Facility { }

static class House implements Facility {
@XmlAttribute
public String getName() { return "Bob"; }
}

@XmlRootElement(namespace = "", name = "Houzz")
static class HouseWithNoNamespace implements Facility {
@XmlAttribute
public String getName() { return "Bill"; }
}

// Also: for better or worse, cannot only override local name so:
@XmlRootElement(name = "Houzz2")
static class HouseWithNoNamespace2 implements Facility {
@XmlAttribute
public String getName() { return "Frank"; }
}

private final XmlMapper MAPPER = mapperBuilder()
.annotationIntrospector(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()))
.build();

// [dataformat-xml#18]
public void testNamespaceViaJAXB() throws Exception
{
String xml = MAPPER.writeValueAsString(new House());
if (!xml.contains("<House xmlns")
|| !xml.contains(TEST_NAMESPACE)) {
fail("Expected `xmlns` declaration for element `House`, none seen: XML = "+xml);
}

// But should be able to mask it...
xml = MAPPER.writeValueAsString(new HouseWithNoNamespace());
if (!xml.contains("<Houzz")
|| xml.contains("xmlns")) {
fail("Expected NO `xmlns` declaration for element `Houzz` but got XML = "+xml);
}

xml = MAPPER.writeValueAsString(new HouseWithNoNamespace2());
if (!xml.contains("<Houzz2")
|| xml.contains("xmlns")) {
fail("Expected NO `xmlns` declaration for element `Houzz2` but got XML = "+xml);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void setLastName(final String lastName) {
this.lastName = lastName;
}
}

/*
/**********************************************************************
/* Set up
Expand Down

0 comments on commit 3ad3995

Please sign in to comment.