1 package com.fasterxml.jackson.dataformat.xml;
2
3 import com.fasterxml.jackson.databind.AnnotationIntrospector;
4 import com.fasterxml.jackson.databind.module.SimpleModule;
5 import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
6 import com.fasterxml.jackson.dataformat.xml.deser.XmlBeanDeserializerModifier;
7 import com.fasterxml.jackson.dataformat.xml.deser.XmlStringDeserializer;
8 import com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializerModifier;
9
10 /**
11  * Module that implements most functionality needed to support producing and
12  * consuming XML instead of JSON.
13  */

14 public class JacksonXmlModule
15     extends SimpleModule
16     implements java.io.Serializable
17 {
18     private static final long serialVersionUID = 1L;
19
20     /**
21      * Determination of whether indexed properties (arrays, Lists) that are not explicitly
22      * annotated (with {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper}
23      * or equivalent) should default to using implicit wrapper (with same name as property) or not.
24      * If enabled, wrapping is used by defaultif false, it is not.
25      *<p>
26      * Note that JAXB annotation introspector always assumes "do not wrap by default".
27      * Jackson annotations have different default due to backwards compatibility.
28      * 
29      * @since 2.1
30      */

31     protected boolean _cfgDefaultUseWrapper = JacksonXmlAnnotationIntrospector.DEFAULT_USE_WRAPPER;
32
33     /**
34      * Name used for pseudo-property used for returning XML Text value (which does
35      * not have actual element name to use). Defaults to empty String, but
36      * may be changed for interoperability reasons: JAXB, for example, uses
37      * "value" as name.
38      * 
39      * @since 2.1
40      */

41     protected String _cfgNameForTextElement = FromXmlParser.DEFAULT_UNNAMED_TEXT_PROPERTY;
42     
43     /*
44     /**********************************************************************
45     /* Life-cycle: construction
46     /**********************************************************************
47      */

48     
49     public JacksonXmlModule()
50     {
51         super("JacksonXmlModule", PackageVersion.VERSION);
52         XmlStringDeserializer deser = new XmlStringDeserializer();
53         addDeserializer(String.class, deser);
54         addDeserializer(CharSequence.class, deser);
55     }
56
57     @SuppressWarnings("deprecation")
58     @Override
59     public void setupModule(SetupContext context)
60     {
61         // Need to modify BeanDeserializer, BeanSerializer that are used
62         context.addBeanSerializerModifier(new XmlBeanSerializerModifier());
63         context.addBeanDeserializerModifier(new XmlBeanDeserializerModifier(_cfgNameForTextElement));
64
65         // as well as AnnotationIntrospector
66         context.insertAnnotationIntrospector(_constructIntrospector());
67
68         // and finally inform XmlFactory about overrides, if need be:
69         if (_cfgNameForTextElement != FromXmlParser.DEFAULT_UNNAMED_TEXT_PROPERTY) {
70             XmlMapper m = (XmlMapper) context.getOwner();
71             m.setXMLTextElementName(_cfgNameForTextElement);
72         }
73
74         // Usually this would be the first call; but here anything added will
75         // be stuff user may has added, so do it afterwards instead.
76         super.setupModule(context);
77     }    
78
79     /*
80     /**********************************************************************
81     /* Life-cycle: configuration
82     /**********************************************************************
83      */

84
85     /**
86      * Method that can be used to define whether {@link AnnotationIntrospector}
87      * we register will use wrapper for indexed (List, array) properties or not,
88      * if there are no explicit annotations.
89      * See {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper}
90      * for details.
91      *<p>
92      * Note that method MUST be called before registering the module; otherwise change
93      * will not have any effect.
94      * 
95      * @param state Whether to enable or disable "use wrapper for non-annotated List properties"
96      * 
97      * @since 2.1
98      */

99     public void setDefaultUseWrapper(boolean state) {
100         _cfgDefaultUseWrapper = state;
101     }
102
103     /**
104      * Method that can be used to define alternate "virtual name" to use
105      * for XML CDATA segments; that is, text values. Default name is empty String
106      * (""); but some frameworks use other names: JAXB, for example, uses
107      * "value".
108      *<p>
109      * Note that method MUST be called before registering the module; otherwise change
110      * will not have any effect.
111      * 
112      * @param name Virtual name to use when exposing XML character data sections
113      * 
114      * @since 2.1
115      */

116     public void setXMLTextElementName(String name) {
117         _cfgNameForTextElement = name;
118     }
119     
120     /*
121     /**********************************************************************
122     /* Internal methods
123     /**********************************************************************
124      */

125
126     protected AnnotationIntrospector _constructIntrospector() {
127         return new JacksonXmlAnnotationIntrospector(_cfgDefaultUseWrapper);
128     }
129 }
130