##### Coverage Report - org.yaml.snakeyaml.representer.SafeRepresenter

Classes in this File | Line Coverage | Branch Coverage | Complexity
SafeRepresenter |
96% | 24/25
100% | 4/4
| 2.5555555555555554;2.556
SafeRepresenter$IteratorWrapper |
100% | 4/4
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentArray |
100% | 4/4
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentBoolean |
100% | 5/5
100% | 2/2
| 2.5555555555555554;2.556
SafeRepresenter$RepresentByteArray |
100% | 3/3
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentDate |
100% | 50/50
100% | 26/26
| 2.5555555555555554;2.556
SafeRepresenter$RepresentEnum |
100% | 3/3
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentIterator |
100% | 3/3
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentList |
100% | 2/2
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentMap |
100% | 2/2
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentNull |
100% | 2/2
N/A | N/A
| 2.5555555555555554;2.556
SafeRepresenter$RepresentNumber |
100% | 14/14
100% | 16/16
| 2.5555555555555554;2.556
SafeRepresenter$RepresentSet |
100% | 6/6
100% | 2/2
| 2.5555555555555554;2.556
SafeRepresenter$RepresentString |
100% | 10/10
100% | 2/2
| 2.5555555555555554;2.556

1 |  |
     /**
2 |  |
      * Copyright (c) 2008-2011, http://www.snakeyaml.org
3 |  |
      *
4 |  |
      * Licensed under the Apache License, Version 2.0 (the "License");
5 |  |
      * you may not use this file except in compliance with the License.
6 |  |
      * You may obtain a copy of the License at
7 |  |
      *
8 |  |
      *     http://www.apache.org/licenses/LICENSE-2.0
9 |  |
      *
10 |  |
      * Unless required by applicable law or agreed to in writing, software
11 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
12 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  |
      * See the License for the specific language governing permissions and
14 |  |
      * limitations under the License.
15 |  |
      */
16 |  |
17 |  |
     package org.yaml.snakeyaml.representer;
18 |  |
19 |  |
     import java.math.BigInteger;
20 |  |
     import java.util.Arrays;
21 |  |
     import java.util.Calendar;
22 |  |
     import java.util.Date;
23 |  |
     import java.util.HashMap;
24 |  |
     import java.util.Iterator;
25 |  |
     import java.util.LinkedHashMap;
26 |  |
     import java.util.List;
27 |  |
     import java.util.Map;
28 |  |
     import java.util.Set;
29 |  |
     import java.util.TimeZone;
30 |  |
     import java.util.regex.Pattern;
31 |  |
32 |  |
     import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
33 |  |
     import org.yaml.snakeyaml.nodes.Node;
34 |  |
     import org.yaml.snakeyaml.nodes.Tag;
35 |  |
36 |  |
     /**
37 |  |
      * Represent standard Java classes
38 |  |
      */
