1 package com.fasterxml.jackson.dataformat.xml.deser;
2
3 import java.io.IOException;
4
5 import com.fasterxml.jackson.core.*;
6 import com.fasterxml.jackson.databind.*;
7 import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
8 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
9
10 /**
11  * Custom variant used instead of "plain" {@code StringDeserializer} to handle
12  * couple of edge cases that XML parser exposes.
13  *<p>
14  * NOTE: mostly copy-pasted from standard {@code StringDeserializer}
15  *
16  * @since 2.9.4
17  */

18 public class XmlStringDeserializer
19     extends StdScalarDeserializer<String>
20 {
21     private static final long serialVersionUID = 1L;
22
23     public XmlStringDeserializer() { super(String.class); }
24
25     @Override
26     public boolean isCachable() { return true; }
27
28     @Override
29     public Object getEmptyValue(DeserializationContext ctxt) throws JsonMappingException {
30         return "";
31     }
32
33     @Override
34     public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
35     {
36         if (p.hasToken(JsonToken.VALUE_STRING)) {
37             return p.getText();
38         }
39         JsonToken t = p.getCurrentToken();
40         if (t == JsonToken.START_ARRAY) {
41             return _deserializeFromArray(p, ctxt);
42         }
43         if (t == JsonToken.VALUE_EMBEDDED_OBJECT) {
44             Object ob = p.getEmbeddedObject();
45             if (ob == null) {
46                 return null;
47             }
48             if (ob instanceof byte[]) {
49                 return ctxt.getBase64Variant().encode((byte[]) ob, false);
50             }
51             // otherwise, try conversion using toString()...
52             return ob.toString();
53         }
54         // allow coercions, as handled by `FromXmlParser.getValueAsString()`: this includes
55         // START_OBJECT in some cases.
56         String text = p.getValueAsString(null);
57         if ((text != null) || (t == JsonToken.VALUE_NULL)) {
58             return text;
59         }
60         return (String) ctxt.handleUnexpectedToken(_valueClass, p);
61     }
62
63     // Since we can never have type info ("natural type"; String, Boolean, Integer, Double):
64     // (is it an error to even call this version?)
65     @Override
66     public String deserializeWithType(JsonParser p, DeserializationContext ctxt,
67             TypeDeserializer typeDeserializer) throws IOException {
68         return deserialize(p, ctxt);
69     }
70 }
71