##### Coverage Report - org.yaml.snakeyaml.serializer.Serializer

Classes in this File | Line Coverage | Branch Coverage | Complexity
Serializer |
100% | 108/108
100% | 40/40
| 4.714285714285714;4.714
Serializer$1 |
100% | 1/1
N/A | N/A
| 4.714285714285714;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 |  |
     }