39 |  |
     class SafeRepresenter extends BaseRepresenter {
40 |  |
41 |  |
         protected Map<Class<? extends Object>, Tag> classTags;
42 |  |
43 | 3965 |
         public SafeRepresenter() {
44 | 3965 |
             this.nullRepresenter = new RepresentNull();
45 | 3965 |
             this.representers.put(String.class, new RepresentString());
46 | 3965 |
             this.representers.put(Boolean.class, new RepresentBoolean());
47 | 3965 |
             this.representers.put(Character.class, new RepresentString());
48 | 3965 |
             this.representers.put(byte[].class, new RepresentByteArray());
49 | 3965 |
             this.multiRepresenters.put(Number.class, new RepresentNumber());
50 | 3965 |
             this.multiRepresenters.put(List.class, new RepresentList());
51 | 3965 |
             this.multiRepresenters.put(Map.class, new RepresentMap());
52 | 3965 |
             this.multiRepresenters.put(Set.class, new RepresentSet());
53 | 3965 |
             this.multiRepresenters.put(Iterator.class, new RepresentIterator());
54 | 3965 |
             this.multiRepresenters.put(new Object[0].getClass(), new RepresentArray());
55 | 3965 |
             this.multiRepresenters.put(Date.class, new RepresentDate());
56 | 3965 |
             this.multiRepresenters.put(Enum.class, new RepresentEnum());
57 | 3965 |
             this.multiRepresenters.put(Calendar.class, new RepresentDate());
58 | 3965 |
             classTags = new HashMap<Class<? extends Object>, Tag>();
59 | 3965 |
         }
60 |  |
61 |  |
         protected Tag getTag(Class<?> clazz, Tag defaultTag) {
62 | 170082 |
             if (classTags.containsKey(clazz)) {
63 | 1 |
                 return classTags.get(clazz);
64 |  |
             } else {
65 | 170081 |
                 return defaultTag;
66 |  |
             }
67 |  |
         }
68 |  |
69 |  |
         /**
70 |  |
          * Define a tag for the <code>Class</code> to serialize
71 |  |
          *
72 |  |
          * @deprecated use Tag instead of String
73 |  |
          * @param clazz
74 |  |
          *            <code>Class</code> which tag is changed
75 |  |
          * @param tag
76 |  |
          *            new tag to be used for every instance of the specified
77 |  |
          *            <code>Class</code>
78 |  |
          * @return the previous tag associated with the <code>Class</code>
79 |  |
          */
80 |  |
         public Tag addClassTag(Class<? extends Object> clazz, String tag) {
81 | 0 |
             return addClassTag(clazz, new Tag(tag));
82 |  |
         }
83 |  |
84 |  |
         /**
85 |  |
          * Define a tag for the <code>Class</code> to serialize.
86 |  |
          *
87 |  |
          * @param clazz
88 |  |
          *            <code>Class</code> which tag is changed
89 |  |
          * @param tag
90 |  |
          *            new tag to be used for every instance of the specified
91 |  |
          *            <code>Class</code>
92 |  |
          * @return the previous tag associated with the <code>Class</code>
93 |  |
          */
94 |  |
         public Tag addClassTag(Class<? extends Object> clazz, Tag tag) {
95 | 16 |
             if (tag == null) {
96 | 1 |
                 throw new NullPointerException("Tag must be provided.");
97 |  |
             }
98 | 15 |
             return classTags.put(clazz, tag);
99 |  |
         }
100 |  |
101 | 3965 |
         protected class RepresentNull implements Represent {
102 |  |
             public Node representData(Object data) {
103 | 177 |
                 return representScalar(Tag.NULL, "null");
104 |  |
             }
105 |  |
         }
106 |  |
107 | 1 |
         public static Pattern BINARY_PATTERN = Pattern.compile("[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]");
108 |  |
109 | 7930 |
         protected class RepresentString implements Represent {
110 |  |
             public Node representData(Object data) {
111 | 453089 |
                 Tag tag = Tag.STR;
112 | 453089 |
                 Character style = null;
113 | 453089 |
                 String value = data.toString();
114 | 453089 |
                 if (BINARY_PATTERN.matcher(value).find()) {
115 | 3 |
                     tag = Tag.BINARY;
116 |  |
                     char[] binary;
117 | 3 |
                     binary = Base64Coder.encode(value.getBytes());
118 | 3 |
                     value = String.valueOf(binary);
119 | 3 |
                     style = '|';
120 |  |
                 }
121 | 453089 |
                 return representScalar(tag, value, style);
122 |  |
             }
123 |  |
         }
124 |  |
125 | 3965 |
         protected class RepresentBoolean implements Represent {
126 |  |
             public Node representData(Object data) {
127 |  |
                 String value;
128 | 16 |
                 if (Boolean.TRUE.equals(data)) {
129 | 12 |
                     value = "true";
130 |  |
                 } else {
131 | 4 |
                     value = "false";
132 |  |
                 }
133 | 16 |
                 return representScalar(Tag.BOOL, value);
134 |  |
             }
135 |  |
         }
136 |  |
137 | 3965 |
         protected class RepresentNumber implements Represent {
138 |  |
             public Node representData(Object data) {
139 |  |
                 Tag tag;
140 |  |
                 String value;
141 | 143589 |
                 if (data instanceof Byte || data instanceof Short || data instanceof Integer
142 |  |
                         || data instanceof Long || data instanceof BigInteger) {
143 | 119543 |
                     tag = Tag.INT;
144 | 119543 |
                     value = data.toString();
145 |  |
                 } else {
146 | 24046 |
                     Number number = (Number) data;
147 | 24046 |
                     tag = Tag.FLOAT;
148 | 24046 |
                     if (number.equals(Double.NaN)) {
149 | 2 |
                         value = ".NaN";
150 | 24044 |
                     } else if (number.equals(Double.POSITIVE_INFINITY)) {
151 | 1 |
                         value = ".inf";
152 | 24043 |
                     } else if (number.equals(Double.NEGATIVE_INFINITY)) {
153 | 2 |
                         value = "-.inf";
154 |  |
                     } else {
155 | 24041 |
                         value = number.toString();
156 |  |
                     }
157 |  |
                 }
158 | 143589 |
                 return representScalar(getTag(data.getClass(), tag), value);
159 |  |
             }
160 |  |
         }
161 |  |
162 | 3965 |
         protected class RepresentList implements Represent {
163 |  |
             @SuppressWarnings("unchecked")
164 |  |
             public Node representData(Object data) {
165 | 16171 |
                 return representSequence(getTag(data.getClass(), Tag.SEQ), (List<Object>) data, null);
166 |  |
             }
167 |  |
         }
168 |  |
169 | 3965 |
         protected class RepresentIterator implements Represent {
170 |  |
             @SuppressWarnings("unchecked")
171 |  |
             public Node representData(Object data) {
172 | 1 |
                 Iterator<Object> iter = (Iterator<Object>) data;
173 | 1 |
                 return representSequence(getTag(data.getClass(), Tag.SEQ), new IteratorWrapper(iter),
174 |  |
                         null);
175 |  |
             }
176 |  |
         }
177 |  |
178 |  |
         private class IteratorWrapper implements Iterable<Object> {
179 |  |
             private Iterator<Object> iter;
180 |  |
181 | 1 |
             public IteratorWrapper(Iterator<Object> iter) {
182 | 1 |
                 this.iter = iter;
183 | 1 |
             }
184 |  |
185 |  |
             public Iterator<Object> iterator() {
186 | 1 |
                 return iter;
187 |  |
             }
188 |  |
         }
189 |  |
190 | 3965 |
         protected class RepresentArray implements Represent {
191 |  |
             public Node representData(Object data) {
192 | 38 |
                 Object[] array = (Object[]) data;
193 | 38 |
                 List<Object> list = Arrays.asList(array);
194 | 38 |
                 return representSequence(Tag.SEQ, list, null);
195 |  |
             }
196 |  |
         }
197 |  |
198 | 3965 |
         protected class RepresentMap implements Represent {
199 |  |
             @SuppressWarnings("unchecked")
200 |  |
             public Node representData(Object data) {
201 | 10163 |
                 return representMapping(getTag(data.getClass(), Tag.MAP), (Map<Object, Object>) data,
202 |  |
                         null);
203 |  |
             }
204 |  |
         }
205 |  |
206 | 3965 |
         protected class RepresentSet implements Represent {
207 |  |
             @SuppressWarnings("unchecked")
208 |  |
             public Node representData(Object data) {
209 | 34 |
                 Map<Object, Object> value = new LinkedHashMap<Object, Object>();
210 | 34 |
                 Set<Object> set = (Set<Object>) data;
211 | 34 |
                 for (Object key : set) {
212 | 51 |
                     value.put(key, null);
213 |  |
                 }
214 | 32 |
                 return representMapping(getTag(data.getClass(), Tag.SET), value, null);
215 |  |
             }
216 |  |
         }
217 |  |
218 | 7934 |
         protected class RepresentDate implements Represent {
219 |  |
             public Node representData(Object data) {
220 |  |
                 // because SimpleDateFormat ignores timezone we have to use Calendar
221 |  |
                 Calendar calendar;
222 | 83 |
                 if (data instanceof Calendar) {
223 | 5 |
                     calendar = (Calendar) data;
224 |  |
                 } else {
225 | 78 |
                     calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
226 | 78 |
                     calendar.setTime((Date) data);
227 |  |
                 }
228 | 83 |
                 int years = calendar.get(Calendar.YEAR);
229 | 83 |
                 int months = calendar.get(Calendar.MONTH) + 1; // 0..12
230 | 83 |
                 int days = calendar.get(Calendar.DAY_OF_MONTH); // 1..31
231 | 83 |
                 int hour24 = calendar.get(Calendar.HOUR_OF_DAY); // 0..24
232 | 83 |
                 int minutes = calendar.get(Calendar.MINUTE); // 0..59
233 | 83 |
                 int seconds = calendar.get(Calendar.SECOND); // 0..59
234 | 83 |
                 int millis = calendar.get(Calendar.MILLISECOND);
235 | 83 |
                 StringBuilder buffer = new StringBuilder(String.valueOf(years));
236 | 86 |
                 while (buffer.length() < 4) {
237 |  |
                     // ancient years
238 | 3 |
                     buffer.insert(0, "0");
239 |  |
                 }
240 | 83 |
                 buffer.append("-");
241 | 83 |
                 if (months < 10) {
242 | 60 |
                     buffer.append("0");
243 |  |
                 }
244 | 83 |
                 buffer.append(String.valueOf(months));
245 | 83 |
                 buffer.append("-");
246 | 83 |
                 if (days < 10) {
247 | 23 |
                     buffer.append("0");
248 |  |
                 }
249 | 83 |
                 buffer.append(String.valueOf(days));
250 | 83 |
                 buffer.append("T");
251 | 83 |
                 if (hour24 < 10) {
252 | 42 |
                     buffer.append("0");
253 |  |
                 }
254 | 83 |
                 buffer.append(String.valueOf(hour24));
255 | 83 |
                 buffer.append(":");
256 | 83 |
                 if (minutes < 10) {
257 | 28 |
                     buffer.append("0");
258 |  |
                 }
259 | 83 |
                 buffer.append(String.valueOf(minutes));
260 | 83 |
                 buffer.append(":");
261 | 83 |
                 if (seconds < 10) {
262 | 30 |
                     buffer.append("0");
263 |  |
                 }
264 | 83 |
                 buffer.append(String.valueOf(seconds));
265 | 83 |
                 if (millis > 0) {
266 | 19 |
                     if (millis < 10) {
267 | 1 |
                         buffer.append(".00");
268 | 18 |
                     } else if (millis < 100) {
269 | 6 |
                         buffer.append(".0");
270 |  |
                     } else {
271 | 12 |
                         buffer.append(".");
272 |  |
                     }
273 | 19 |
                     buffer.append(String.valueOf(millis));
274 |  |
                 }
275 | 83 |
                 if (TimeZone.getTimeZone("UTC").equals(calendar.getTimeZone())) {
276 | 78 |
                     buffer.append("Z");
277 |  |
                 } else {
278 |  |
                     // Get the Offset from GMT taking DST into account
279 | 5 |
                     int gmtOffset = calendar.getTimeZone().getOffset(calendar.get(Calendar.ERA),
280 |  |
                             calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
281 |  |
                             calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK),
282 |  |
                             calendar.get(Calendar.MILLISECOND));
283 | 5 |
                     int minutesOffset = gmtOffset / (60 * 1000);
284 | 5 |
                     int hoursOffset = minutesOffset / 60;
285 | 5 |
                     int partOfHour = minutesOffset % 60;
286 | 5 |
                     buffer.append((hoursOffset > 0 ? "+" : "") + hoursOffset + ":"
287 |  |
                             + (partOfHour < 10 ? "0" + partOfHour : partOfHour));
288 |  |
                 }
289 | 83 |
                 return representScalar(getTag(data.getClass(), Tag.TIMESTAMP), buffer.toString(), null);
290 |  |
             }
291 |  |
         }
292 |  |
293 | 3965 |
         protected class RepresentEnum implements Represent {
294 |  |
             public Node representData(Object data) {
295 | 30 |
                 Tag tag = new Tag(data.getClass());
296 | 30 |
                 return representScalar(getTag(data.getClass(), tag), ((Enum<?>) data).name());
297 |  |
             }
298 |  |
         }
299 |  |
300 | 3965 |
         protected class RepresentByteArray implements Represent {
301 |  |
             public Node representData(Object data) {
302 | 4 |
                 char[] binary = Base64Coder.encode((byte[]) data);
303 | 4 |
                 return representScalar(Tag.BINARY, String.valueOf(binary), '|');
304 |  |
             }
305 |  |
         }
306 |  |
     }