Coverage Report - org.yaml.snakeyaml.representer.BaseRepresenter
 
Classes in this File Line Coverage Branch Coverage Complexity
BaseRepresenter
96%
87/90
97%
43/44
3
BaseRepresenter$1
100%
2/2
N/A
3
 
 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.util.ArrayList;
 20  
 import java.util.HashMap;
 21  
 import java.util.IdentityHashMap;
 22  
 import java.util.LinkedHashMap;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 
 26  
 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
 27  
 import org.yaml.snakeyaml.DumperOptions.ScalarStyle;
 28  
 import org.yaml.snakeyaml.error.YAMLException;
 29  
 import org.yaml.snakeyaml.introspector.PropertyUtils;
 30  
 import org.yaml.snakeyaml.nodes.AnchorNode;
 31  
 import org.yaml.snakeyaml.nodes.MappingNode;
 32  
 import org.yaml.snakeyaml.nodes.Node;
 33  
 import org.yaml.snakeyaml.nodes.NodeTuple;
 34  
 import org.yaml.snakeyaml.nodes.ScalarNode;
 35  
 import org.yaml.snakeyaml.nodes.SequenceNode;
 36  
 import org.yaml.snakeyaml.nodes.Tag;
 37  
 
 38  
 /**
 39  
  * Represent basic YAML structures: scalar, sequence, mapping
 40  
  */
 41  3965
 public abstract class BaseRepresenter {
 42  3965
     protected final Map<Class<?>, Represent> representers = new HashMap<Class<?>, Represent>();
 43  
     /**
 44  
      * in Java 'null' is not a type. So we have to keep the null representer
 45  
      * separately otherwise it will coincide with the default representer which
 46  
      * is stored with the key null.
 47  
      */
 48  
     protected Represent nullRepresenter;
 49  
     // the order is important (map can be also a sequence of key-values)
 50  3965
     protected final Map<Class<?>, Represent> multiRepresenters = new LinkedHashMap<Class<?>, Represent>();
 51  
     private Character defaultStyle;
 52  3965
     protected FlowStyle defaultFlowStyle = FlowStyle.AUTO;
 53  3965
     protected final Map<Object, Node> representedObjects = new IdentityHashMap<Object, Node>() {
 54  
         private static final long serialVersionUID = -5576159264232131854L;
 55  
 
 56  71766
         public Node put(Object key, Node value) {
 57  67801
             return super.put(key, new AnchorNode(value));
 58  
         }
 59  
     };
 60  
 
 61  
     protected Object objectToRepresent;
 62  
     private PropertyUtils propertyUtils;
 63  3965
     private boolean explicitPropertyUtils = false;
 64  
 
 65  
     public Node represent(Object data) {
 66  16394
         Node node = representData(data);
 67  16385
         representedObjects.clear();
 68  16385
         objectToRepresent = null;
 69  16385
         return node;
 70  
     }
 71  
 
 72  
     protected final Node representData(Object data) {
 73  671967
         objectToRepresent = data;
 74  
         // check for identity
 75  671967
         if (representedObjects.containsKey(objectToRepresent)) {
 76  7133
             Node node = representedObjects.get(objectToRepresent);
 77  7133
             return node;
 78  
         }
 79  
         // }
 80  
         // check for null first
 81  664834
         if (data == null) {
 82  180
             Node node = nullRepresenter.representData(data);
 83  180
             return node;
 84  
         }
 85  
         // check the same class
 86  
         Node node;
 87  664654
         Class<?> clazz = data.getClass();
 88  664654
         if (representers.containsKey(clazz)) {
 89  453155
             Represent representer = representers.get(clazz);
 90  453155
             node = representer.representData(data);
 91  453155
         } else {
 92  
             // check the parents
 93  211499
             for (Class<?> repr : multiRepresenters.keySet()) {
 94  580119
                 if (repr.isInstance(data)) {
 95  170115
                     Represent representer = multiRepresenters.get(repr);
 96  170115
                     node = representer.representData(data);
 97  170113
                     return node;
 98  
                 }
 99  
             }
 100  
             // check array of primitives
 101  41384
             if (clazz.isArray()) {
 102  2
                 throw new YAMLException("Arrays of primitives are not fully supported.");
 103  
             }
 104  
             // check defaults
 105  41382
             if (multiRepresenters.containsKey(null)) {
 106  0
                 Represent representer = multiRepresenters.get(null);
 107  0
                 node = representer.representData(data);
 108  0
             } else {
 109  41382
                 Represent representer = representers.get(null);
 110  41382
                 node = representer.representData(data);
 111  
             }
 112  
         }
 113  494531
         return node;
 114  
     }
 115  
 
 116  
     protected Node representScalar(Tag tag, String value, Character style) {
 117  597025
         if (style == null) {
 118  597018
             style = this.defaultStyle;
 119  
         }
 120  597025
         Node node = new ScalarNode(tag, value, null, null, style);
 121  
         // representedObjects.put(objectToRepresent, node);
 122  597025
         return node;
 123  
     }
 124  
 
 125  
     protected Node representScalar(Tag tag, String value) {
 126  143848
         return representScalar(tag, value, null);
 127  
     }
 128  
 
 129  
     protected Node representSequence(Tag tag, Iterable<? extends Object> sequence, Boolean flowStyle) {
 130  16224
         int size = 10;// default for ArrayList
 131  16224
         if (sequence instanceof List<?>) {
 132  16217
             size = ((List<?>) sequence).size();
 133  
         }
 134  16224
         List<Node> value = new ArrayList<Node>(size);
 135  16224
         SequenceNode node = new SequenceNode(tag, value, flowStyle);
 136  16224
         representedObjects.put(objectToRepresent, node);
 137  16224
         boolean bestStyle = true;
 138  16224
         for (Object item : sequence) {
 139  114677
             Node nodeItem = representData(item);
 140  114677
             if (!((nodeItem instanceof ScalarNode && ((ScalarNode) nodeItem).getStyle() == null))) {
 141  14197
                 bestStyle = false;
 142  
             }
 143  114677
             value.add(nodeItem);
 144  114677
         }
 145  16224
         if (flowStyle == null) {
 146  16216
             if (defaultFlowStyle != FlowStyle.AUTO) {
 147  13064
                 node.setFlowStyle(defaultFlowStyle.getStyleBoolean());
 148  
             } else {
 149  3152
                 node.setFlowStyle(bestStyle);
 150  
             }
 151  
         }
 152  16224
         return node;
 153  
     }
 154  
 
 155  
     protected Node representMapping(Tag tag, Map<? extends Object, Object> mapping,
 156  
             Boolean flowStyle) {
 157  10199
         List<NodeTuple> value = new ArrayList<NodeTuple>(mapping.size());
 158  10199
         MappingNode node = new MappingNode(tag, value, flowStyle);
 159  10199
         representedObjects.put(objectToRepresent, node);
 160  10199
         boolean bestStyle = true;
 161  10199
         for (Object itemKey : mapping.keySet()) {
 162  100402
             Object itemValue = mapping.get(itemKey);
 163  100402
             Node nodeKey = representData(itemKey);
 164  100402
             Node nodeValue = representData(itemValue);
 165  100402
             if (!((nodeKey instanceof ScalarNode && ((ScalarNode) nodeKey).getStyle() == null))) {
 166  52
                 bestStyle = false;
 167  
             }
 168  100402
             if (!((nodeValue instanceof ScalarNode && ((ScalarNode) nodeValue).getStyle() == null))) {
 169  99
                 bestStyle = false;
 170  
             }
 171  100402
             value.add(new NodeTuple(nodeKey, nodeValue));
 172  100402
         }
 173  10199
         if (flowStyle == null) {
 174  10195
             if (defaultFlowStyle != FlowStyle.AUTO) {
 175  10056
                 node.setFlowStyle(defaultFlowStyle.getStyleBoolean());
 176  
             } else {
 177  139
                 node.setFlowStyle(bestStyle);
 178  
             }
 179  
         }
 180  10199
         return node;
 181  
     }
 182  
 
 183  
     public void setDefaultScalarStyle(ScalarStyle defaultStyle) {
 184  3963
         this.defaultStyle = defaultStyle.getChar();
 185  3963
     }
 186  
 
 187  
     public void setDefaultFlowStyle(FlowStyle defaultFlowStyle) {
 188  30095
         this.defaultFlowStyle = defaultFlowStyle;
 189  30095
     }
 190  
 
 191  
     public FlowStyle getDefaultFlowStyle() {
 192  13067
         return this.defaultFlowStyle;
 193  
     }
 194  
 
 195  
     public void setPropertyUtils(PropertyUtils propertyUtils) {
 196  5
         this.propertyUtils = propertyUtils;
 197  5
         this.explicitPropertyUtils = true;
 198  5
     }
 199  
 
 200  
     public final PropertyUtils getPropertyUtils() {
 201  49338
         if (propertyUtils == null) {
 202  3958
             propertyUtils = new PropertyUtils();
 203  
         }
 204  49338
         return propertyUtils;
 205  
     }
 206  
 
 207  
     public final boolean isExplicitPropertyUtils() {
 208  2
         return explicitPropertyUtils;
 209  
     }
 210  
 }