| | package com.whitemagicsoftware.yamlp; |
| | |
| | -import com.fasterxml.jackson.databind.JsonNode; |
| | -import com.fasterxml.jackson.databind.ObjectMapper; |
| | -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; |
| | -import java.io.File; |
| | -import java.io.FileInputStream; |
| | -import java.io.IOException; |
| | -import java.io.InputStream; |
| | -import java.util.HashMap; |
| | -import java.util.Iterator; |
| | -import java.util.Map; |
| | -import java.util.regex.Matcher; |
| | -import java.util.regex.Pattern; |
| | -import org.kohsuke.args4j.CmdLineException; |
| | -import org.kohsuke.args4j.CmdLineParser; |
| | - |
| | -/** |
| | - * <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 Main { |
| | - |
| | - /** |
| | - * Map of references to dereferenced field values. |
| | - */ |
| | - private final Map<String, String> references = new HashMap<>(); |
| | - |
| | - /** |
| | - * Compiled regex. |
| | - */ |
| | - private Pattern pattern; |
| | - |
| | - /** |
| | - * Start of the Universe. |
| | - */ |
| | - private JsonNode documentRoot; |
| | - |
| | - /** |
| | - * Command-line options parsed using third-party library. |
| | - */ |
| | - private Configuration configuration; |
| | - |
| | - /** |
| | - * Constructs the application entry point with post-parsed command line |
| | - * options. |
| | - */ |
| | - private Main( Configuration configuration ) { |
| | - setConfiguration( configuration ); |
| | - } |
| | - |
| | - /** |
| | - * Runs before the processing begins. No default behaviour. |
| | - */ |
| | - public void preprocess() { |
| | - } |
| | - |
| | - /** |
| | - * Runs after processing ends. Checks |
| | - */ |
| | - public void postprocess() { |
| | - if( isShowVariables() ) { |
| | - Map<String, String> r = getReferences(); |
| | - |
| | - for( String key : r.keySet() ) { |
| | - stderr( key + " = " + r.get( key ) ); |
| | - } |
| | - } |
| | - } |
| | - |
| | - /** |
| | - * 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 { |
| | - process( getFilename() ); |
| | - } |
| | - |
| | - /** |
| | - * Open a file and process its YAML contents. The underlying file stream is |
| | - * closed on success or error. |
| | - * |
| | - * @param filename The file name to process. |
| | - * |
| | - * @throws IOException Could not read the file contents. |
| | - */ |
| | - public void process( final String filename ) throws IOException { |
| | - process( new File( filename ) ); |
| | - } |
| | - |
| | - /** |
| | - * Open a file and process its YAML contents. The underlying file stream is |
| | - * closed on success or error. |
| | - * |
| | - * @param file The file to process. |
| | - * |
| | - * @throws IOException Could not read the file contents. |
| | - */ |
| | - public void process( final File file ) throws IOException { |
| | - try( final InputStream in = new FileInputStream( file ) ) { |
| | - process( in ); |
| | - } |
| | - } |
| | - |
| | - /** |
| | - * 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( firstDocument( 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 ) { |
| | - final Iterator<Map.Entry<String, JsonNode>> fields = root.fields(); |
| | - |
| | - while( fields.hasNext() ) { |
| | - populateCache( fields.next() ); |
| | - } |
| | - } |
| | - |
| | - /** |
| | - * 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 JsonNode firstDocument( final InputStream in ) throws IOException { |
| | - final JsonNode root = new ObjectMapper( new YAMLFactory() ).readTree( in ); |
| | - setDocumentRoot( root ); |
| | - return root; |
| | - } |
| | - |
| | - /** |
| | - * Process the given field, which is a named node. |
| | - * |
| | - * @param field The named node. |
| | - */ |
| | - private void populateCache( final Map.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() ) { |
| | - resolve( fieldValue.asText() ); |
| | - } |
| | - } |
| | - } |
| | - |
| | - /** |
| | - * 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. |
| | - */ |
| | - private String resolve( String fieldValue ) { |
| | - final Matcher m = patternMatch( fieldValue ); |
| | - |
| | - while( m.find() ) { |
| | - final String delimited = m.group( 1 ); |
| | - final String reference = m.group( 2 ); |
| | - final String dereference = resolve( lookup( reference ) ); |
| | - |
| | - fieldValue = fieldValue.replace( delimited, dereference ); |
| | - |
| | - // This will probably perform a number of superfluous calls. |
| | - updateReferences( 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 reference The variable name. |
| | - * @param dereferenced The resolved value. |
| | - */ |
| | - private void updateReferences( String reference, String dereferenced ) { |
| | - if( dereferenced.isEmpty() ) { |
| | - missing( reference, dereferenced ); |
| | - } else { |
| | - getReferences().put( reference, dereferenced ); |
| | - } |
| | - } |
| | - |
| | - /** |
| | - * Called when a reference is dereferenced to an empty string. |
| | - * |
| | - * @param reference |
| | - * @param dereferenced |
| | - */ |
| | - private void missing( String reference, String dereferenced ) { |
| | - warn( String.format( "%s = '%s'", reference, dereferenced ) ); |
| | - } |
| | - |
| | - /** |
| | - * Called by all methods that log information. |
| | - * |
| | - * @param message The text to log to standard error. |
| | - */ |
| | - private void warn( String message ) { |
| | - getConfiguration().log( "[WARN] " + 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 value for a reference. |
| | - * |
| | - * @param reference The reference to a value. |
| | - * |
| | - * @return The dereferenced value. |
| | - */ |
| | - private String lookup( final String reference ) { |
| | - final String path = '/' + reference.replace( getSeparator(), '/' ); |
| | - return getDocumentRoot().at( path ).asText(); |
| | - } |
| | - |
| | - /** |
| | - * Sets the parent node for the entire YAML document tree. |
| | - * |
| | - * @param documentRoot The parent node. |
| | - */ |
| | - private void setDocumentRoot( JsonNode documentRoot ) { |
| | - this.documentRoot = documentRoot; |
| | - } |
| | - |
| | - /** |
| | - * Returns the parent node for the entire YAML document tree. |
| | - * |
| | - * @return The parent node. |
| | - */ |
| | - public JsonNode 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; |
| | - } |
| | - |
| | - private Map<String, String> getReferences() { |
| | - return this.references; |
| | - } |
| | - |
| | - private String getFilename() { |
| | - return getConfiguration().getFilename(); |
| | - } |
| | - |
| | - private String getRegex() { |
| | - return getConfiguration().getRegex(); |
| | - } |
| | - |
| | - private char getSeparator() { |
| | - return getConfiguration().getSeparator(); |
| | - } |
| | - |
| | - private boolean isLogging() { |
| | - return getConfiguration().isLogging(); |
| | - } |
| | - |
| | - private boolean isShowVariables() { |
| | - return getConfiguration().isShowVariables(); |
| | - } |
| | - |
| | - private void stderr( String message ) { |
| | - getConfiguration().stderr( message ); |
| | - } |
| | - |
| | - private Configuration getConfiguration() { |
| | - return this.configuration; |
| | - } |
| | - |
| | - private void setConfiguration( Configuration configuration ) { |
| | - this.configuration = configuration; |
| | - } |
| | - |
| | - /** |
| | - * Processes the YAML document specified on the command line. |
| | - * |
| | - * @param args Contains a filename. |
| | - */ |
| | - 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( configuration ); |
| | - main.preprocess(); |
| | - main.process(); |
| | - main.postprocess(); |
| | - } catch( CmdLineException | IOException e ) { |
| | - configuration.usage( clp ); |
| | +import com.fasterxml.jackson.core.JsonGenerationException; |
| | +import com.fasterxml.jackson.core.ObjectCodec; |
| | +import com.fasterxml.jackson.core.io.IOContext; |
| | +import com.fasterxml.jackson.databind.JsonNode; |
| | +import com.fasterxml.jackson.databind.ObjectMapper; |
| | +import com.fasterxml.jackson.databind.node.ObjectNode; |
| | +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; |
| | +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; |
| | +import java.io.File; |
| | +import java.io.FileInputStream; |
| | +import java.io.IOException; |
| | +import java.io.InputStream; |
| | +import java.io.Writer; |
| | +import java.util.HashMap; |
| | +import java.util.Map; |
| | +import java.util.Map.Entry; |
| | +import java.util.regex.Matcher; |
| | +import java.util.regex.Pattern; |
| | +import org.kohsuke.args4j.CmdLineException; |
| | +import org.kohsuke.args4j.CmdLineParser; |
| | +import org.yaml.snakeyaml.DumperOptions; |
| | + |
| | +/** |
| | + * <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 Main { |
| | + |
| | + /** |
| | + * Should be JsonPointer.SEPARATOR, but Jackson YAML uses magic values. |
| | + */ |
| | + private final static char SEPARATOR = '/'; |
| | + |
| | + private final static int GROUP_DELIMITED = 1; |
| | + private final static int GROUP_REFERENCE = 2; |
| | + |
| | + /** |
| | + * Map of references to dereferenced field values. |
| | + */ |
| | + private final Map<String, String> references = new HashMap<>(); |
| | + |
| | + /** |
| | + * Compiled regex. |
| | + */ |
| | + private Pattern pattern; |
| | + |
| | + /** |
| | + * Start of the Universe. |
| | + */ |
| | + private ObjectNode documentRoot; |
| | + |
| | + /** |
| | + * Command-line options parsed using third-party library. |
| | + */ |
| | + private Configuration configuration; |
| | + |
| | + /** |
| | + * Constructs the application entry point with post-parsed command line |
| | + * options. |
| | + */ |
| | + private Main( Configuration configuration ) { |
| | + setConfiguration( configuration ); |
| | + } |
| | + |
| | + /** |
| | + * 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(); |
| | + |
| | + if( isShowVariables() ) { |
| | + showVariables(); |
| | + } |
| | + } |
| | + |
| | + /** |
| | + * 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 { |
| | + process( getFilename() ); |
| | + } |
| | + |
| | + /** |
| | + * Open a file and process its YAML contents. The underlying file stream is |
| | + * closed on success or error. |
| | + * |
| | + * @param filename The file name to process. |
| | + * |
| | + * @throws IOException Could not read the file contents. |
| | + */ |
| | + public void process( final String filename ) throws IOException { |
| | + process( new File( filename ) ); |
| | + } |
| | + |
| | + /** |
| | + * Open a file and process its YAML contents. The underlying file stream is |
| | + * closed on success or error. |
| | + * |
| | + * @param file The file to process. |
| | + * |
| | + * @throws IOException Could not read the file contents. |
| | + */ |
| | + public void process( final File file ) throws IOException { |
| | + try( final InputStream in = new FileInputStream( file ) ) { |
| | + process( in ); |
| | + } |
| | + } |
| | + |
| | + /** |
| | + * 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() ) { |
| | + resolve( fieldValue.asText() ); |
| | + } |
| | + } |
| | + } |
| | + |
| | + /** |
| | + * 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 ); |
| | + } |
| | + } |
| | + |
| | + /** |
| | + * 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. |
| | + */ |
| | + private 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; |
| | + } |
| | + |
| | + /** |
| | + * 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 { |
| | + getObjectMapper().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 message The text to log to standard error. |
| | + */ |
| | + private void warn( String message ) { |
| | + getConfiguration().log( "[WARN] " + 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(); |
| | + } |
| | + |
| | + /** |
| | + * 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 + reference.replace( getDelimitedSeparator(), SEPARATOR ); |
| | + } |
| | + |
| | + /** |
| | + * 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() { |
| | + return this.references; |
| | + } |
| | + |
| | + private class ResolverYAMLFactory extends YAMLFactory { |
| | + |
| | + @Override |
| | + protected YAMLGenerator _createGenerator( |
| | + Writer out, IOContext ctxt ) throws IOException { |
| | + return new ResolverYAMLGenerator( |
| | + ctxt, _generatorFeatures, _yamlGeneratorFeatures, _objectCodec, |
| | + out, _version ); |
| | + } |
| | + } |
| | + |
| | + private class ResolverYAMLGenerator extends YAMLGenerator { |
| | + |
| | + public ResolverYAMLGenerator( |
| | + IOContext ctxt, |
| | + int jsonFeatures, |
| | + int yamlFeatures, |
| | + ObjectCodec codec, |
| | + Writer out, |
| | + DumperOptions.Version version ) throws IOException { |
| | + super( ctxt, jsonFeatures, yamlFeatures, codec, out, version ); |
| | + } |
| | + |
| | + @Override |
| | + public void writeString( String text ) |
| | + throws IOException, JsonGenerationException { |
| | + super.writeString( substitute( text ) ); |
| | + } |
| | + } |
| | + |
| | + private YAMLFactory getYAMLFactory() { |
| | + return new ResolverYAMLFactory(); |
| | + } |
| | + |
| | + private ObjectMapper getObjectMapper() { |
| | + return new ObjectMapper( getYAMLFactory() ); |
| | + } |
| | + |
| | + private String getFilename() { |
| | + return getConfiguration().getFilename(); |
| | + } |
| | + |
| | + 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 ); |
| | + } |
| | + |
| | + private Configuration getConfiguration() { |
| | + return this.configuration; |
| | + } |
| | + |
| | + private void setConfiguration( Configuration configuration ) { |
| | + this.configuration = configuration; |
| | + } |
| | + |
| | + /** |
| | + * Processes the YAML document specified on the command line. |
| | + * |
| | + * @param args Contains a filename. |
| | + */ |
| | + 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( configuration ); |
| | + main.preprocess(); |
| | + main.process(); |
| | + main.postprocess(); |
| | + } catch( CmdLineException e ) { |
| | + configuration.usage( clp ); |
| | + } catch( IOException e ) { |
| | + configuration.log( e.getLocalizedMessage() ); |
| | } |
| | } |