| target | ||
| !target/yamlp.jar | ||
| +build | ||
| +#Tue May 19 17:42:14 PDT 2020 | ||
| +gradle.version=6.4 | ||
| +# Default ignored files | ||
| +/shelf/ | ||
| +/workspace.xml | ||
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="CompilerConfiguration"> | ||
| + <bytecodeTargetLevel> | ||
| + <module name="yamlp (1)" target="1.8" /> | ||
| + <module name="yamlp (2)" target="1.8" /> | ||
| + </bytecodeTargetLevel> | ||
| + </component> | ||
| +</project> |
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="Encoding"> | ||
| + <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" /> | ||
| + </component> | ||
| +</project> |
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="GradleMigrationSettings" migrationVersion="1" /> | ||
| + <component name="GradleSettings"> | ||
| + <option name="linkedExternalProjectsSettings"> | ||
| + <GradleProjectSettings> | ||
| + <option name="delegatedBuild" value="true" /> | ||
| + <option name="testRunner" value="GRADLE" /> | ||
| + <option name="distributionType" value="LOCAL" /> | ||
| + <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||
| + <option name="gradleHome" value="/opt/gradle" /> | ||
| + <option name="gradleJvm" value="14" /> | ||
| + <option name="modules"> | ||
| + <set> | ||
| + <option value="$PROJECT_DIR$" /> | ||
| + </set> | ||
| + </option> | ||
| + <option name="useQualifiedModuleNames" value="true" /> | ||
| + </GradleProjectSettings> | ||
| + </option> | ||
| + </component> | ||
| +</project> |
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="RemoteRepositoriesConfiguration"> | ||
| + <remote-repository> | ||
| + <option name="id" value="central" /> | ||
| + <option name="name" value="Central Repository" /> | ||
| + <option name="url" value="https://repo.maven.apache.org/maven2" /> | ||
| + </remote-repository> | ||
| + <remote-repository> | ||
| + <option name="id" value="central" /> | ||
| + <option name="name" value="Maven Central repository" /> | ||
| + <option name="url" value="https://repo1.maven.org/maven2" /> | ||
| + </remote-repository> | ||
| + <remote-repository> | ||
| + <option name="id" value="jboss.community" /> | ||
| + <option name="name" value="JBoss Community repository" /> | ||
| + <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> | ||
| + </remote-repository> | ||
| + <remote-repository> | ||
| + <option name="id" value="MavenLocal" /> | ||
| + <option name="name" value="MavenLocal" /> | ||
| + <option name="url" value="file:$MAVEN_REPOSITORY$/" /> | ||
| + </remote-repository> | ||
| + <remote-repository> | ||
| + <option name="id" value="maven" /> | ||
| + <option name="name" value="maven" /> | ||
| + <option name="url" value="http://repo.maven.apache.org/maven2" /> | ||
| + </remote-repository> | ||
| + <remote-repository> | ||
| + <option name="id" value="MavenRepo" /> | ||
| + <option name="name" value="MavenRepo" /> | ||
| + <option name="url" value="https://repo.maven.apache.org/maven2/" /> | ||
| + </remote-repository> | ||
| + </component> | ||
| +</project> |
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="ExternalStorageConfigurationManager" enabled="true" /> | ||
| + <component name="MavenProjectsManager"> | ||
| + <option name="originalFiles"> | ||
| + <list> | ||
| + <option value="$PROJECT_DIR$/pom.xml" /> | ||
| + <option value="$PROJECT_DIR$/dependency-reduced-pom.xml" /> | ||
| + </list> | ||
| + </option> | ||
| + </component> | ||
| + <component name="ProjectRootManager" version="2" languageLevel="JDK_14" project-jdk-name="JDK1.8" project-jdk-type="JavaSDK" /> | ||
| +</project> |
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="ProjectModuleManager"> | ||
| + <modules> | ||
| + <module fileurl="file://$PROJECT_DIR$/yamlp (1).iml" filepath="$PROJECT_DIR$/yamlp (1).iml" /> | ||
| + <module fileurl="file://$PROJECT_DIR$/yamlp (2).iml" filepath="$PROJECT_DIR$/yamlp (2).iml" /> | ||
| + </modules> | ||
| + </component> | ||
| +</project> |
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="VcsDirectoryMappings"> | ||
| + <mapping directory="" vcs="Git" /> | ||
| + </component> | ||
| +</project> |
| java -jar $HONE/bin/yamlp.jar < variables.yaml > processed.yaml | ||
| - java -jar $HONE/bin/yamlp.jar --xml < variables.yaml > processed.xml | ||
| - java -jar $HONE/bin/yamlp.jar --json < variables.yaml > processed.json | ||
| - | ||
| These examples show to to run the YAML preprocessor, reading a file from standard input (e.g., `variables.yaml`) and writing the processed version of the file to standard output (e.g., `processed.yaml`). | ||
| # Options | ||
| The command line arguments include: | ||
| * `--help` -- show the usage information | ||
| * `--input` -- path to the YAML file to process (standard input) | ||
| -* `--json` -- export contents in JSON format | ||
| -* `--xml` -- export contents in XML format | ||
| * `--regex` -- set expression for matching variables (`(\\$(.*?)\\$)`) | ||
| * `--separator` -- set the separator for delimited paths (`.`) | ||
| -* `--variables` -- output variables to standard error | ||
| * `--quiet` -- suppress writing missing references to standard error | ||
| ## regex | ||
| The regular expression syntax allows a variety of syntaxes to be used when matching variable name references, such as: | ||
| -* `(\$(.*?)\$)` - matches `$...$` | ||
| -* `(\$\{(.*?)\})` - matches `${...}` | ||
| +* `(\$(.*?)\$)` -- matches `$...$` | ||
| +* `(\$\{(.*?)\})` -- matches `${...}` | ||
| The open and closing parentheses---`(` and `)`---are mandatory. The `?` indicates a non-greedy match. Without the `?`, multiple variable references would not match. For example, `name: $var.1$ $var.2$` would be treated as a variable named `var.1$ $var.2` instead of two distinct variables `var.1` and `var.2`. | ||
| Wrap the regular expression in single quotes when running the command, such as: | ||
| java -jar $HOME/bin/yamlp.jar --regex '(\$(.*?)\$)' < variables.yaml | ||
| java -jar $HOME/bin/yamlp.jar --regex '(\$\{(.*?)\})' < variables.yaml | ||
| - | ||
| The single quote prevents the shell from expanding the regex argument into a list of file names. |
| +Manifest-Version: 1.0 | ||
| +Main-Class: com.whitemagicsoftware.yamlp.Main | ||
| + | ||
| +plugins { | ||
| + id 'java' | ||
| + id 'maven-publish' | ||
| +} | ||
| + | ||
| +repositories { | ||
| + mavenCentral() | ||
| +} | ||
| + | ||
| +dependencies { | ||
| + implementation 'org.yaml:snakeyaml:1.26' | ||
| + implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.11.0' | ||
| + implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.0' | ||
| + implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.0' | ||
| + implementation 'args4j:args4j:2.33' | ||
| +} | ||
| + | ||
| +group = 'com.whitemagicsoftware' | ||
| +version = '1.0' | ||
| + | ||
| +publishing { | ||
| + publications { | ||
| + maven(MavenPublication) { | ||
| + from(components.java) | ||
| + } | ||
| + } | ||
| +} | ||
| + | ||
| +jar { | ||
| + duplicatesStrategy = DuplicatesStrategy.EXCLUDE | ||
| + | ||
| + manifest { | ||
| + attributes 'Main-Class': "com.whitemagicsoftware.yamlp.Main" | ||
| + } | ||
| + | ||
| + from { | ||
| + (configurations.runtimeClasspath.findAll { !it.path.endsWith(".pom") }).collect { | ||
| + it.isDirectory() ? it : zipTree(it) | ||
| + } | ||
| + } | ||
| + | ||
| + archiveFileName = 'yamlp.jar' | ||
| + | ||
| + exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' | ||
| +} | ||
| + | ||
| +tasks.withType(JavaCompile) { | ||
| + options.encoding = 'UTF-8' | ||
| +} | ||
| -<?xml version="1.0" encoding="UTF-8"?> | ||
| -<project-shared-configuration> | ||
| - <!-- | ||
| -This file contains additional configuration written by modules in the NetBeans IDE. | ||
| -The configuration is intended to be shared among all the users of project and | ||
| -therefore it is assumed to be part of version control checkout. | ||
| -Without this configuration present, some functionality in the IDE may be limited or fail altogether. | ||
| ---> | ||
| - <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1"> | ||
| - <word>behaviour</word> | ||
| - </spellchecker-wordlist> | ||
| - <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1"> | ||
| - <!-- | ||
| -Properties that influence various parts of the IDE, especially code formatting and the like. | ||
| -You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up. | ||
| -That way multiple projects can share the same settings (useful for formatting rules for example). | ||
| -Any value defined here will override the pom.xml file value but is only applicable to the current project. | ||
| ---> | ||
| - <netbeans.hint.license>mit</netbeans.hint.license> | ||
| - </properties> | ||
| -</project-shared-configuration> | ||
| -<?xml version="1.0" encoding="UTF-8"?> | ||
| -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| - <modelVersion>4.0.0</modelVersion> | ||
| - <groupId>com.whitemagicsoftware</groupId> | ||
| - <artifactId>yamlp</artifactId> | ||
| - <version>1.0</version> | ||
| - <packaging>jar</packaging> | ||
| - <build> | ||
| - <finalName>${project.artifactId}</finalName> | ||
| - <plugins> | ||
| - <plugin> | ||
| - <groupId>org.apache.maven.plugins</groupId> | ||
| - <artifactId>maven-shade-plugin</artifactId> | ||
| - <version>3.1.0</version> | ||
| - <executions> | ||
| - <execution> | ||
| - <phase>package</phase> | ||
| - <goals> | ||
| - <goal>shade</goal> | ||
| - </goals> | ||
| - <configuration> | ||
| - <transformers> | ||
| - <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | ||
| - <mainClass>com.whitemagicsoftware.yamlp.Main</mainClass> | ||
| - </transformer> | ||
| - </transformers> | ||
| - <outputDirectory>/tmp</outputDirectory> | ||
| - </configuration> | ||
| - </execution> | ||
| - </executions> | ||
| - </plugin> | ||
| - </plugins> | ||
| - </build> | ||
| - <dependencies> | ||
| - <dependency> | ||
| - <groupId>org.yaml</groupId> | ||
| - <artifactId>snakeyaml</artifactId> | ||
| - <version>1.18</version> | ||
| - </dependency> | ||
| - <dependency> | ||
| - <groupId>com.fasterxml.jackson.dataformat</groupId> | ||
| - <artifactId>jackson-dataformat-yaml</artifactId> | ||
| - <version>2.9.1</version> | ||
| - </dependency> | ||
| - <dependency> | ||
| - <groupId>com.fasterxml.jackson.dataformat</groupId> | ||
| - <artifactId>jackson-dataformat-xml</artifactId> | ||
| - <version>2.9.1</version> | ||
| - </dependency> | ||
| - <dependency> | ||
| - <groupId>com.fasterxml.jackson.core</groupId> | ||
| - <artifactId>jackson-databind</artifactId> | ||
| - <version>2.9.1</version> | ||
| - </dependency> | ||
| - <dependency> | ||
| - <groupId>args4j</groupId> | ||
| - <artifactId>args4j</artifactId> | ||
| - <version>2.33</version> | ||
| - </dependency> | ||
| - </dependencies> | ||
| - <properties> | ||
| - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| - <maven.compiler.source>1.8</maven.compiler.source> | ||
| - <maven.compiler.target>1.8</maven.compiler.target> | ||
| - </properties> | ||
| -</project> | ||
| + |
| +/* | ||
| + * This file was generated by the Gradle 'init' task. | ||
| + */ | ||
| + | ||
| +rootProject.name = 'yamlp' | ||
| package com.whitemagicsoftware.yamlp; | ||
| -import static com.whitemagicsoftware.yamlp.FileType.JSON; | ||
| -import static com.whitemagicsoftware.yamlp.FileType.XML; | ||
| -import static com.whitemagicsoftware.yamlp.FileType.YAML; | ||
| +import org.kohsuke.args4j.CmdLineParser; | ||
| +import org.kohsuke.args4j.Option; | ||
| + | ||
| import java.io.File; | ||
| import java.io.FileInputStream; | ||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
| -import org.kohsuke.args4j.CmdLineParser; | ||
| -import org.kohsuke.args4j.Option; | ||
| + | ||
| +import static com.whitemagicsoftware.yamlp.FileType.*; | ||
| /** | ||
| - * | ||
| * @author White Magic Software, Ltd. | ||
| */ | ||
| * Separates variable nodes (e.g., the dots in $root.node.var$). | ||
| */ | ||
| - private final static String DEFAULT_SEPERATOR = "."; | ||
| + private final static String DEFAULT_SEPARATOR = "."; | ||
| /** | ||
| * Used to find fields that have variables in their values. | ||
| */ | ||
| private String regex = DEFAULT_REGEX; | ||
| /** | ||
| * Variable name separator given on the command line. | ||
| */ | ||
| - private String separator = DEFAULT_SEPERATOR; | ||
| + private String separator = DEFAULT_SEPARATOR; | ||
| /** | ||
| public InputStream getInputStream() throws IOException { | ||
| final String filename = getInputFilename(); | ||
| - | ||
| - final InputStream stream = isEmpty( filename ) | ||
| - ? System.in | ||
| - : createFileInputStream( filename ); | ||
| - return stream; | ||
| + return isEmpty( filename ) | ||
| + ? System.in | ||
| + : createFileInputStream( filename ); | ||
| } | ||
| /** | ||
| * Open a file. | ||
| * | ||
| * @param filename The file name to open. | ||
| - * | ||
| * @throws IOException Could not open the file. | ||
| */ | ||
| private InputStream createFileInputStream( final String filename ) | ||
| - throws IOException { | ||
| - final File file = new File( filename ); | ||
| - final InputStream stream = new FileInputStream( file ); | ||
| - | ||
| - return stream; | ||
| + throws IOException { | ||
| + return new FileInputStream( new File( filename ) ); | ||
| } | ||
| /** | ||
| * Sets name of the YAML file to parse. | ||
| * | ||
| * @param inputFilename File containing a YAML document. | ||
| */ | ||
| - @Option( name = "--input", | ||
| - required = false, metaVar = "input.yaml", usage = "YAML filename" ) | ||
| + @Option(name = "--input", metaVar = "input.yaml", usage = "YAML filename") | ||
| public void setInputFilename( final String inputFilename ) { | ||
| this.inputFilename = inputFilename; | ||
| public String getOutputFilename() { | ||
| return this.outputFilename; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Sets name of the file to export. | ||
| - * | ||
| - * @param inputFilename File containing a YAML document. | ||
| - */ | ||
| - @Option( name = "--output", | ||
| - metaVar = "output.json", | ||
| - usage = "Destination filename (XML, JSON, YAML)" ) | ||
| - public void setOutputFilename( final String inputFilename ) { | ||
| - this.inputFilename = inputFilename; | ||
| } | ||
| } | ||
| - @Option( name = "--regex", | ||
| - metaVar = DEFAULT_REGEX, | ||
| - usage = "Regular expression to match variables" ) | ||
| + @Option(name = "--regex", | ||
| + metaVar = DEFAULT_REGEX, | ||
| + usage = "Regular expression to match variables") | ||
| private void setRegex( final String regex ) { | ||
| this.regex = regex; | ||
| } | ||
| - @Option( name = "--separator", | ||
| - metaVar = DEFAULT_SEPERATOR, | ||
| - usage = "Default variable expression separator" ) | ||
| + @Option(name = "--separator", | ||
| + metaVar = DEFAULT_SEPARATOR, | ||
| + usage = "Default variable expression separator") | ||
| private void setSeparator( final String separator ) { | ||
| this.separator = separator; | ||
| public boolean isLogging() { | ||
| return this.logging; | ||
| - } | ||
| - | ||
| - @Option( name = "--quiet", | ||
| - usage = "Disables writing to standard error" ) | ||
| - private void setLogging( final boolean logging ) { | ||
| - this.logging = logging; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Answers whether to write the variables to standard error. | ||
| - * | ||
| - * @return false Don't show the variables. | ||
| - */ | ||
| - public boolean isShowVariables() { | ||
| - return this.showVariables; | ||
| - } | ||
| - | ||
| - @Option( name = "--variables", | ||
| - usage = "Write variables to standard error" ) | ||
| - private void setShowVariables( final boolean showVariables ) { | ||
| - this.showVariables = showVariables; | ||
| - } | ||
| - | ||
| - private boolean isExportFormat( final FileType type ) { | ||
| - return this.exportFormat == type || type.matches( getOutputFilename() ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Answers whether to write the variables in JSON format. | ||
| - * | ||
| - * @return true Export in JSON format. | ||
| - */ | ||
| - public boolean isExportJson() { | ||
| - return isExportFormat( JSON ); | ||
| - } | ||
| - | ||
| - @Option( name = "--json", usage = "Force export in JSON format" ) | ||
| - private void setExportJson( final boolean exportJson ) { | ||
| - if( exportJson ) { | ||
| - this.exportFormat = JSON; | ||
| - } | ||
| - } | ||
| - | ||
| - /** | ||
| - * Answers whether to write the variables in XML format. | ||
| - * | ||
| - * @return true Export in XML format. | ||
| - */ | ||
| - public boolean isExportXml() { | ||
| - return isExportFormat( XML ); | ||
| - } | ||
| - | ||
| - @Option( name = "--xml", usage = "Force export in XML format" ) | ||
| - private void setExportXml( final boolean exportXml ) { | ||
| - if( exportXml ) { | ||
| - this.exportFormat = XML; | ||
| - } | ||
| - } | ||
| - | ||
| - /** | ||
| - * Answers whether to write the variables in YAML format. | ||
| - * | ||
| - * @return true Export in YAML format. | ||
| - */ | ||
| - public boolean isExportYaml() { | ||
| - return isExportFormat( YAML ); | ||
| - } | ||
| - | ||
| - @Option( name = "--yaml", usage = "Force export in YAML format" ) | ||
| - private void setExportYaml( final boolean exportYaml ) { | ||
| - if( exportYaml ) { | ||
| - this.exportFormat = YAML; | ||
| - } | ||
| } | ||
| * | ||
| * @param s The string to check for content. | ||
| - * | ||
| * @return true The string has no content (or is null). | ||
| */ | ||
| private boolean isEmpty( final String s ) { | ||
| - return s == null ? true : s.isEmpty(); | ||
| + return s == null || s.isEmpty(); | ||
| } | ||
| } | ||
| private String[] extensions; | ||
| - private FileType( final String... extensions ) { | ||
| + FileType( final String... extensions ) { | ||
| setExtensions( extensions ); | ||
| } |
| * @param args Contains a filename. | ||
| */ | ||
| - public static void main( final String args[] ) { | ||
| + public static void main( final String[] args ) { | ||
| final Configuration configuration = new Configuration(); | ||
| final CmdLineParser clp = new CmdLineParser( configuration ); | ||
| try { | ||
| clp.parseArgument( args ); | ||
| Main main = new Main(); | ||
| main.run( configuration ); | ||
| } | ||
| - catch( CmdLineException e ) { | ||
| + catch( final CmdLineException e ) { | ||
| configuration.usage( clp ); | ||
| } | ||
| - catch( IOException e ) { | ||
| + catch( final IOException e ) { | ||
| configuration.log( e.getLocalizedMessage() ); | ||
| } |
| -/* | ||
| - * The MIT License | ||
| - * | ||
| - * Copyright 2017 White Magic Software, Ltd.. | ||
| - * | ||
| - * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| - * of this software and associated documentation files (the "Software"), to deal | ||
| - * in the Software without restriction, including without limitation the rights | ||
| - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| - * copies of the Software, and to permit persons to whom the Software is | ||
| - * furnished to do so, subject to the following conditions: | ||
| - * | ||
| - * The above copyright notice and this permission notice shall be included in | ||
| - * all copies or substantial portions of the Software. | ||
| - * | ||
| - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| - * THE SOFTWARE. | ||
| - */ | ||
| -package com.whitemagicsoftware.yamlp.parser; | ||
| - | ||
| -import com.fasterxml.jackson.core.JsonGenerationException; | ||
| -import com.fasterxml.jackson.core.JsonGenerator; | ||
| -import com.fasterxml.jackson.databind.JsonSerializer; | ||
| -import com.fasterxml.jackson.databind.SerializerProvider; | ||
| -import java.io.IOException; | ||
| - | ||
| -/** | ||
| - * @author White Magic Software, Ltd. | ||
| - */ | ||
| -public class StringValueSerializer extends JsonSerializer<String> { | ||
| - | ||
| - private YamlParser parser; | ||
| - | ||
| - public StringValueSerializer( final YamlParser parser ) { | ||
| - setParser( parser ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public Class<String> handledType() { | ||
| - return String.class; | ||
| - } | ||
| - | ||
| - @Override | ||
| - public void serialize( final String value, | ||
| - final JsonGenerator jgen, | ||
| - final SerializerProvider provider ) | ||
| - throws IOException, JsonGenerationException { | ||
| - | ||
| - final String fieldName = jgen.getOutputContext().getCurrentName(); | ||
| - final String fieldValue = getParser().substitute( value ); | ||
| - | ||
| - jgen.writeStringField( fieldName, fieldValue ); | ||
| - } | ||
| - | ||
| - private YamlParser getParser() { | ||
| - return this.parser; | ||
| - } | ||
| - | ||
| - private void setParser( final YamlParser parser ) { | ||
| - this.parser = parser; | ||
| - } | ||
| -} | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| -import com.fasterxml.jackson.dataformat.xml.XmlFactory; | ||
| -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; | ||
| -import com.whitemagicsoftware.yamlp.Configuration; | ||
| -import com.whitemagicsoftware.yamlp.resolvers.ResolverXmlFactory; | ||
| -import com.whitemagicsoftware.yamlp.resolvers.ResolverXmlMapper; | ||
| -import com.whitemagicsoftware.yamlp.resolvers.ResolverYAMLFactory; | ||
| -import java.io.File; | ||
| -import java.io.FileInputStream; | ||
| -import java.io.IOException; | ||
| -import java.io.InputStream; | ||
| -import java.util.HashMap; | ||
| -import java.util.Map; | ||
| -import java.util.Map.Entry; | ||
| -import java.util.regex.Matcher; | ||
| -import java.util.regex.Pattern; | ||
| - | ||
| -/** | ||
| - * <p> | ||
| - * This program loads a YAML document into memory, scans for variable | ||
| - * declarations, then substitutes any self-referential values back into the | ||
| - * document. Its output is the given YAML document without any variables. | ||
| - * Variables in the YAML document are denoted using a bracketed dollar symbol | ||
| - * syntax. For example: $field.name$. Some nomenclature to keep from going | ||
| - * squirrely, consider: | ||
| - * </p> | ||
| - * | ||
| - * <pre> | ||
| - * root: | ||
| - * node: | ||
| - * name: $field.name$ | ||
| - * field: | ||
| - * name: Alan Turing | ||
| - * </pre> | ||
| - * | ||
| - * The various components of the given YAML are called: | ||
| - * | ||
| - * <ul> | ||
| - * <li><code>$field.name$</code> - delimited reference</li> | ||
| - * <li><code>field.name</code> - reference</li> | ||
| - * <li><code>name</code> - YAML field</li> | ||
| - * <li><code>Alan Turing</code> - (dereferenced) field value</li> | ||
| - * </ul> | ||
| - * | ||
| - * @author White Magic Software, Ltd. | ||
| - */ | ||
| -public class YamlParser { | ||
| - | ||
| - /** | ||
| - * Separates YAML variable nodes (e.g., the dots in | ||
| - * <code>$root.node.var$</code>). | ||
| - */ | ||
| - public static final String SEPARATOR = "."; | ||
| - public static final char SEPARATOR_CHAR = SEPARATOR.charAt( 0 ); | ||
| - | ||
| - private final static int GROUP_DELIMITED = 1; | ||
| - private final static int GROUP_REFERENCE = 2; | ||
| - | ||
| - /** | ||
| - * Compiled regex. | ||
| - */ | ||
| - private Pattern pattern; | ||
| - | ||
| - /** | ||
| - * Start of the Universe. | ||
| - */ | ||
| - private ObjectNode documentRoot; | ||
| - | ||
| - /** | ||
| - * Command-line options parsed using third-party library. | ||
| - */ | ||
| - private Configuration configuration; | ||
| - | ||
| - /** | ||
| - * Prefer JsonPointer.SEPARATOR, but Jackson YAML uses magic values. | ||
| - */ | ||
| - private final static char SEPARATOR_YAML = '/'; | ||
| - | ||
| - /** | ||
| - * Map of references to dereferenced field values. | ||
| - */ | ||
| - private Map<String, String> references; | ||
| - | ||
| - public YamlParser( final Configuration configuration ) throws IOException { | ||
| - setConfiguration( configuration ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the given string with all the delimited references swapped with | ||
| - * their recursively resolved values. | ||
| - * | ||
| - * @param text The text to parse with zero or more delimited references to | ||
| - * replace. | ||
| - * | ||
| - * @return The substituted value. | ||
| - */ | ||
| - public String substitute( String text ) { | ||
| - final Matcher matcher = patternMatch( text ); | ||
| - final Map<String, String> map = getReferences(); | ||
| - | ||
| - while( matcher.find() ) { | ||
| - final String key = matcher.group( GROUP_DELIMITED ); | ||
| - final String value = map.get( key ); | ||
| - | ||
| - if( value == null ) { | ||
| - missing( text ); | ||
| - } | ||
| - else { | ||
| - text = text.replace( key, value ); | ||
| - } | ||
| - } | ||
| - | ||
| - return text; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Runs before the processing begins. No default behaviour. | ||
| - */ | ||
| - public void preprocess() { | ||
| - } | ||
| - | ||
| - /** | ||
| - * Runs after processing ends. Writes the variables to standard error if the | ||
| - * option to do so was given on the command line. | ||
| - * | ||
| - * @throws IOException Could not write the document (to standard output). | ||
| - */ | ||
| - public void postprocess() throws IOException { | ||
| - writeDocument(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Open a file specified on the command line and process its YAML contents. | ||
| - * The underlying file stream is closed on success or error. | ||
| - * | ||
| - * @throws IOException Could not read the file contents. | ||
| - */ | ||
| - public void process() throws IOException { | ||
| - preprocess(); | ||
| - process( getInputStream() ); | ||
| - postprocess(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Opens the configured input stream (could be a file or standard input). | ||
| - * | ||
| - * @throws IOException Could not open the stream for reading. | ||
| - */ | ||
| - private InputStream getInputStream() throws IOException { | ||
| - return getConfiguration().getInputStream(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Read and process the contents from an open stream. The stream remains open | ||
| - * after calling this method, regardless of success or error. This can be | ||
| - * considered the main entry point to the program. | ||
| - * | ||
| - * @param in The stream with a YAML document to process. | ||
| - * | ||
| - * @throws IOException Could not read the file contents. | ||
| - */ | ||
| - public void process( final InputStream in ) throws IOException { | ||
| - process( readDocument( in ) ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Iterate over a given root node (at any level of the tree) and process each | ||
| - * leaf node. | ||
| - * | ||
| - * @param root A node to process. | ||
| - */ | ||
| - private void process( final JsonNode root ) { | ||
| - root.fields().forEachRemaining( this::process ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Process the given field, which is a named node. This is where the | ||
| - * application does the up-front work of mapping references to their fully | ||
| - * recursively dereferenced values. | ||
| - * | ||
| - * @param field The named node. | ||
| - */ | ||
| - private void process( final Entry<String, JsonNode> field ) { | ||
| - final JsonNode node = field.getValue(); | ||
| - | ||
| - if( node.isObject() ) { | ||
| - process( node ); | ||
| - } | ||
| - else { | ||
| - final JsonNode fieldValue = field.getValue(); | ||
| - | ||
| - // Only basic data types can be parsed into variable values. For | ||
| - // node structures, YAML has a built-in mechanism. | ||
| - if( fieldValue.isValueNode() ) { | ||
| - try { | ||
| - resolve( fieldValue.asText() ); | ||
| - } | ||
| - catch( StackOverflowError e ) { | ||
| - error( "Unresolvable: " + node.textValue() + " = " + fieldValue ); | ||
| - } | ||
| - } | ||
| - } | ||
| - } | ||
| - | ||
| - /** | ||
| - * Inserts the delimited references and field values into the cache. This will | ||
| - * overwrite existing references. | ||
| - * | ||
| - * @param fieldValue YAML field containing zero or more delimited references. | ||
| - * If it contains a delimited reference, the parameter is modified with the | ||
| - * dereferenced value before it is returned. | ||
| - * | ||
| - * @return fieldValue without delimited references. | ||
| - */ | ||
| - private String resolve( String fieldValue ) { | ||
| - final Matcher matcher = patternMatch( fieldValue ); | ||
| - | ||
| - while( matcher.find() ) { | ||
| - final String delimited = matcher.group( GROUP_DELIMITED ); | ||
| - final String reference = matcher.group( GROUP_REFERENCE ); | ||
| - final String dereference = resolve( lookup( reference ) ); | ||
| - | ||
| - fieldValue = fieldValue.replace( delimited, dereference ); | ||
| - | ||
| - // This will perform some superfluous calls by overwriting existing | ||
| - // items in the delimited reference map. | ||
| - put( delimited, dereference ); | ||
| - } | ||
| - | ||
| - return fieldValue; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Inserts a key/value pair into the references map. The map retains | ||
| - * references and dereferenced values found in the YAML. If the reference | ||
| - * already exists, this will overwrite with a new value. | ||
| - * | ||
| - * @param delimited The variable name. | ||
| - * @param dereferenced The resolved value. | ||
| - */ | ||
| - private void put( String delimited, String dereferenced ) { | ||
| - if( dereferenced.isEmpty() ) { | ||
| - missing( delimited ); | ||
| - } | ||
| - else { | ||
| - getReferences().put( delimited, dereferenced ); | ||
| - } | ||
| - } | ||
| - | ||
| - /** | ||
| - * Reads the first YAML document from the input stream. | ||
| - * | ||
| - * @param in The YAML contents. | ||
| - * | ||
| - * @return The root node for the YAML document. | ||
| - * | ||
| - * @throws IOException Could not read the stream. | ||
| - */ | ||
| - private ObjectNode readDocument( final InputStream in ) throws IOException { | ||
| - setDocumentRoot( (ObjectNode)getObjectMapper().readTree( in ) ); | ||
| - return getDocumentRoot(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Writes the modified YAML document to standard output. | ||
| - */ | ||
| - private void writeDocument() throws IOException { | ||
| - final boolean xmlFormat = getConfiguration().isExportXml(); | ||
| - final ObjectMapper result; | ||
| - | ||
| - if( xmlFormat ) { | ||
| - result = new ResolverXmlMapper( this ); | ||
| - } | ||
| - else { | ||
| - result = getObjectMapper(); | ||
| - } | ||
| - | ||
| - result.writeValue( System.out, getDocumentRoot() ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Writes the variables to standard error, no questions asked. This ignores | ||
| - * the silent/quiet/anti-logging option. | ||
| - */ | ||
| - protected void showVariables() { | ||
| - final Map<String, String> r = getReferences(); | ||
| - | ||
| - for( String key : r.keySet() ) { | ||
| - stderr( key + " = " + r.get( key ) ); | ||
| - } | ||
| - } | ||
| - | ||
| - /** | ||
| - * Called when a delimited reference is dereferenced to an empty string. | ||
| - * | ||
| - * @param delimited Delimited reference with no derived value. | ||
| - */ | ||
| - private void missing( final String delimited ) { | ||
| - warn( String.format( "Missing '%s'.", delimited ) ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Called by all methods that log information. | ||
| - * | ||
| - * @param level The level string (WARN/ERROR). | ||
| - * @param message The message to log. | ||
| - */ | ||
| - private void log( String level, String message ) { | ||
| - getConfiguration().log( String.format( "[%s] %s", level, message ) ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Called by all methods that log warning information. | ||
| - * | ||
| - * @param message The text to log to standard error. | ||
| - */ | ||
| - private void warn( String message ) { | ||
| - log( "WARN", message ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Called by all methods that log error information. | ||
| - * | ||
| - * @param message The text to log to standard error. | ||
| - */ | ||
| - private void error( String message ) { | ||
| - log( "ERROR", message ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns a pattern matcher for the given text. | ||
| - * | ||
| - * @param text The text that contains zero or more instances of a pattern that | ||
| - * can be found using the regular expression. | ||
| - */ | ||
| - private Matcher patternMatch( String text ) { | ||
| - return getPattern().matcher( text ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Finds the YAML value for a reference. | ||
| - * | ||
| - * @param reference References a value in the YAML document. | ||
| - * | ||
| - * @return The dereferenced value. | ||
| - */ | ||
| - private String lookup( final String reference ) { | ||
| - return getDocumentRoot().at( asPath( reference ) ).asText(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Sets the parent node for the entire YAML document tree. | ||
| - * | ||
| - * @param documentRoot The parent node. | ||
| - */ | ||
| - private void setDocumentRoot( ObjectNode documentRoot ) { | ||
| - this.documentRoot = documentRoot; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the parent node for the entire YAML document tree. | ||
| - * | ||
| - * @return The parent node. | ||
| - */ | ||
| - public ObjectNode getDocumentRoot() { | ||
| - return this.documentRoot; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the compiled regular expression pattern used to match delimited | ||
| - * references. | ||
| - * | ||
| - * @return A compiled regex for use with the Matcher. | ||
| - */ | ||
| - private Pattern getPattern() { | ||
| - if( this.pattern == null ) { | ||
| - this.pattern = Pattern.compile( getRegex() ); | ||
| - } | ||
| - | ||
| - return this.pattern; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the list of references mapped to dereferenced values. | ||
| - * | ||
| - * @return | ||
| - */ | ||
| - private Map<String, String> getReferences() { | ||
| - if( this.references == null ) { | ||
| - this.references = createReferences(); | ||
| - } | ||
| - | ||
| - return this.references; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Converts a reference (not delimited) to a path that can be used to find a | ||
| - * value that should exist inside the YAML document. | ||
| - * | ||
| - * @param reference The reference to convert to a YAML document path. | ||
| - * | ||
| - * @return The reference with a leading slash and its separator characters | ||
| - * converted to slashes. | ||
| - */ | ||
| - private String asPath( final String reference ) { | ||
| - return SEPARATOR_YAML + reference.replace( | ||
| - getDelimitedSeparator(), | ||
| - SEPARATOR_YAML ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Subclasses can override this method to insert their own map. | ||
| - * | ||
| - * @return An empty HashMap, never null. | ||
| - */ | ||
| - protected Map<String, String> createReferences() { | ||
| - return new HashMap<>(); | ||
| - } | ||
| - | ||
| - private YAMLFactory createYAMLFactory() { | ||
| - return new ResolverYAMLFactory( this ); | ||
| - } | ||
| - | ||
| - private ObjectMapper getObjectMapper() { | ||
| - return new ObjectMapper( createYAMLFactory() ); | ||
| - } | ||
| - | ||
| - private XmlFactory createXmlFactory() { | ||
| - return new ResolverXmlFactory( this ); | ||
| - } | ||
| - | ||
| - private String getRegex() { | ||
| - return getConfiguration().getRegex(); | ||
| - } | ||
| - | ||
| - private char getDelimitedSeparator() { | ||
| - return getConfiguration().getSeparator(); | ||
| - } | ||
| - | ||
| - private boolean isLogging() { | ||
| - return getConfiguration().isLogging(); | ||
| - } | ||
| - | ||
| - private boolean isShowVariables() { | ||
| - return getConfiguration().isShowVariables(); | ||
| - } | ||
| - | ||
| - private void stderr( String message ) { | ||
| - getConfiguration().stderr( message ); | ||
| +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; | ||
| +import com.whitemagicsoftware.yamlp.Configuration; | ||
| +import com.whitemagicsoftware.yamlp.resolvers.ResolverYAMLFactory; | ||
| + | ||
| +import java.io.IOException; | ||
| +import java.io.InputStream; | ||
| +import java.util.HashMap; | ||
| +import java.util.Map; | ||
| +import java.util.Map.Entry; | ||
| +import java.util.regex.Matcher; | ||
| +import java.util.regex.Pattern; | ||
| + | ||
| +/** | ||
| + * <p> | ||
| + * This program loads a YAML document into memory, scans for variable | ||
| + * declarations, then substitutes any self-referential values back into the | ||
| + * document. Its output is the given YAML document without any variables. | ||
| + * Variables in the YAML document are denoted using a bracketed dollar symbol | ||
| + * syntax. For example: $field.name$. Some nomenclature to keep from going | ||
| + * squirrely, consider: | ||
| + * </p> | ||
| + * | ||
| + * <pre> | ||
| + * root: | ||
| + * node: | ||
| + * name: $field.name$ | ||
| + * field: | ||
| + * name: Alan Turing | ||
| + * </pre> | ||
| + * <p> | ||
| + * The various components of the given YAML are called: | ||
| + * | ||
| + * <ul> | ||
| + * <li><code>$field.name$</code> - delimited reference</li> | ||
| + * <li><code>field.name</code> - reference</li> | ||
| + * <li><code>name</code> - YAML field</li> | ||
| + * <li><code>Alan Turing</code> - (dereferenced) field value</li> | ||
| + * </ul> | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public class YamlParser { | ||
| + | ||
| + private final static int GROUP_DELIMITED = 1; | ||
| + private final static int GROUP_REFERENCE = 2; | ||
| + | ||
| + /** | ||
| + * Compiled regex. | ||
| + */ | ||
| + private Pattern pattern; | ||
| + | ||
| + /** | ||
| + * Start of the Universe. | ||
| + */ | ||
| + private ObjectNode documentRoot; | ||
| + | ||
| + /** | ||
| + * Command-line options parsed using third-party library. | ||
| + */ | ||
| + private Configuration configuration; | ||
| + | ||
| + /** | ||
| + * Prefer JsonPointer.SEPARATOR, but Jackson YAML uses magic values. | ||
| + */ | ||
| + private final static char SEPARATOR_YAML = '/'; | ||
| + | ||
| + /** | ||
| + * Map of references to dereferenced field values. | ||
| + */ | ||
| + private Map<String, String> references; | ||
| + | ||
| + public YamlParser( final Configuration configuration ) { | ||
| + setConfiguration( configuration ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the given string with all the delimited references swapped with | ||
| + * their recursively resolved values. | ||
| + * | ||
| + * @param text The text to parse with zero or more delimited references to | ||
| + * replace. | ||
| + * @return The substituted value. | ||
| + */ | ||
| + public String substitute( String text ) { | ||
| + final Matcher matcher = patternMatch( text ); | ||
| + final Map<String, String> map = getReferences(); | ||
| + | ||
| + while( matcher.find() ) { | ||
| + final String key = matcher.group( GROUP_DELIMITED ); | ||
| + final String value = map.get( key ); | ||
| + | ||
| + if( value == null ) { | ||
| + missing( text ); | ||
| + } | ||
| + else { | ||
| + text = text.replace( key, value ); | ||
| + } | ||
| + } | ||
| + | ||
| + return text; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Runs before the processing begins. No default behaviour. | ||
| + */ | ||
| + public void preprocess() { | ||
| + } | ||
| + | ||
| + /** | ||
| + * Runs after processing ends. Writes the variables to standard error if the | ||
| + * option to do so was given on the command line. | ||
| + * | ||
| + * @throws IOException Could not write the document (to standard output). | ||
| + */ | ||
| + public void postprocess() throws IOException { | ||
| + writeDocument(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Open a file specified on the command line and process its YAML contents. | ||
| + * The underlying file stream is closed on success or error. | ||
| + * | ||
| + * @throws IOException Could not read the file contents. | ||
| + */ | ||
| + public void process() throws IOException { | ||
| + preprocess(); | ||
| + process( getInputStream() ); | ||
| + postprocess(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Opens the configured input stream (could be a file or standard input). | ||
| + * | ||
| + * @throws IOException Could not open the stream for reading. | ||
| + */ | ||
| + private InputStream getInputStream() throws IOException { | ||
| + return getConfiguration().getInputStream(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Read and process the contents from an open stream. The stream remains open | ||
| + * after calling this method, regardless of success or error. This can be | ||
| + * considered the main entry point to the program. | ||
| + * | ||
| + * @param in The stream with a YAML document to process. | ||
| + * @throws IOException Could not read the file contents. | ||
| + */ | ||
| + public void process( final InputStream in ) throws IOException { | ||
| + process( readDocument( in ) ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Iterate over a given root node (at any level of the tree) and process each | ||
| + * leaf node. | ||
| + * | ||
| + * @param root A node to process. | ||
| + */ | ||
| + private void process( final JsonNode root ) { | ||
| + root.fields().forEachRemaining( this::process ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Process the given field, which is a named node. This is where the | ||
| + * application does the up-front work of mapping references to their fully | ||
| + * recursively dereferenced values. | ||
| + * | ||
| + * @param field The named node. | ||
| + */ | ||
| + private void process( final Entry<String, JsonNode> field ) { | ||
| + final JsonNode node = field.getValue(); | ||
| + | ||
| + if( node.isObject() ) { | ||
| + process( node ); | ||
| + } | ||
| + else { | ||
| + final JsonNode fieldValue = field.getValue(); | ||
| + | ||
| + // Only basic data types can be parsed into variable values. For | ||
| + // node structures, YAML has a built-in mechanism. | ||
| + if( fieldValue.isValueNode() ) { | ||
| + try { | ||
| + resolve( fieldValue.asText() ); | ||
| + } catch( StackOverflowError e ) { | ||
| + error( "Unresolvable: " + node.textValue() + " = " + fieldValue ); | ||
| + } | ||
| + } | ||
| + } | ||
| + } | ||
| + | ||
| + /** | ||
| + * Inserts the delimited references and field values into the cache. This will | ||
| + * overwrite existing references. | ||
| + * | ||
| + * @param fieldValue YAML field containing zero or more delimited references. | ||
| + * If it contains a delimited reference, the parameter is | ||
| + * modified with the | ||
| + * dereferenced value before it is returned. | ||
| + * @return fieldValue without delimited references. | ||
| + */ | ||
| + private String resolve( String fieldValue ) { | ||
| + final Matcher matcher = patternMatch( fieldValue ); | ||
| + | ||
| + while( matcher.find() ) { | ||
| + final String delimited = matcher.group( GROUP_DELIMITED ); | ||
| + final String reference = matcher.group( GROUP_REFERENCE ); | ||
| + final String dereference = resolve( lookup( reference ) ); | ||
| + | ||
| + fieldValue = fieldValue.replace( delimited, dereference ); | ||
| + | ||
| + // This will perform some superfluous calls by overwriting existing | ||
| + // items in the delimited reference map. | ||
| + put( delimited, dereference ); | ||
| + } | ||
| + | ||
| + return fieldValue; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Inserts a key/value pair into the references map. The map retains | ||
| + * references and dereferenced values found in the YAML. If the reference | ||
| + * already exists, this will overwrite with a new value. | ||
| + * | ||
| + * @param delimited The variable name. | ||
| + * @param dereferenced The resolved value. | ||
| + */ | ||
| + private void put( String delimited, String dereferenced ) { | ||
| + if( dereferenced.isEmpty() ) { | ||
| + missing( delimited ); | ||
| + } | ||
| + else { | ||
| + getReferences().put( delimited, dereferenced ); | ||
| + } | ||
| + } | ||
| + | ||
| + /** | ||
| + * Reads the first YAML document from the input stream. | ||
| + * | ||
| + * @param in The YAML contents. | ||
| + * @return The root node for the YAML document. | ||
| + * @throws IOException Could not read the stream. | ||
| + */ | ||
| + private ObjectNode readDocument( final InputStream in ) throws IOException { | ||
| + setDocumentRoot( (ObjectNode) createObjectMapper().readTree( in ) ); | ||
| + return getDocumentRoot(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Writes the modified YAML document to standard output. | ||
| + */ | ||
| + private void writeDocument() throws IOException { | ||
| + createObjectMapper().writeValue( System.out, getDocumentRoot() ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Called when a delimited reference is dereferenced to an empty string. | ||
| + * | ||
| + * @param delimited Delimited reference with no derived value. | ||
| + */ | ||
| + private void missing( final String delimited ) { | ||
| + warn( String.format( "Missing '%s'.", delimited ) ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Called by all methods that log information. | ||
| + * | ||
| + * @param level The level string (WARN/ERROR). | ||
| + * @param message The message to log. | ||
| + */ | ||
| + private void log( String level, String message ) { | ||
| + getConfiguration().log( String.format( "[%s] %s", level, message ) ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Called by all methods that log warning information. | ||
| + * | ||
| + * @param message The text to log to standard error. | ||
| + */ | ||
| + private void warn( String message ) { | ||
| + log( "WARN", message ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Called by all methods that log error information. | ||
| + * | ||
| + * @param message The text to log to standard error. | ||
| + */ | ||
| + private void error( String message ) { | ||
| + log( "ERROR", message ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns a pattern matcher for the given text. | ||
| + * | ||
| + * @param text The text that contains zero or more instances of a pattern that | ||
| + * can be found using the regular expression. | ||
| + */ | ||
| + private Matcher patternMatch( String text ) { | ||
| + return getPattern().matcher( text ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Finds the YAML value for a reference. | ||
| + * | ||
| + * @param reference References a value in the YAML document. | ||
| + * @return The dereferenced value. | ||
| + */ | ||
| + private String lookup( final String reference ) { | ||
| + return getDocumentRoot().at( asPath( reference ) ).asText(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Sets the parent node for the entire YAML document tree. | ||
| + * | ||
| + * @param documentRoot The parent node. | ||
| + */ | ||
| + private void setDocumentRoot( ObjectNode documentRoot ) { | ||
| + this.documentRoot = documentRoot; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the parent node for the entire YAML document tree. | ||
| + * | ||
| + * @return The parent node. | ||
| + */ | ||
| + public ObjectNode getDocumentRoot() { | ||
| + return this.documentRoot; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the compiled regular expression pattern used to match delimited | ||
| + * references. | ||
| + * | ||
| + * @return A compiled regex for use with the Matcher. | ||
| + */ | ||
| + private Pattern getPattern() { | ||
| + if( this.pattern == null ) { | ||
| + this.pattern = Pattern.compile( getRegex() ); | ||
| + } | ||
| + | ||
| + return this.pattern; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the list of references mapped to dereferenced values. | ||
| + * | ||
| + * @return A map of key/value pairs. | ||
| + */ | ||
| + private Map<String, String> getReferences() { | ||
| + if( this.references == null ) { | ||
| + this.references = createReferences(); | ||
| + } | ||
| + | ||
| + return this.references; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Converts a reference (not delimited) to a path that can be used to find a | ||
| + * value that should exist inside the YAML document. | ||
| + * | ||
| + * @param reference The reference to convert to a YAML document path. | ||
| + * @return The reference with a leading slash and its separator characters | ||
| + * converted to slashes. | ||
| + */ | ||
| + private String asPath( final String reference ) { | ||
| + return SEPARATOR_YAML + reference.replace( | ||
| + getDelimitedSeparator(), | ||
| + SEPARATOR_YAML ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Subclasses can override this method to insert their own map. | ||
| + * | ||
| + * @return An empty HashMap, never null. | ||
| + */ | ||
| + protected Map<String, String> createReferences() { | ||
| + return new HashMap<>(); | ||
| + } | ||
| + | ||
| + private YAMLFactory createYAMLFactory() { | ||
| + return new ResolverYAMLFactory( this ); | ||
| + } | ||
| + | ||
| + private ObjectMapper createObjectMapper() { | ||
| + return new ObjectMapper( createYAMLFactory() ); | ||
| + } | ||
| + | ||
| + private String getRegex() { | ||
| + return getConfiguration().getRegex(); | ||
| + } | ||
| + | ||
| + private char getDelimitedSeparator() { | ||
| + return getConfiguration().getSeparator(); | ||
| } | ||
| -/* | ||
| - * The MIT License | ||
| - * | ||
| - * Copyright 2017 White Magic Software, Ltd.. | ||
| - * | ||
| - * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| - * of this software and associated documentation files (the "Software"), to deal | ||
| - * in the Software without restriction, including without limitation the rights | ||
| - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| - * copies of the Software, and to permit persons to whom the Software is | ||
| - * furnished to do so, subject to the following conditions: | ||
| - * | ||
| - * The above copyright notice and this permission notice shall be included in | ||
| - * all copies or substantial portions of the Software. | ||
| - * | ||
| - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| - * THE SOFTWARE. | ||
| - */ | ||
| -package com.whitemagicsoftware.yamlp.resolvers; | ||
| - | ||
| -import com.fasterxml.jackson.dataformat.xml.XmlFactory; | ||
| -import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; | ||
| -import com.whitemagicsoftware.yamlp.parser.YamlParser; | ||
| -import java.io.IOException; | ||
| -import java.io.Writer; | ||
| - | ||
| -/** | ||
| - * Responsible for instantiating a resolver generator that can intercept | ||
| - * document value writes. | ||
| - * | ||
| - * @author White Magic Software, Ltd. | ||
| - */ | ||
| -public final class ResolverXmlFactory extends XmlFactory { | ||
| - | ||
| - private static final long serialVersionUID = 1L; | ||
| - | ||
| - private YamlParser yamlParser; | ||
| - | ||
| - public ResolverXmlFactory( final YamlParser yamlParser ) { | ||
| - setYamlParser( yamlParser ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public ToXmlGenerator createGenerator( Writer out ) throws IOException { | ||
| - return new ToXmlGenerator( | ||
| - _createContext( out, false ), | ||
| - _generatorFeatures, | ||
| - _xmlGeneratorFeatures, | ||
| - _objectCodec, | ||
| - _createXmlWriter( out ) | ||
| - ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the YAML parser used when constructing this instance. | ||
| - * | ||
| - * @return A non-null instance. | ||
| - */ | ||
| - private YamlParser getYamlParser() { | ||
| - return this.yamlParser; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Sets the YAML parser used when constructing this instance. | ||
| - * | ||
| - * @param yamlParser A non-null instance. | ||
| - */ | ||
| - private void setYamlParser( final YamlParser yamlParser ) { | ||
| - this.yamlParser = yamlParser; | ||
| - } | ||
| -} | ||
| -/* | ||
| - * The MIT License | ||
| - * | ||
| - * Copyright 2017 White Magic Software, Ltd.. | ||
| - * | ||
| - * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| - * of this software and associated documentation files (the "Software"), to deal | ||
| - * in the Software without restriction, including without limitation the rights | ||
| - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| - * copies of the Software, and to permit persons to whom the Software is | ||
| - * furnished to do so, subject to the following conditions: | ||
| - * | ||
| - * The above copyright notice and this permission notice shall be included in | ||
| - * all copies or substantial portions of the Software. | ||
| - * | ||
| - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| - * THE SOFTWARE. | ||
| - */ | ||
| -package com.whitemagicsoftware.yamlp.resolvers; | ||
| - | ||
| -import com.fasterxml.jackson.dataformat.xml.XmlMapper; | ||
| -import com.whitemagicsoftware.yamlp.parser.YamlParser; | ||
| -import java.io.IOException; | ||
| -import javax.xml.stream.XMLStreamWriter; | ||
| - | ||
| -/** | ||
| - * @author White Magic Software, Ltd. | ||
| - */ | ||
| -public final class ResolverXmlMapper extends XmlMapper { | ||
| - | ||
| - private YamlParser yamlParser; | ||
| - | ||
| - public ResolverXmlMapper( final YamlParser yamlParser ) { | ||
| - setYamlParser( yamlParser ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public void writeValue( final XMLStreamWriter output, final Object value ) | ||
| - throws IOException { | ||
| - super.writeValue( output, getYamlParser().substitute( value.toString() ) ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the YAML parser used when constructing this instance. | ||
| - * | ||
| - * @return A non-null instance. | ||
| - */ | ||
| - private YamlParser getYamlParser() { | ||
| - return this.yamlParser; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Sets the YAML parser used when constructing this instance. | ||
| - * | ||
| - * @param yamlParser A non-null instance. | ||
| - */ | ||
| - private void setYamlParser( final YamlParser yamlParser ) { | ||
| - this.yamlParser = yamlParser; | ||
| - } | ||
| -} | ||
| package com.whitemagicsoftware.yamlp.resolvers; | ||
| -import com.fasterxml.jackson.core.JsonGenerationException; | ||
| import com.fasterxml.jackson.core.ObjectCodec; | ||
| import com.fasterxml.jackson.core.io.IOContext; | ||
| import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; | ||
| import com.whitemagicsoftware.yamlp.parser.YamlParser; | ||
| +import org.yaml.snakeyaml.DumperOptions; | ||
| + | ||
| import java.io.IOException; | ||
| import java.io.Writer; | ||
| -import org.yaml.snakeyaml.DumperOptions; | ||
| /** | ||
| public ResolverYAMLGenerator( | ||
| - final YamlParser yamlParser, | ||
| - final IOContext ctxt, | ||
| - final int jsonFeatures, | ||
| - final int yamlFeatures, | ||
| - final ObjectCodec codec, | ||
| - final Writer out, | ||
| - final DumperOptions.Version version ) throws IOException { | ||
| + final YamlParser yamlParser, | ||
| + final IOContext ctxt, | ||
| + final int jsonFeatures, | ||
| + final int yamlFeatures, | ||
| + final ObjectCodec codec, | ||
| + final Writer out, | ||
| + final DumperOptions.Version version ) throws IOException { | ||
| super( ctxt, jsonFeatures, yamlFeatures, codec, out, version ); | ||
| setYamlParser( yamlParser ); | ||
| } | ||
| @Override | ||
| - public void writeString( final String text ) | ||
| - throws IOException, JsonGenerationException { | ||
| + public void writeString( final String text ) throws IOException { | ||
| final YamlParser parser = getYamlParser(); | ||
| super.writeString( parser.substitute( text ) ); | ||
| Author | Dave Jarvis <email> |
|---|---|
| Date | 2020-05-19 17:42:38 GMT-0700 |
| Commit | 5307661d6251cc8dbccb0c2ee14f139cf3e0ad3f |
| Parent | f1a147f |
| Delta | 592 lines added, 888 lines removed, 296-line decrease |