Coverage Report - org.yaml.snakeyaml.serializer.Serializer
 
Classes in this File Line Coverage Branch Coverage Complexity
Serializer
100%
108/108
100%
40/40
4.714
Serializer$1
100%
1/1
N/A
4.714
 
 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.serializer;
 18  
 
 19  
 import java.io.IOException;
 20  
 import java.text.NumberFormat;
 21  
 import java.util.HashMap;
 22  
 import java.util.HashSet;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 import java.util.Set;
 26  
 
 27  
 import org.yaml.snakeyaml.DumperOptions;
 28  
 import org.yaml.snakeyaml.emitter.Emitable;
 29  
 import org.yaml.snakeyaml.events.AliasEvent;
 30  
 import org.yaml.snakeyaml.events.DocumentEndEvent;
 31  
 import org.yaml.snakeyaml.events.DocumentStartEvent;
 32  
 import org.yaml.snakeyaml.events.ImplicitTuple;
 33  
 import org.yaml.snakeyaml.events.MappingEndEvent;
 34  
 import org.yaml.snakeyaml.events.MappingStartEvent;
 35  
 import org.yaml.snakeyaml.events.ScalarEvent;
 36  
 import org.yaml.snakeyaml.events.SequenceEndEvent;
 37  
 import org.yaml.snakeyaml.events.SequenceStartEvent;
 38  
 import org.yaml.snakeyaml.events.StreamEndEvent;
 39  
 import org.yaml.snakeyaml.events.StreamStartEvent;
 40  
 import org.yaml.snakeyaml.nodes.AnchorNode;
 41  
 import org.yaml.snakeyaml.nodes.CollectionNode;
 42  
 import org.yaml.snakeyaml.nodes.MappingNode;
 43  
 import org.yaml.snakeyaml.nodes.Node;
 44  
 import org.yaml.snakeyaml.nodes.NodeId;
 45  
 import org.yaml.snakeyaml.nodes.NodeTuple;
 46  
 import org.yaml.snakeyaml.nodes.ScalarNode;
 47  
 import org.yaml.snakeyaml.nodes.SequenceNode;
 48  
 import org.yaml.snakeyaml.nodes.Tag;
 49  
 import org.yaml.snakeyaml.resolver.Resolver;
 50  
 
 51  
 public final class Serializer {
 52  
     private final Emitable emitter;
 53  
     private final Resolver resolver;
 54  
     private boolean explicitStart;
 55  
     private boolean explicitEnd;
 56  
     private Integer[] useVersion;
 57  
     private Map<String, String> useTags;
 58  
     private Set<Node> serializedNodes;
 59  
     private Map<Node, String> anchors;
 60  
     private int lastAnchorId;
 61  
     private Boolean closed;
 62  
     private Tag explicitRoot;
 63  
 
 64  16395
     public Serializer(Emitable emitter, Resolver resolver, DumperOptions opts, Tag rootTag) {
 65  16395
         this.emitter = emitter;
 66  16395
         this.resolver = resolver;
 67  16395
         this.explicitStart = opts.isExplicitStart();
 68  16395
         this.explicitEnd = opts.isExplicitEnd();
 69  16395
         if (opts.getVersion() != null) {
 70  2
             this.useVersion = opts.getVersion().getArray();
 71  
         }
 72  16395
         this.useTags = opts.getTags();
 73  16395
         this.serializedNodes = new HashSet<Node>();
 74  16395
         this.anchors = new HashMap<Node, String>();
 75  16395
         this.lastAnchorId = 0;
 76  16395
         this.closed = null;
 77  16395
         this.explicitRoot = rootTag;
 78  16395
     }
 79  
 
 80  
     public void open() throws IOException {
 81  16394
         if (closed == null) {
 82  16392
             this.emitter.emit(new StreamStartEvent(null, null));
 83  16392
             this.closed = Boolean.FALSE;
 84  2
         } else if (Boolean.TRUE.equals(closed)) {
 85  1
             throw new SerializerException("serializer is closed");
 86  
         } else {
 87  1
             throw new SerializerException("serializer is already opened");
 88  
         }
 89  16392
     }
 90  
 
 91  
     public void close() throws IOException {
 92  16382
         if (closed == null) {
 93  1
             throw new SerializerException("serializer is not opened");
 94  16381
         } else if (!Boolean.TRUE.equals(closed)) {
 95  16380
             this.emitter.emit(new StreamEndEvent(null, null));
 96  16380
             this.closed = Boolean.TRUE;
 97  
         }
 98  16381
     }
 99  
 
 100  
     public void serialize(Node node) throws IOException {
 101  16387
         if (closed == null) {
 102  1
             throw new SerializerException("serializer is not opened");
 103  16386
         } else if (closed) {
 104  1
             throw new SerializerException("serializer is closed");
 105  
         }
 106  16385
         this.emitter.emit(new DocumentStartEvent(null, null, this.explicitStart, this.useVersion,
 107  
                 useTags));
 108  16385
         anchorNode(node);
 109  16385
         if (explicitRoot != null) {
 110  13071
             node.setTag(explicitRoot);
 111  
         }
 112  16385
         serializeNode(node, null, null);
 113  16383
         this.emitter.emit(new DocumentEndEvent(null, null, this.explicitEnd));
 114  16383
         this.serializedNodes.clear();
 115  16383
         this.anchors.clear();
 116  16383
         this.lastAnchorId = 0;
 117  16383
     }
 118  
 
 119  
     private void anchorNode(Node node) {
 120  671946
         if (node.getNodeId() == NodeId.anchor) {
 121  7133
             node = ((AnchorNode) node).getRealNode();
 122  
         }
 123  671946
         if (this.anchors.containsKey(node)) {
 124  7133
             String anchor = this.anchors.get(node);
 125  7133
             if (null == anchor) {
 126  7077
                 anchor = generateAnchor();
 127  7077
                 this.anchors.put(node, anchor);
 128  
             }
 129  7133
         } else {
 130  664813
             this.anchors.put(node, null);
 131  1
             switch (node.getNodeId()) {
 132  
             case sequence:
 133  16223
                 SequenceNode seqNode = (SequenceNode) node;
 134  16223
                 List<Node> list = seqNode.getValue();
 135  16223
                 for (Node item : list) {
 136  114677
                     anchorNode(item);
 137  
                 }
 138  16223
                 break;
 139  
             case mapping:
 140  51574
                 MappingNode mnode = (MappingNode) node;
 141  51574
                 List<NodeTuple> map = mnode.getValue();
 142  51574
                 for (NodeTuple object : map) {
 143  270442
                     Node key = object.getKeyNode();
 144  270442
                     Node value = object.getValueNode();
 145  270442
                     anchorNode(key);
 146  270442
                     anchorNode(value);
 147  270442
                 }
 148  
                 break;
 149  
             }
 150  
         }
 151  671946
     }
 152  
 
 153  
     private String generateAnchor() {
 154  7077
         this.lastAnchorId++;
 155  7077
         NumberFormat format = NumberFormat.getNumberInstance();
 156  7077
         format.setMinimumIntegerDigits(3);
 157  7077
         format.setGroupingUsed(false);
 158  7077
         String anchorId = format.format(this.lastAnchorId);
 159  7077
         return "id" + anchorId;
 160  
     }
 161  
 
 162  
     private void serializeNode(Node node, Node parent, Object index) throws IOException {
 163  671946
         if (node.getNodeId() == NodeId.anchor) {
 164  7133
             node = ((AnchorNode) node).getRealNode();
 165  
         }
 166  671946
         String tAlias = this.anchors.get(node);
 167  671946
         if (this.serializedNodes.contains(node)) {
 168  7133
             this.emitter.emit(new AliasEvent(tAlias, null, null));
 169  
         } else {
 170  664813
             this.serializedNodes.add(node);
 171  664813
             switch (node.getNodeId()) {
 172  
             case scalar:
 173  597016
                 ScalarNode scalarNode = (ScalarNode) node;
 174  597016
                 Tag detectedTag = this.resolver.resolve(NodeId.scalar, scalarNode.getValue(), true);
 175  597016
                 Tag defaultTag = this.resolver.resolve(NodeId.scalar, scalarNode.getValue(), false);
 176  597016
                 ImplicitTuple tuple = new ImplicitTuple(node.getTag().equals(detectedTag), node
 177  
                         .getTag().equals(defaultTag));
 178  597016
                 ScalarEvent event = new ScalarEvent(tAlias, node.getTag().getValue(), tuple,
 179  
                         scalarNode.getValue(), null, null, scalarNode.getStyle());
 180  597016
                 this.emitter.emit(event);
 181  597014
                 break;
 182  
             case sequence:
 183  16223
                 SequenceNode seqNode = (SequenceNode) node;
 184  16223
                 boolean implicitS = (node.getTag().equals(this.resolver.resolve(NodeId.sequence,
 185  
                         null, true)));
 186  16223
                 this.emitter.emit(new SequenceStartEvent(tAlias, node.getTag().getValue(),
 187  
                         implicitS, null, null, seqNode.getFlowStyle()));
 188  16223
                 int indexCounter = 0;
 189  16223
                 List<Node> list = seqNode.getValue();
 190  16223
                 for (Node item : list) {
 191  114677
                     serializeNode(item, node, indexCounter);
 192  114677
                     indexCounter++;
 193  
                 }
 194  16223
                 this.emitter.emit(new SequenceEndEvent(null, null));
 195  16223
                 break;
 196  
             default:// instance of MappingNode
 197  51574
                 Tag implicitTag = this.resolver.resolve(NodeId.mapping, null, true);
 198  51574
                 boolean implicitM = (node.getTag().equals(implicitTag));
 199  51574
                 this.emitter.emit(new MappingStartEvent(tAlias, node.getTag().getValue(),
 200  
                         implicitM, null, null, ((CollectionNode) node).getFlowStyle()));
 201  51574
                 MappingNode mnode = (MappingNode) node;
 202  51574
                 List<NodeTuple> map = mnode.getValue();
 203  51574
                 for (NodeTuple row : map) {
 204  270442
                     Node key = row.getKeyNode();
 205  270442
                     Node value = row.getValueNode();
 206  270442
                     serializeNode(key, mnode, null);
 207  270442
                     serializeNode(value, mnode, key);
 208  270442
                 }
 209  51574
                 this.emitter.emit(new MappingEndEvent(null, null));
 210  
             }
 211  
         }
 212  671944
     }
 213  
 }