Coverage Report - org.yaml.snakeyaml.representer.SafeRepresenter
 
Classes in this File Line Coverage Branch Coverage Complexity
SafeRepresenter
96%
28/29
100%
4/4
2.65
SafeRepresenter$IteratorWrapper
100%
4/4
N/A
2.65
SafeRepresenter$RepresentArray
100%
4/4
N/A
2.65
SafeRepresenter$RepresentBoolean
100%
5/5
100%
2/2
2.65
SafeRepresenter$RepresentByteArray
100%
3/3
N/A
2.65
SafeRepresenter$RepresentDate
100%
50/50
100%
28/28
2.65
SafeRepresenter$RepresentEnum
100%
3/3
N/A
2.65
SafeRepresenter$RepresentIterator
100%
3/3
N/A
2.65
SafeRepresenter$RepresentList
100%
2/2
N/A
2.65
SafeRepresenter$RepresentMap
100%
2/2
N/A
2.65
SafeRepresenter$RepresentNull
100%
2/2
N/A
2.65
SafeRepresenter$RepresentNumber
100%
14/14
100%
16/16
2.65
SafeRepresenter$RepresentSet
100%
6/6
100%
2/2
2.65
SafeRepresenter$RepresentString
86%
13/15
100%
6/6
2.65
 
 1  
 /**
 2  
  * Copyright (c) 2008-2012, 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  
 package org.yaml.snakeyaml.representer;
 17  
 
 18  
 import java.io.UnsupportedEncodingException;
 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.error.YAMLException;
 33  
 import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
 34  
 import org.yaml.snakeyaml.nodes.Node;
 35  
 import org.yaml.snakeyaml.nodes.Tag;
 36  
 import org.yaml.snakeyaml.reader.StreamReader;
 37  
 
 38  
 /**
 39  
  * Represent standard Java classes
 40  
  */
 41  
 class SafeRepresenter extends BaseRepresenter {
 42  
 
 43  
     protected Map<Class<? extends Object>, Tag> classTags;
 44  132938
     protected TimeZone timeZone = null;
 45  
 
 46  132938
     public SafeRepresenter() {
 47  132938
         this.nullRepresenter = new RepresentNull();
 48  132938
         this.representers.put(String.class, new RepresentString());
 49  132938
         this.representers.put(Boolean.class, new RepresentBoolean());
 50  132938
         this.representers.put(Character.class, new RepresentString());
 51  132938
         this.representers.put(byte[].class, new RepresentByteArray());
 52  132938
         this.multiRepresenters.put(Number.class, new RepresentNumber());
 53  132938
         this.multiRepresenters.put(List.class, new RepresentList());
 54  132938
         this.multiRepresenters.put(Map.class, new RepresentMap());
 55  132938
         this.multiRepresenters.put(Set.class, new RepresentSet());
 56  132938
         this.multiRepresenters.put(Iterator.class, new RepresentIterator());
 57  132938
         this.multiRepresenters.put(new Object[0].getClass(), new RepresentArray());
 58  132938
         this.multiRepresenters.put(Date.class, new RepresentDate());
 59  132938
         this.multiRepresenters.put(Enum.class, new RepresentEnum());
 60  132938
         this.multiRepresenters.put(Calendar.class, new RepresentDate());
 61  132938
         classTags = new HashMap<Class<? extends Object>, Tag>();
 62  132938
     }
 63  
 
 64  
     protected Tag getTag(Class<?> clazz, Tag defaultTag) {
 65  170114
         if (classTags.containsKey(clazz)) {
 66  1
             return classTags.get(clazz);
 67  
         } else {
 68  170113
             return defaultTag;
 69  
         }
 70  
     }
 71  
 
 72  
     /**
 73  
      * Define a tag for the <code>Class</code> to serialize
 74  
      * 
 75  
      * @deprecated use Tag instead of String
 76  
      * @param clazz
 77  
      *            <code>Class</code> which tag is changed
 78  
      * @param tag
 79  
      *            new tag to be used for every instance of the specified
 80  
      *            <code>Class</code>
 81  
      * @return the previous tag associated with the <code>Class</code>
 82  
      */
 83  
     public Tag addClassTag(Class<? extends Object> clazz, String tag) {
 84  0
         return addClassTag(clazz, new Tag(tag));
 85  
     }
 86  
 
 87  
     /**
 88  
      * Define a tag for the <code>Class</code> to serialize.
 89  
      * 
 90  
      * @param clazz
 91  
      *            <code>Class</code> which tag is changed
 92  
      * @param tag
 93  
      *            new tag to be used for every instance of the specified
 94  
      *            <code>Class</code>
 95  
      * @return the previous tag associated with the <code>Class</code>
 96  
      */
 97  
     public Tag addClassTag(Class<? extends Object> clazz, Tag tag) {
 98  16
         if (tag == null) {
 99  1
             throw new NullPointerException("Tag must be provided.");
 100  
         }
 101  15
         return classTags.put(clazz, tag);
 102  
     }
 103  
 
 104  132938
     protected class RepresentNull implements Represent {
 105  
         public Node representData(Object data) {
 106  177
             return representScalar(Tag.NULL, "null");
 107  
         }
 108  
     }
 109  
 
 110  1
     public static Pattern MULTILINE_PATTERN = Pattern.compile("\n|\u0085|\u2028|\u2029");
 111  
 
 112  265877
     protected class RepresentString implements Represent {
 113  
         public Node representData(Object data) {
 114  522327
             Tag tag = Tag.STR;
 115  522327
             Character style = null;
 116  522327
             String value = data.toString();
 117  522327
             if (StreamReader.NON_PRINTABLE.matcher(value).find()) {
 118  2116
                 tag = Tag.BINARY;
 119  
                 char[] binary;
 120  
                 try {
 121  2116
                     binary = Base64Coder.encode(value.getBytes("UTF-8"));
 122  0
                 } catch (UnsupportedEncodingException e) {
 123  0
                     throw new YAMLException(e);
 124  2116
                 }
 125  2116
                 value = String.valueOf(binary);
 126  2116
                 style = '|';
 127  
             }
 128  
             // if no other scalar style is explicitly set, use literal style for
 129  
             // multiline scalars
 130  522327
             if (defaultScalarStyle == null && MULTILINE_PATTERN.matcher(value).find()) {
 131  6033
                 style = '|';
 132  
             }
 133  522327
             return representScalar(tag, value, style);
 134  
         }
 135  
     }
 136  
 
 137  132938
     protected class RepresentBoolean implements Represent {
 138  
         public Node representData(Object data) {
 139  
             String value;
 140  16
             if (Boolean.TRUE.equals(data)) {
 141  12
                 value = "true";
 142  
             } else {
 143  4
                 value = "false";
 144  
             }
 145  16
             return representScalar(Tag.BOOL, value);
 146  
         }
 147  
     }
 148  
 
 149  132938
     protected class RepresentNumber implements Represent {
 150  
         public Node representData(Object data) {
 151  
             Tag tag;
 152  
             String value;
 153  143608
             if (data instanceof Byte || data instanceof Short || data instanceof Integer
 154  
                     || data instanceof Long || data instanceof BigInteger) {
 155  119561
                 tag = Tag.INT;
 156  119561
                 value = data.toString();
 157  
             } else {
 158  24047
                 Number number = (Number) data;
 159  24047
                 tag = Tag.FLOAT;
 160  24047
                 if (number.equals(Double.NaN)) {
 161  2
                     value = ".NaN";
 162  24045
                 } else if (number.equals(Double.POSITIVE_INFINITY)) {
 163  1
                     value = ".inf";
 164  24044
                 } else if (number.equals(Double.NEGATIVE_INFINITY)) {
 165  2
                     value = "-.inf";
 166  
                 } else {
 167  24042
                     value = number.toString();
 168  
                 }
 169  
             }
 170  143608
             return representScalar(getTag(data.getClass(), tag), value);
 171  
         }
 172  
     }
 173  
 
 174  132938
     protected class RepresentList implements Represent {
 175  
         @SuppressWarnings("unchecked")
 176  
         public Node representData(Object data) {
 177  16175
             return representSequence(getTag(data.getClass(), Tag.SEQ), (List<Object>) data, null);
 178  
         }
 179  
     }
 180  
 
 181  132938
     protected class RepresentIterator implements Represent {
 182  
         @SuppressWarnings("unchecked")
 183  
         public Node representData(Object data) {
 184  1
             Iterator<Object> iter = (Iterator<Object>) data;
 185  1
             return representSequence(getTag(data.getClass(), Tag.SEQ), new IteratorWrapper(iter),
 186  
                     null);
 187  
         }
 188  
     }
 189  
 
 190  
     private static class IteratorWrapper implements Iterable<Object> {
 191  
         private Iterator<Object> iter;
 192  
 
 193  1
         public IteratorWrapper(Iterator<Object> iter) {
 194  1
             this.iter = iter;
 195  1
         }
 196  
 
 197  
         public Iterator<Object> iterator() {
 198  1
             return iter;
 199  
         }
 200  
     }
 201  
 
 202  132938
     protected class RepresentArray implements Represent {
 203  
         public Node representData(Object data) {
 204  38
             Object[] array = (Object[]) data;
 205  38
             List<Object> list = Arrays.asList(array);
 206  38
             return representSequence(Tag.SEQ, list, null);
 207  
         }
 208  
     }
 209  
 
 210  132938
     protected class RepresentMap implements Represent {
 211  
         @SuppressWarnings("unchecked")
 212  
         public Node representData(Object data) {
 213  10170
             return representMapping(getTag(data.getClass(), Tag.MAP), (Map<Object, Object>) data,
 214  
                     null);
 215  
         }
 216  
     }
 217  
 
 218  132938
     protected class RepresentSet implements Represent {
 219  
         @SuppressWarnings("unchecked")
 220  
         public Node representData(Object data) {
 221  34
             Map<Object, Object> value = new LinkedHashMap<Object, Object>();
 222  34
             Set<Object> set = (Set<Object>) data;
 223  34
             for (Object key : set) {
 224  51
                 value.put(key, null);
 225  
             }
 226  32
             return representMapping(getTag(data.getClass(), Tag.SET), value, null);
 227  
         }
 228  
     }
 229  
 
 230  265880
     protected class RepresentDate implements Represent {
 231  
         public Node representData(Object data) {
 232  
             // because SimpleDateFormat ignores timezone we have to use Calendar
 233  
             Calendar calendar;
 234  85
             if (data instanceof Calendar) {
 235  5
                 calendar = (Calendar) data;
 236  
             } else {
 237  80
                 calendar = Calendar.getInstance(getTimeZone() == null ? TimeZone.getTimeZone("UTC")
 238  
                         : timeZone);
 239  80
                 calendar.setTime((Date) data);
 240  
             }
 241  85
             int years = calendar.get(Calendar.YEAR);
 242  85
             int months = calendar.get(Calendar.MONTH) + 1; // 0..12
 243  85
             int days = calendar.get(Calendar.DAY_OF_MONTH); // 1..31
 244  85
             int hour24 = calendar.get(Calendar.HOUR_OF_DAY); // 0..24
 245  85
             int minutes = calendar.get(Calendar.MINUTE); // 0..59
 246  85
             int seconds = calendar.get(Calendar.SECOND); // 0..59
 247  85
             int millis = calendar.get(Calendar.MILLISECOND);
 248  85
             StringBuilder buffer = new StringBuilder(String.valueOf(years));
 249  88
             while (buffer.length() < 4) {
 250  
                 // ancient years
 251  3
                 buffer.insert(0, "0");
 252  
             }
 253  85
             buffer.append("-");
 254  85
             if (months < 10) {
 255  62
                 buffer.append("0");
 256  
             }
 257  85
             buffer.append(String.valueOf(months));
 258  85
             buffer.append("-");
 259  85
             if (days < 10) {
 260  23
                 buffer.append("0");
 261  
             }
 262  85
             buffer.append(String.valueOf(days));
 263  85
             buffer.append("T");
 264  85
             if (hour24 < 10) {
 265  39
                 buffer.append("0");
 266  
             }
 267  85
             buffer.append(String.valueOf(hour24));
 268  85
             buffer.append(":");
 269  85
             if (minutes < 10) {
 270  28
                 buffer.append("0");
 271  
             }
 272  85
             buffer.append(String.valueOf(minutes));
 273  85
             buffer.append(":");
 274  85
             if (seconds < 10) {
 275  30
                 buffer.append("0");
 276  
             }
 277  85
             buffer.append(String.valueOf(seconds));
 278  85
             if (millis > 0) {
 279  21
                 if (millis < 10) {
 280  1
                     buffer.append(".00");
 281  20
                 } else if (millis < 100) {
 282  6
                     buffer.append(".0");
 283  
                 } else {
 284  14
                     buffer.append(".");
 285  
                 }
 286  21
                 buffer.append(String.valueOf(millis));
 287  
             }
 288  85
             if (TimeZone.getTimeZone("UTC").equals(calendar.getTimeZone())) {
 289  79
                 buffer.append("Z");
 290  
             } else {
 291  
                 // Get the Offset from GMT taking DST into account
 292  6
                 int gmtOffset = calendar.getTimeZone().getOffset(calendar.get(Calendar.ERA),
 293  
                         calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
 294  
                         calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK),
 295  
                         calendar.get(Calendar.MILLISECOND));
 296  6
                 int minutesOffset = gmtOffset / (60 * 1000);
 297  6
                 int hoursOffset = minutesOffset / 60;
 298  6
                 int partOfHour = minutesOffset % 60;
 299  6
                 buffer.append((hoursOffset > 0 ? "+" : "") + hoursOffset + ":"
 300  
                         + (partOfHour < 10 ? "0" + partOfHour : partOfHour));
 301  
             }
 302  85
             return representScalar(getTag(data.getClass(), Tag.TIMESTAMP), buffer.toString(), null);
 303  
         }
 304  
     }
 305  
 
 306  132938
     protected class RepresentEnum implements Represent {
 307  
         public Node representData(Object data) {
 308  30
             Tag tag = new Tag(data.getClass());
 309  30
             return representScalar(getTag(data.getClass(), tag), ((Enum<?>) data).name());
 310  
         }
 311  
     }
 312  
 
 313  132938
     protected class RepresentByteArray implements Represent {
 314  
         public Node representData(Object data) {
 315  5
             char[] binary = Base64Coder.encode((byte[]) data);
 316  5
             return representScalar(Tag.BINARY, String.valueOf(binary), '|');
 317  
         }
 318  
     }
 319  
 
 320  
     public TimeZone getTimeZone() {
 321  80
         return timeZone;
 322  
     }
 323  
 
 324  
     public void setTimeZone(TimeZone timeZone) {
 325  132936
         this.timeZone = timeZone;
 326  132936
     }
 327  
 }