2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024 Ericsson
4 * Modifications Copyright (C) 2024 OpenInfra Foundation Europe
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
21 package org.oran.smo.yangtools.parser.model.yangdom;
23 import java.io.BufferedWriter;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.OutputStream;
28 import java.io.OutputStreamWriter;
29 import java.io.Writer;
30 import java.nio.charset.StandardCharsets;
31 import java.util.Arrays;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Objects;
37 import org.oran.smo.yangtools.parser.model.YangModel;
38 import org.oran.smo.yangtools.parser.model.statements.yang.CY;
39 import org.oran.smo.yangtools.parser.model.util.GrammarHelper;
42 * Use this class to write out a Yang DOM to a file or output stream. This is typically used where
43 * a YAM is parsed into a DOM, the DOM is manipulated (for example, statements added or removed),
44 * and the result is written out again.
46 * @author Mark Hollmann
48 public abstract class YangDomWriter {
51 * Writes the DOM into a file as denoted by the resolver.
53 public static void writeOut(final YangModel yangModel, final OutputFileNameResolver resolver,
54 final File targetDirectory) throws IOException {
56 final String fileName = resolver.getOutputFileNameForYangInput(yangModel);
57 final File outFile = new File(targetDirectory, fileName);
58 targetDirectory.mkdirs();
59 outFile.createNewFile();
61 final FileOutputStream fileOutputStream = new FileOutputStream(outFile);
62 writeOut(yangModel, fileOutputStream);
63 fileOutputStream.close();
67 * Writes the DOM into an output stream as denoted by the resolver. Note the stream will
68 * not be automatically closed afterwards - it is up to the client to do so.
70 public static void writeOut(final YangModel yangModel, final OutputStreamResolver resolver) throws IOException {
71 final OutputStream outputStream = resolver.getOutputStreamForYangInput(yangModel);
72 writeOut(yangModel, outputStream);
76 * Writes the DOM into an output stream, using UTF-8 character set.
78 public static void writeOut(final YangModel yangModel, final OutputStream outputStream) throws IOException {
80 final Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
82 final YangDomDocumentRoot domDocumentRoot = yangModel.getYangModelRoot().getDomDocumentRoot();
83 writeDomNode(writer, domDocumentRoot.getChildren().get(0), "");
89 private static final Set<String> ADD_COMMENT_AT_END_FOR = new HashSet<>(Arrays.asList(CY.CONTAINER, CY.LIST,
92 private static void writeDomNode(final Writer writer, final YangDomElement domElement, final String indent)
96 writer.write(domElement.getName());
98 if (domElement.getValue() != null) {
100 writeString(writer, domElement.getValue());
103 final List<YangDomElement> children = domElement.getChildren();
104 if (children.isEmpty()) {
107 writer.write(" {\n");
108 final String newIndent = indent + " ";
109 for (final YangDomElement child : children) {
110 writeDomNode(writer, child, newIndent);
112 writer.write(indent);
114 if (ADD_COMMENT_AT_END_FOR.contains(domElement.getName())) {
115 writer.write("} // end '");
116 writer.write(domElement.getName());
118 writer.write(domElement.getValue());
126 private static void writeString(final Writer writer, final String value) throws IOException {
128 if (GrammarHelper.isUnquotableString(value)) {
130 * If there are no characters in the string that might need special handling we can simply write
131 * out the string. And no, we don't care about this stupid stipulation about wrapping at 80 characters.
138 * The string contains characters that must be escaped. Write as double-quoted string, with escaping
141 writer.write(convertToDoubleQuotedString(value));
145 * The supplied string is converted to a double-quoted string in accordance with the YANG rules.
147 private static String convertToDoubleQuotedString(final String input) {
149 final StringBuilder sb = new StringBuilder();
153 for (final char c : Objects.requireNonNull(input).toCharArray()) {
156 sb.append('\\').append('n');
159 sb.append('\\').append('t');
162 sb.append('\\').append('"');
165 sb.append('\\').append('\\');
173 return sb.toString();