All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snakeyaml.engine.v2.serializer.Serializer Maven / Gradle / Ivy

There is a newer version: 2.9
Show newest version
/**
 * Copyright (c) 2018, http://www.snakeyaml.org
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.snakeyaml.engine.v2.serializer; import org.snakeyaml.engine.v2.api.DumpSettings; import org.snakeyaml.engine.v2.common.Anchor; import org.snakeyaml.engine.v2.emitter.Emitable; import org.snakeyaml.engine.v2.events.AliasEvent; import org.snakeyaml.engine.v2.events.DocumentEndEvent; import org.snakeyaml.engine.v2.events.DocumentStartEvent; import org.snakeyaml.engine.v2.events.ImplicitTuple; import org.snakeyaml.engine.v2.events.MappingEndEvent; import org.snakeyaml.engine.v2.events.MappingStartEvent; import org.snakeyaml.engine.v2.events.ScalarEvent; import org.snakeyaml.engine.v2.events.SequenceEndEvent; import org.snakeyaml.engine.v2.events.SequenceStartEvent; import org.snakeyaml.engine.v2.events.StreamEndEvent; import org.snakeyaml.engine.v2.events.StreamStartEvent; import org.snakeyaml.engine.v2.nodes.AnchorNode; import org.snakeyaml.engine.v2.nodes.CollectionNode; import org.snakeyaml.engine.v2.nodes.MappingNode; import org.snakeyaml.engine.v2.nodes.Node; import org.snakeyaml.engine.v2.nodes.NodeTuple; import org.snakeyaml.engine.v2.nodes.NodeType; import org.snakeyaml.engine.v2.nodes.ScalarNode; import org.snakeyaml.engine.v2.nodes.SequenceNode; import org.snakeyaml.engine.v2.nodes.Tag; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; public class Serializer { private final DumpSettings settings; private final Emitable emitable; private final Set serializedNodes; private final Map anchors; public Serializer(DumpSettings settings, Emitable emitable) { this.settings = settings; this.emitable = emitable; this.serializedNodes = new HashSet(); this.anchors = new HashMap(); } public void serialize(Node node) { this.emitable.emit(new DocumentStartEvent(settings.isExplicitStart(), settings.getYamlDirective(), settings.getTagDirective())); anchorNode(node); settings.getExplicitRootTag().ifPresent(node::setTag); serializeNode(node); this.emitable.emit(new DocumentEndEvent(settings.isExplicitEnd())); this.serializedNodes.clear(); this.anchors.clear(); } public void open() { this.emitable.emit(new StreamStartEvent()); } public void close() { this.emitable.emit(new StreamEndEvent()); // clean up the resources this.anchors.clear(); this.serializedNodes.clear(); } private void anchorNode(Node node) { final Node realNode; if (node.getNodeType() == NodeType.ANCHOR) { realNode = ((AnchorNode) node).getRealNode(); } else { realNode = node; } if (this.anchors.containsKey(realNode)) { //it looks weird, anchors does contain the key node but we call computeIfAbsent() // this is because the value is null (HashMap permits values to be null) this.anchors.computeIfAbsent(realNode, a -> settings.getAnchorGenerator().nextAnchor(realNode)); } else { this.anchors.put(realNode, realNode.getAnchor().isPresent() ? settings.getAnchorGenerator().nextAnchor(realNode) : null); switch (realNode.getNodeType()) { case SEQUENCE: SequenceNode seqNode = (SequenceNode) realNode; List list = seqNode.getValue(); for (Node item : list) { anchorNode(item); } break; case MAPPING: MappingNode mappingNode = (MappingNode) realNode; List map = mappingNode.getValue(); for (NodeTuple object : map) { Node key = object.getKeyNode(); Node value = object.getValueNode(); anchorNode(key); anchorNode(value); } break; default: // no further action required for non-collections } } } private void serializeNode(Node node) { if (node.getNodeType() == NodeType.ANCHOR) { node = ((AnchorNode) node).getRealNode(); } Optional tAlias = Optional.ofNullable(this.anchors.get(node)); if (this.serializedNodes.contains(node)) { this.emitable.emit(new AliasEvent(tAlias)); } else { this.serializedNodes.add(node); switch (node.getNodeType()) { case SCALAR: ScalarNode scalarNode = (ScalarNode) node; Tag detectedTag = settings.getScalarResolver().resolve(scalarNode.getValue(), true); Tag defaultTag = settings.getScalarResolver().resolve(scalarNode.getValue(), false); ImplicitTuple tuple = new ImplicitTuple(node.getTag().equals(detectedTag), node .getTag().equals(defaultTag)); ScalarEvent event = new ScalarEvent(tAlias, Optional.of(node.getTag().getValue()), tuple, scalarNode.getValue(), scalarNode.getScalarStyle()); this.emitable.emit(event); break; case SEQUENCE: SequenceNode seqNode = (SequenceNode) node; boolean implicitS = node.getTag().equals(Tag.SEQ); this.emitable.emit(new SequenceStartEvent(tAlias, Optional.of(node.getTag().getValue()), implicitS, seqNode.getFlowStyle())); List list = seqNode.getValue(); for (Node item : list) { serializeNode(item); } this.emitable.emit(new SequenceEndEvent()); break; default:// instance of MappingNode boolean implicitM = node.getTag().equals(Tag.MAP); this.emitable.emit(new MappingStartEvent(tAlias, Optional.of(node.getTag().getValue()), implicitM, ((CollectionNode) node).getFlowStyle())); MappingNode mappingNode = (MappingNode) node; List map = mappingNode.getValue(); for (NodeTuple entry : map) { Node key = entry.getKeyNode(); Node value = entry.getValueNode(); serializeNode(key); serializeNode(value); } this.emitable.emit(new MappingEndEvent()); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy