1 package com.fasterxml.jackson.databind.ser.impl;
2
3 import java.io.IOException;
4 import java.util.*;
5
6 import com.fasterxml.jackson.core.*;
7 import com.fasterxml.jackson.core.type.WritableTypeId;
8 import com.fasterxml.jackson.databind.*;
9 import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
10 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
11 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes;
12 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
13 import com.fasterxml.jackson.databind.ser.std.StaticListSerializerBase;
14
15 /**
16  * Efficient implement for serializing {@link Collection}s that contain Strings.
17  * The only complexity is due to possibility that serializer for {@link String}
18  * may be overridde; because of this, logic is needed to ensure that the default
19  * serializer is in use to use fastest mode, or if not, to defer to custom
20  * String serializer.
21  */

22 @JacksonStdImpl
23 @SuppressWarnings("serial")
24 public class StringCollectionSerializer
25     extends StaticListSerializerBase<Collection<String>>
26 {
27     public final static StringCollectionSerializer instance = new StringCollectionSerializer();
28
29     /*
30     /**********************************************************
31     /* Life-cycle
32     /**********************************************************
33      */

34     
35     protected StringCollectionSerializer() {
36         super(Collection.class);
37     }
38
39     protected StringCollectionSerializer(StringCollectionSerializer src,
40             Boolean unwrapSingle)
41     {
42         super(src, unwrapSingle);
43     }        
44
45     @Override
46     public JsonSerializer<?> _withResolved(BeanProperty prop, Boolean unwrapSingle) {
47         return new StringCollectionSerializer(this, unwrapSingle);
48     }
49
50     @Override protected JsonNode contentSchema() {
51         return createSchemaNode("string"true);
52     }
53     
54     @Override
55     protected void acceptContentVisitor(JsonArrayFormatVisitor visitor) throws JsonMappingException
56     {
57         visitor.itemsFormat(JsonFormatTypes.STRING);
58     }
59
60     /*
61     /**********************************************************
62     /* Actual serialization
63     /**********************************************************
64      */

65     
66     @Override
67     public void serialize(Collection<String> value, JsonGenerator g,
68             SerializerProvider provider) throws IOException
69     {
70         final int len = value.size();
71         if (len == 1) {
72             if (((_unwrapSingle == null) &&
73                     provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED))
74                     || (_unwrapSingle == Boolean.TRUE)) {
75                 serializeContents(value, g, provider);
76                 return;
77             }
78         }
79         g.writeStartArray(value, len);
80         serializeContents(value, g, provider);
81         g.writeEndArray();
82     }
83
84     @Override
85     public void serializeWithType(Collection<String> value, JsonGenerator g,
86             SerializerProvider provider, TypeSerializer typeSer)
87         throws IOException
88     {
89         WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
90                 typeSer.typeId(value, JsonToken.START_ARRAY));
91         g.setCurrentValue(value);
92         serializeContents(value, g, provider);
93         typeSer.writeTypeSuffix(g, typeIdDef);
94     }
95
96     private final void serializeContents(Collection<String> value, JsonGenerator g,
97             SerializerProvider provider)
98         throws IOException
99     {
100         int i = 0;
101
102         try {
103             for (String str : value) {
104                 if (str == null) {
105                     provider.defaultSerializeNull(g);
106                 } else {
107                     g.writeString(str);
108                 }
109                 ++i;
110             }
111         } catch (Exception e) {
112             wrapAndThrow(provider, e, value, i);
113         }
114     }
115 }
116