1 package com.fasterxml.jackson.dataformat.xml.util;
2
3 import javax.xml.namespace.QName;
4
5 import com.fasterxml.jackson.databind.*;
6 import com.fasterxml.jackson.databind.cfg.MapperConfig;
7 import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
8 import com.fasterxml.jackson.databind.type.ClassKey;
9 import com.fasterxml.jackson.databind.util.LRUMap;
10 import com.fasterxml.jackson.dataformat.xml.XmlAnnotationIntrospector;
11
12
16 public class XmlRootNameLookup
17 implements java.io.Serializable
18 {
19 private static final long serialVersionUID = 1L;
20
21
28 protected final transient LRUMap<ClassKey,QName> _rootNames = new LRUMap<ClassKey,QName>(40, 200);
29
30 public XmlRootNameLookup() { }
31
32 protected Object readResolve() {
33
34 if (_rootNames == null) {
35 return new XmlRootNameLookup();
36 }
37 return this;
38 }
39
40 public QName findRootName(JavaType rootType, MapperConfig<?> config) {
41 return findRootName(rootType.getRawClass(), config);
42 }
43
44 public QName findRootName(Class<?> rootType, MapperConfig<?> config)
45 {
46 ClassKey key = new ClassKey(rootType);
47 QName name;
48 synchronized (_rootNames) {
49 name = _rootNames.get(key);
50 }
51 if (name != null) {
52 return name;
53 }
54 name = _findRootName(rootType, config);
55 synchronized (_rootNames) {
56 _rootNames.put(key, name);
57 }
58 return name;
59 }
60
61
62
63 protected QName _findRootName(Class<?> rootType, MapperConfig<?> config)
64 {
65 BeanDescription beanDesc = config.introspectClassAnnotations(rootType);
66 AnnotationIntrospector intr = config.getAnnotationIntrospector();
67 AnnotatedClass ac = beanDesc.getClassInfo();
68 String localName = null;
69 String ns = null;
70
71 PropertyName root = intr.findRootName(ac);
72 if (root != null) {
73 localName = root.getSimpleName();
74 ns = root.getNamespace();
75 }
76
77 if (localName == null || localName.length() == 0) {
78
79
80 localName = StaxUtil.sanitizeXmlTypeName(rootType.getSimpleName());
81 return new QName("", localName);
82 }
83
84 if (ns == null || ns.length() == 0) {
85 ns = findNamespace(intr, ac);
86 }
87 if (ns == null) {
88 ns = "";
89 }
90 return new QName(ns, localName);
91 }
92
93 private String findNamespace(AnnotationIntrospector ai, AnnotatedClass ann)
94 {
95 for (AnnotationIntrospector intr : ai.allIntrospectors()) {
96 if (intr instanceof XmlAnnotationIntrospector) {
97 String ns = ((XmlAnnotationIntrospector) intr).findNamespace(ann);
98 if (ns != null) {
99 return ns;
100 }
101 }
102 }
103 return null;
104 }
105 }
106