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

com.amihaiemil.eoyaml.YamlPrintVisitor Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2016-2024, Mihai Emil Andronache
 * All rights reserved.
 * 

* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ package com.amihaiemil.eoyaml; import java.io.StringWriter; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; /** * Visitor which prints the YAML in block format. * @author Mihai Andronache ([email protected]) * @version $Id: 524a3bb19917dc5371a33c7fc07281c9864156c0 $ * @checkstyle ExecutableStatementCount (1000 lines) * @since 7.2.0 */ final class YamlPrintVisitor implements YamlVisitor { /** * How many indentation spaces to use? */ private final int indentation; /** * Line separator. */ private final String lineSeparator; /** * Print each node as block-style always. */ private final boolean alwaysBlock; /** * Ctor. * @param lineSeparator Line separator. * @param alwaysBlock Print each node as block-style always. */ YamlPrintVisitor(final String lineSeparator, final boolean alwaysBlock) { this(2, lineSeparator, alwaysBlock); } /** * Ctor. * @param indentation Number of spaces to use for indentation. * @param lineSeparator Line separator. * @param alwaysBlock Print each node as block-style always. */ YamlPrintVisitor( final int indentation, final String lineSeparator, final boolean alwaysBlock ) { this.indentation = indentation; this.lineSeparator = lineSeparator; this.alwaysBlock = alwaysBlock; } @Override public String visitYamlMapping(final YamlMapping node) { final StringWriter writer = new StringWriter(); final String printed; if((node instanceof ReadFlowMapping || node instanceof JsonYamlMapping) && !this.alwaysBlock) { this.printFlowMapping(node, writer); printed = writer.toString(); } else { this.printBlockMapping(node, writer); final String printedMapping = writer.toString(); if (printedMapping.length() > 0) { printed = printedMapping.substring( 0, printedMapping.length() - 1 ); } else { printed = printedMapping; } } return printed; } @Override public String visitYamlSequence(final YamlSequence node) { final StringWriter writer = new StringWriter(); final String printed; if((node instanceof ReadFlowSequence || node instanceof JsonYamlSequence) && !this.alwaysBlock) { this.printFlowSequence(node, writer); printed = writer.toString(); } else { this.printBlockSequence(node, writer); final String printedSequence = writer.toString(); if (printedSequence.length() > 0) { printed = printedSequence.substring( 0, printedSequence.length() - 1 ); } else { printed = printedSequence; } } return printed; } @Override public String visitScalar(final Scalar node) { final StringWriter writer = new StringWriter(); if (node instanceof BaseFoldedScalar) { final BaseFoldedScalar foldedScalar = (BaseFoldedScalar) node; writer.append(">"); if(!node.comment().value().isEmpty()) { writer.append(" # ").append(node.comment().value()); } writer.append(this.lineSeparator); final List unfolded = foldedScalar.unfolded(); for(int idx = 0; idx < unfolded.size(); idx++) { writer.append( this.indent( unfolded.get(idx).trim(), indentation ) ); if(idx < unfolded.size() - 1) { writer.append(this.lineSeparator); } } } else if (node instanceof RtYamlScalarBuilder.BuiltLiteralBlockScalar || node instanceof ReadLiteralBlockScalar ) { writer.append("|"); if(!node.comment().value().isEmpty()) { writer.append(" # ").append(node.comment().value()); } writer .append(this.lineSeparator) .append( this.indent(node.value(), indentation) ); } else { writer.append(new Escaped(node).value()); final Comment comment = node.comment(); if (comment instanceof ScalarComment) { final ScalarComment scalarComment = (ScalarComment) comment; if (!scalarComment.inline().value().isEmpty()) { writer.append(" # ").append( scalarComment.inline().value() ); } } } return writer.toString(); } @Override public String visitYamlStream(final YamlStream node) { final StringWriter writer = new StringWriter(); node.forEach( yaml -> writer.append("---") .append(this.lineSeparator) .append( this.indent( this.visitYamlNode(yaml), this.indentation ) ) .append(this.lineSeparator) ); final String printedStream = writer.toString(); final String trimmed; if (printedStream.length() > 0) { trimmed = printedStream.substring(0, printedStream.length() - 1); } else { trimmed = printedStream; } return trimmed; } @Override public String visitYamlNode(final YamlNode node) { final StringWriter writer = new StringWriter(); if (node == null || node.isEmpty()) { if (node instanceof YamlSequence) { writer.append("[]"); } else if (node instanceof YamlMapping) { writer.append("{}"); } else if (node instanceof YamlStream) { writer.append("---" + this.lineSeparator + "..."); } else { writer.append("null"); } } else { if (node instanceof Scalar) { writer.append(this.visitScalar((Scalar) node)); } else if (node instanceof YamlSequence) { writer.append(this.visitYamlSequence((YamlSequence) node)); } else if (node instanceof YamlMapping) { writer.append(this.visitYamlMapping((YamlMapping) node)); } else if (node instanceof YamlStream) { writer.append(this.visitYamlStream((YamlStream) node)); } } return writer.toString(); } @Override public String defaultResult() { return ""; } @Override public String aggregateResult( final String aggregate, final String nextResult ) { return aggregate + nextResult; } /** * Indent a text with a number of spaces. * @param print Text to indent. * @param numberOfSpaces Number of indentation spaces. * @return Indented text. */ private String indent(final String print, final int numberOfSpaces) { int spaces = numberOfSpaces; final StringBuilder indent = new StringBuilder(); while (spaces > 0) { indent.append(" "); spaces--; } final String[] lines = print.split(this.lineSeparator); final StringWriter indented = new StringWriter(); for(final String line : lines) { indented .append(indent.toString()) .append(line) .append(this.lineSeparator); } final String str = indented.toString(); return str.substring(0, str.length() - 1); } /** * Print a comment. Make sure to split the lines if there are more * lines separated by NewLine and also add a '# ' in front of each * line. * @param node Node containing the Comment. * @return Printed comment. */ private String printPossibleComment(final YamlNode node) { final StringWriter writer = new StringWriter(); if(node != null && node.comment() != null) { final Comment tmpComment; if(node.comment() instanceof ScalarComment) { tmpComment = ((ScalarComment) node.comment()).above(); } else { tmpComment = node.comment(); } final String com = tmpComment.value(); if (com.trim().length() != 0) { String[] lines = com.split(this.lineSeparator); for (final String line : lines) { writer .append("# ") .append(line) .append(this.lineSeparator); } } } return writer.toString(); } /** * Write a block mapping to the given StringWriter. * @param node Block YamlMapping to print. * @param writer String writer. */ private void printBlockMapping( final YamlMapping node, final StringWriter writer ) { for (final YamlNode key : node.keys()) { final YamlNode value = node.value(key); writer.append(this.printPossibleComment(value)); if(key.type().equals(Node.SCALAR)) { writer.append(this.visitYamlNode(key)); } else { writer.append("?").append(this.lineSeparator); final String printedValue = this.visitYamlNode(key); writer.append(this.indent(printedValue, this.indentation)); writer.append(this.lineSeparator); } if(value == null || value.type().equals(Node.SCALAR)) { writer.append(": "); writer.append(this.visitYamlNode(value)); } else { final String printedValue = this.visitYamlNode(value); if("null".equals(printedValue) || printedValue.startsWith("[") || printedValue.startsWith("{") ) { writer.append(": "); writer.append(printedValue); } else { writer.append(":"); writer.append(this.lineSeparator); writer.append(this.indent(printedValue, this.indentation)); } } writer.append(this.lineSeparator); } } /** * Write a flow mapping to the given StringWriter. * @param node Flow YamlMapping to print. * @param writer String writer. */ private void printFlowMapping( final YamlMapping node, final StringWriter writer ) { writer.append("{"); int i=0; final Set keys = node.keys(); for (final YamlNode key : keys) { final YamlNode value = node.value(key); writer.append(this.visitYamlNode(key)); writer.append(": "); writer.append(this.visitYamlNode(value)); i++; if(i values = node.values(); for (final YamlNode value : values) { writer.append(this.visitYamlNode(value)); i++; if(i cases = Arrays.asList( flowMap, flowSequence, blockSequence, isNullRef, justSpaces, spaceAfterColon, otherSpecialChars ); for(final String regex : cases) { if(value.matches(regex)) { return true; } } return false; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy