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

com.amazon.ion.system.IonTextWriterBuilder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2007-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package com.amazon.ion.system;

import static com.amazon.ion.system.IonWriterBuilder.InitialIvmHandling.SUPPRESS;

import com.amazon.ion.IonCatalog;
import com.amazon.ion.IonWriter;
import com.amazon.ion.SymbolTable;
import com.amazon.ion.Timestamp;
import com.amazon.ion.impl._Private_IonTextWriterBuilder;
import com.amazon.ion.impl._Private_Utils;
import java.io.OutputStream;
import java.nio.charset.Charset;

/**
 * The builder for creating {@link IonWriter}s emitting the Ion text syntax.
 * 

* WARNING: This class should not be extended by code outside of * this library. *

* Builders may be configured once and reused to construct multiple * objects. *

* Instances of this class are not not safe for use by multiple threads * unless they are {@linkplain #immutable() immutable}. *

* The most general and correct approach is to use the {@link #standard()} * builder: *

 *    IonWriter w = IonTextWriterBuilder.standard().build(outputStream);
 *
* The standard configuration gives a direct representation of what's written, * including version markers and local symbol tables. That's good for * diagnostics but it may be more than you want in many situations. * In such cases the {@link #minimal()} or {@link #pretty()} builders (or a * combination) may give more satisfying output: *
 *    IonWriter w = IonTextWriterBuilder.minimal()
 *                                      .withPrettyPrinting()
 *                                      .build(outputStream);
 *
* *

* Configuration properties follow the standard JavaBeans idiom in order to be * friendly to dependency injection systems. They also provide alternative * {@code with...()} mutation methods that enable a more fluid style. * *

Auto-flushing

* * {@link IonWriter}s created by this builder auto-flush to the * underlying data sink after writing each top-level value in the context of * the writer. *

* Currently, there is no configuration point available to disable the * auto-flushing mechanism. Please vote on * issue amazon-ion/ion-java/issues/32 * if you require it. * */ public abstract class IonTextWriterBuilder extends IonWriterBuilderBase { /** * A strategy for minimizing the output of local symbol tables. * By default, no minimization takes place and the writer outputs all data * as-is. * */ public enum LstMinimizing { /** * Discards local symbols, retains imports. */ LOCALS, /* TODO Discards local symbols and imports, retains open content. * This isn't implemented yet, because our symtab implmentations don't * support open content (so it would work the same as EVERYTHING). */ // IMPORTS, /** * Discards everything, collapsing the LST to an IVM. * If {@link com.amazon.ion.system.IonWriterBuilder.IvmMinimizing} * is also in effect, then even that IVM may be suppressed. * * @see IonTextWriterBuilder#setIvmMinimizing(IonWriterBuilder.IvmMinimizing) */ EVERYTHING } /** * The {@code "US-ASCII"} charset. */ public static final Charset ASCII = _Private_Utils.ASCII_CHARSET; /** * The {@code "UTF-8"} charset. */ public static final Charset UTF8 = _Private_Utils.UTF8_CHARSET; /** * Represents common new-line separators that are valid in Ion. * * Unicode defines several characters that can represent a new line, but only carriage return (CR) and linefeed (LF) are valid whitespace in Ion. * Using other new-line characters (such as {@code NEL}) will result in printing invalid Ion. */ public enum NewLineType { /** * A carriage return and linefeed ({@code U+000D} followed by {@code U+000A}). */ CRLF("\r\n"), /** * A single linefeed ({@code U+000A}). */ LF("\n"), /** * The new-line separator specified in the "line.separator" system property. * Using this will result in writing invalid Ion if the platform uses anything other than CR and/or LF as the line separator * and the IonTextWriter is configured to use pretty printing or to write each top-level value on a separate line. */ PLATFORM_DEPENDENT(System.getProperty("line.separator")); private final CharSequence charSequence; NewLineType(CharSequence cs) { this.charSequence = cs; } public CharSequence getCharSequence() { return charSequence; } } /** * The standard builder of text {@link IonWriter}s, with all configuration * properties having their default values. The resulting output is a * direct representation of what's written to the writer, including * version markers and local symbol tables. * * @return a new, mutable builder instance. * * @see #minimal() * @see #pretty() * @see #json() */ public static IonTextWriterBuilder standard() { return _Private_IonTextWriterBuilder.standard(); } /** * Creates a builder configured to minimize system data, eliminating local * symbol tables and minimizing version markers. * * @return a new, mutable builder instance. * * @see #withMinimalSystemData() * */ public static IonTextWriterBuilder minimal() { return standard().withMinimalSystemData(); } /** * Creates a builder preconfigured for basic pretty-printing. *

* The specifics of this configuration may change between releases of this * library, so automated processes should not depend on the exact output * formatting. In particular, there's currently no promise regarding * handling of system data. * * @return a new, mutable builder instance. * * @see #withPrettyPrinting() */ public static IonTextWriterBuilder pretty() { return standard().withPrettyPrinting(); } /** * Creates a builder preconfigured for JSON compatibility. * * @return a new, mutable builder instance. * * @see #withJsonDowngrade() */ public static IonTextWriterBuilder json() { return standard().withJsonDowngrade(); } //========================================================================= // Config points: // * Default IVM // * Re-use same imports after a finish // * Indentation CharSeq private Charset myCharset; private InitialIvmHandling myInitialIvmHandling; private IvmMinimizing myIvmMinimizing; private LstMinimizing myLstMinimizing; private int myLongStringThreshold; private NewLineType myNewLineType; private boolean myTopLevelValuesOnNewLines; private int myMaximumTimestampPrecisionDigits = Timestamp.DEFAULT_MAXIMUM_DIGITS_TEXT; /** NOT FOR APPLICATION USE! */ protected IonTextWriterBuilder() { } /** NOT FOR APPLICATION USE! */ protected IonTextWriterBuilder(IonTextWriterBuilder that) { super(that); this.myCharset = that.myCharset; this.myInitialIvmHandling = that.myInitialIvmHandling; this.myIvmMinimizing = that.myIvmMinimizing; this.myLstMinimizing = that.myLstMinimizing; this.myLongStringThreshold = that.myLongStringThreshold; this.myNewLineType = that.myNewLineType; this.myTopLevelValuesOnNewLines = that.myTopLevelValuesOnNewLines; this.myMaximumTimestampPrecisionDigits = that.myMaximumTimestampPrecisionDigits; } //========================================================================= // Overrides to fix the return type in JavaDocs @Override public abstract IonTextWriterBuilder copy(); @Override public abstract IonTextWriterBuilder immutable(); @Override public abstract IonTextWriterBuilder mutable(); @Override public final IonTextWriterBuilder withCatalog(IonCatalog catalog) { return super.withCatalog(catalog); } @Override public final IonTextWriterBuilder withImports(SymbolTable... imports) { return super.withImports(imports); } //------------------------------------------------------------------------- /** * Gets the charset denoting the output encoding. * Only ASCII and UTF-8 are supported. * * @return may be null, denoting the default of UTF-8. * * @see #setCharset(Charset) * @see #withCharset(Charset) */ public final Charset getCharset() { return myCharset; } /** * Sets the charset denoting the output encoding. * Only ASCII and UTF-8 are supported; applications can use the helper * constants {@link #ASCII} and {@link #UTF8}. * * @param charset may be null, denoting the default of UTF-8. * * @see #getCharset() * @see #withCharset(Charset) * * @throws UnsupportedOperationException if this is immutable. */ public void setCharset(Charset charset) { mutationCheck(); if (charset == null || charset.equals(ASCII) || charset.equals(UTF8)) { myCharset = charset; } else { throw new IllegalArgumentException("Unsupported Charset " + charset); } } /** * Declares the charset denoting the output encoding, * returning a new mutable builder if this is immutable. * Only ASCII and UTF-8 are supported; applications can use the helper * constants {@link #ASCII} and {@link #UTF8}. * * @param charset may be null, denoting the default of UTF-8. * * @return this instance, if mutable; * otherwise a mutable copy of this instance. * * @see #getCharset() * @see #setCharset(Charset) */ public final IonTextWriterBuilder withCharset(Charset charset) { IonTextWriterBuilder b = mutable(); b.setCharset(charset); return b; } /** * Declares the output encoding to be {@code US-ASCII}. * * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ public final IonTextWriterBuilder withCharsetAscii() { return withCharset(ASCII); } //------------------------------------------------------------------------- /** * Declares that this builder should minimize system-level output * (Ion version markers and local symbol tables). *

* This is equivalent to: *

    *
  • {@link #setInitialIvmHandling(IonWriterBuilder.InitialIvmHandling) * setInitialIvmHandling}{@code (}{@link IonWriterBuilder.InitialIvmHandling#SUPPRESS SUPPRESS}{@code )} *
  • {@link #setIvmMinimizing(IonWriterBuilder.IvmMinimizing) * setIvmMinimizing}{@code (}{@link IonWriterBuilder.IvmMinimizing#DISTANT DISTANT}{@code )} *
  • {@link #setLstMinimizing(LstMinimizing) * setLstMinimizing}{@code (}{@link LstMinimizing#EVERYTHING EVERYTHING}{@code )} *
* * @return this instance, if mutable; * otherwise a mutable copy of this instance. * */ public final IonTextWriterBuilder withMinimalSystemData() { IonTextWriterBuilder b = mutable(); b.setInitialIvmHandling(SUPPRESS); b.setIvmMinimizing(IvmMinimizing.DISTANT); b.setLstMinimizing(LstMinimizing.EVERYTHING); return b; } /** * Declares that this builder should use basic pretty-printing. * Does not alter the handling of system data. * Calling this method alters several other configuration properties, * so code should call it first, then make any necessary overrides. *

* The specifics of this configuration may change between releases of this * library, so automated processes should not depend on the exact output * formatting. * * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ public abstract IonTextWriterBuilder withPrettyPrinting(); /** * Declares that this builder should downgrade the writers' output to * JSON compatibility. This format cannot round-trip back to Ion with full * fidelity. *

* The specific conversions are as follows: *

    *
  • System data is suppressed per {@link #withMinimalSystemData()}. *
  • All annotations are suppressed. *
  • Nulls of any type are printed as JSON {@code null}. *
  • Blobs are printed as strings, containing Base64. *
  • Clobs are printed as strings, containing only Unicode code points * U+00 through U+FF. *
  • Sexps are printed as lists. *
  • Symbols are printed as strings. *
  • Timestamps are printed as strings, using Ion timestamp format. *
* * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ public abstract IonTextWriterBuilder withJsonDowngrade(); //------------------------------------------------------------------------- /** * {@inheritDoc} * * @return the initial IVM strategy. * The default value ({@code null}) indicates that an initial IVM is * emitted if and only if it is received by the writer. * * @see #setInitialIvmHandling(IonWriterBuilder.InitialIvmHandling) * @see #withInitialIvmHandling(IonWriterBuilder.InitialIvmHandling) */ @Override public final InitialIvmHandling getInitialIvmHandling() { return myInitialIvmHandling; } /** * Sets the strategy for emitting Ion version markers at the start * of the stream. By default, IVMs are emitted only when explicitly * written or when necessary (for example, before data that's not Ion 1.0). * * @param handling the initial IVM strategy. * Null indicates that explicitly-written IVMs will be emitted. * * @see #getInitialIvmHandling() * @see #withInitialIvmHandling(IonWriterBuilder.InitialIvmHandling) * * @throws UnsupportedOperationException if this is immutable. */ public void setInitialIvmHandling(InitialIvmHandling handling) { mutationCheck(); myInitialIvmHandling = handling; } /** * Declares the strategy for emitting Ion version markers at the start * of the stream, returning a new mutable builder if this is immutable. * By default, IVMs are emitted only when explicitly * written or when necessary (for example, before data that's not Ion 1.0). * * @param handling the initial IVM strategy. * Null indicates that explicitly-written IVMs will be emitted. * * @return this instance, if mutable; * otherwise a mutable copy of this instance. * * @see #setInitialIvmHandling(IonWriterBuilder.InitialIvmHandling) * @see #withInitialIvmHandling(IonWriterBuilder.InitialIvmHandling) */ public final IonTextWriterBuilder withInitialIvmHandling(InitialIvmHandling handling) { IonTextWriterBuilder b = mutable(); b.setInitialIvmHandling(handling); return b; } //------------------------------------------------------------------------- /** * {@inheritDoc} * * @return the IVM minimizing strategy. * The default value ({@code null}) indicates that no minimization occurs * and IVMs are emitted as received by the writer. * * @see #setIvmMinimizing(IonWriterBuilder.IvmMinimizing) * @see #withIvmMinimizing(IonWriterBuilder.IvmMinimizing) * */ @Override public final IvmMinimizing getIvmMinimizing() { return myIvmMinimizing; } /** * Sets the strategy for reducing or eliminating non-initial Ion version * markers. When null, IVMs are emitted as they are written. * * @param minimizing the IVM minimization strategy. * Null indicates that all explicitly-written IVMs will be emitted. * * @see #getIvmMinimizing() * @see #withIvmMinimizing(IonWriterBuilder.IvmMinimizing) * * @throws UnsupportedOperationException if this is immutable. * */ public void setIvmMinimizing(IvmMinimizing minimizing) { mutationCheck(); myIvmMinimizing = minimizing; } /** * Declares the strategy for reducing or eliminating non-initial Ion version * markers, returning a new mutable builder if this is immutable. * When null, IVMs are emitted as they are written. * * @param minimizing the IVM minimization strategy. * Null indicates that all explicitly-written IVMs will be emitted. * * @return this instance, if mutable; * otherwise a mutable copy of this instance. * * @see #setIvmMinimizing(IonWriterBuilder.IvmMinimizing) * @see #getIvmMinimizing() * */ public final IonTextWriterBuilder withIvmMinimizing(IvmMinimizing minimizing) { IonTextWriterBuilder b = mutable(); b.setIvmMinimizing(minimizing); return b; } //------------------------------------------------------------------------- /** * Gets the strategy for reducing or eliminating local symbol tables. * By default, LST data is emitted as received or when necessary * (for example, binary data will always collect and emit local symbols). * * @see #setLstMinimizing(LstMinimizing) * @see #withLstMinimizing(LstMinimizing) * */ public final LstMinimizing getLstMinimizing() { return myLstMinimizing; } /** * Sets the strategy for reducing or eliminating local symbol tables. * By default, LST data is emitted as received or when necessary * (for example, binary data will always collect and emit local symbols). * * @param minimizing the LST minimization strategy. * Null indicates that LSTs will be emitted as received. * * @see #getLstMinimizing() * @see #withLstMinimizing(LstMinimizing) * * @throws UnsupportedOperationException if this is immutable. * */ public void setLstMinimizing(LstMinimizing minimizing) { mutationCheck(); myLstMinimizing = minimizing; } /** * Sets the strategy for reducing or eliminating local symbol tables. * By default, LST data is emitted as received or when necessary * (for example, binary data will always collect and emit local symbols). * * @param minimizing the LST minimization strategy. * Null indicates that LSTs will be emitted as received. * * @return this instance, if mutable; * otherwise a mutable copy of this instance. * * @see #getLstMinimizing() * @see #setLstMinimizing(LstMinimizing) * */ public final IonTextWriterBuilder withLstMinimizing(LstMinimizing minimizing) { IonTextWriterBuilder b = mutable(); b.setLstMinimizing(minimizing); return b; } //------------------------------------------------------------------------- /** * Gets the length beyond which string and clob content will be rendered * as triple-quoted "long strings". * At present, such content will only line-break on extant newlines. * * @return the threshold for printing triple-quoted strings and clobs. * Zero means no limit. * * @see #setLongStringThreshold(int) * @see #withLongStringThreshold(int) */ public final int getLongStringThreshold() { return myLongStringThreshold; } /** * Sets the length beyond which string and clob content will be rendered * as triple-quoted "long strings". * At present, such content will only line-break on extant newlines. * * @param threshold the new threshold; zero means none. * * @see #getLongStringThreshold() * @see #withLongStringThreshold(int) * * @throws UnsupportedOperationException if this is immutable. */ public void setLongStringThreshold(int threshold) { mutationCheck(); myLongStringThreshold = threshold; } /** * Declares the length beyond which string and clob content will be rendered * as triple-quoted "long strings". * At present, such content will only line-break on extant newlines. * * @param threshold the new threshold; zero means none. * * @see #getLongStringThreshold() * @see #setLongStringThreshold(int) * * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ public final IonTextWriterBuilder withLongStringThreshold(int threshold) { IonTextWriterBuilder b = mutable(); b.setLongStringThreshold(threshold); return b; } //========================================================================= /** * Gets the character sequence that will be written as a line separator. * The default is {@link NewLineType#PLATFORM_DEPENDENT} * * @return the character sequence to be written between top-level values; null means the default should be used. * * @see #setNewLineType(NewLineType) * @see #withNewLineType(NewLineType) */ public final NewLineType getNewLineType() { return myNewLineType; } /** * Sets the character sequence that will be written as a line separator. * The default is {@link NewLineType#PLATFORM_DEPENDENT} * * @param newLineType the character sequence to be written between top-level values; null means the default should be used. * * @see #getNewLineType() * @see #withNewLineType(NewLineType) * * @throws UnsupportedOperationException if this is immutable. */ public void setNewLineType(NewLineType newLineType) { mutationCheck(); this.myNewLineType = newLineType; } /** * Declares the character sequence that will be written as a line separator. * The default is {@link NewLineType#PLATFORM_DEPENDENT} * * @param newLineType the character sequence to be written between top-level values; null means the default should be used. * * @see #getNewLineType() * @see #setNewLineType(NewLineType) * * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ public final IonTextWriterBuilder withNewLineType(NewLineType newLineType) { IonTextWriterBuilder b = mutable(); b.setNewLineType(newLineType); return b; } //========================================================================= /** * Gets whether each top level value for standard printing should start on a new line. The default value is {@code false}. * When false, the IonTextWriter will insert a single space character (U+0020) between top-level values. * When pretty-printing, this setting is ignored; the pretty printer will always start top-level values on a new line. * * @return value indicating whether standard printing will insert a newline between top-level values * * @see #setWriteTopLevelValuesOnNewLines(boolean) * @see #withWriteTopLevelValuesOnNewLines(boolean) */ public final boolean getWriteTopLevelValuesOnNewLines() { return myTopLevelValuesOnNewLines; } /** * Sets whether each top level value for standard printing should start on a new line. The default value is {@code false}. * When false, the IonTextWriter will insert a single space character (U+0020) between top-level values. * When pretty-printing, this setting is ignored; the pretty printer will always start top-level values on a new line. * * @param writeTopLevelValuesOnNewLines value indicating whether standard printing will insert a newline between top-level values * * @see #getWriteTopLevelValuesOnNewLines() * @see #withWriteTopLevelValuesOnNewLines(boolean) */ public void setWriteTopLevelValuesOnNewLines(boolean writeTopLevelValuesOnNewLines) { mutationCheck(); myTopLevelValuesOnNewLines = writeTopLevelValuesOnNewLines; } /** * Declares whether each top level value for standard printing should start on a new line. The default value is {@code false}. * When false, the IonTextWriter will insert a single space character (U+0020) between top-level values. * When pretty-printing, this setting is ignored; the pretty printer will always start top-level values on a new line. * * @param writeTopLevelValuesOnNewLines value indicating whether standard printing will insert a newline between top-level values * * @see #getWriteTopLevelValuesOnNewLines() * @see #setWriteTopLevelValuesOnNewLines(boolean) */ public final IonTextWriterBuilder withWriteTopLevelValuesOnNewLines(boolean writeTopLevelValuesOnNewLines) { IonTextWriterBuilder b = mutable(); b.setWriteTopLevelValuesOnNewLines(writeTopLevelValuesOnNewLines); return b; } //========================================================================= /** * Gets the maximum number of digits of fractional second precision allowed to be written for timestamp values. * * @return the currently configured maximum. * * @see #setMaximumTimestampPrecisionDigits(int) * @see #withMaximumTimestampPrecisionDigits(int) */ public final int getMaximumTimestampPrecisionDigits() { return myMaximumTimestampPrecisionDigits; } /** * Sets the maximum number of digits of fractional second precision allowed to be written for timestamp values. * Default: {@link Timestamp#DEFAULT_MAXIMUM_DIGITS_TEXT}. * * @see #getMaximumTimestampPrecisionDigits() * @see #withMaximumTimestampPrecisionDigits(int) */ public void setMaximumTimestampPrecisionDigits(int maximumTimestampPrecisionDigits) { mutationCheck(); myMaximumTimestampPrecisionDigits = maximumTimestampPrecisionDigits; } /** * Sets the maximum number of digits of fractional second precision allowed to be written for timestamp values. * Default: {@link Timestamp#DEFAULT_MAXIMUM_DIGITS_TEXT}. * * @return this instance, if mutable; otherwise a mutable copy of this instance. * * @see #getMaximumTimestampPrecisionDigits() * @see #setMaximumTimestampPrecisionDigits(int) */ public final IonTextWriterBuilder withMaximumTimestampPrecisionDigits(int maximumTimestampPrecisionDigits) { IonTextWriterBuilder b = mutable(); b.setMaximumTimestampPrecisionDigits(maximumTimestampPrecisionDigits); return b; } //========================================================================= /** * Creates a new writer that will write text to the given output * stream. *

* If you have an {@link OutputStream}, you'll get better performance using * {@link #build(OutputStream)} as opposed to wrapping your stream in an * {@link Appendable} and calling this method. * * @param out the stream that will receive Ion text data. * Must not be null. * * @return a new {@link IonWriter} instance; not {@code null}. */ public abstract IonWriter build(Appendable out); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy