diff --git a/src/main/java/com/amazon/ion/IonEncodingVersion.java b/src/main/java/com/amazon/ion/IonEncodingVersion.java index 0d08dd6005..cc064915ec 100644 --- a/src/main/java/com/amazon/ion/IonEncodingVersion.java +++ b/src/main/java/com/amazon/ion/IonEncodingVersion.java @@ -2,8 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 package com.amazon.ion; +import com.amazon.ion.impl._Private_IonTextWriterBuilder_1_1; import com.amazon.ion.system.IonBinaryWriterBuilder; import com.amazon.ion.system.IonBinaryWriterBuilder_1_1; +import com.amazon.ion.system.IonTextWriterBuilder; +import com.amazon.ion.system.IonTextWriterBuilder_1_1; import com.amazon.ion.system._Private_IonBinaryWriterBuilder_1_1; /** @@ -15,30 +18,39 @@ * * @param the type of binary writer builder compatible with this version. */ -// TODO add a parameter for the text writer builder type; add a "textWriterBuilder()" method. -public abstract class IonEncodingVersion { +public abstract class IonEncodingVersion { /** * Ion 1.0, see the binary and * text specification. */ - public static IonEncodingVersion ION_1_0 = new IonEncodingVersion(0) { + public static IonEncodingVersion ION_1_0 = new IonEncodingVersion(0) { @Override public IonBinaryWriterBuilder binaryWriterBuilder() { return IonBinaryWriterBuilder.standard(); } + + @Override + public IonTextWriterBuilder textWriterBuilder() { + return IonTextWriterBuilder.standard(); + } }; /** * Ion 1.1, TODO link to the finalized specification. */ - public static IonEncodingVersion ION_1_1 = new IonEncodingVersion(1) { + public static IonEncodingVersion ION_1_1 = new IonEncodingVersion(1) { @Override public IonBinaryWriterBuilder_1_1 binaryWriterBuilder() { return _Private_IonBinaryWriterBuilder_1_1.standard(); } + + @Override + public IonTextWriterBuilder_1_1 textWriterBuilder() { + return _Private_IonTextWriterBuilder_1_1.standard(); + } }; private final int minorVersion; @@ -53,6 +65,12 @@ private IonEncodingVersion(int minorVersion) { */ public abstract BinaryWriterBuilder binaryWriterBuilder(); + /** + * Provides a new mutable text writer builder for IonWriter instances that write this version of the Ion encoding. + * @return a new mutable writer builder. + */ + public abstract TextWriterBuilder textWriterBuilder(); + @Override public String toString() { return String.format("Ion 1.%d", minorVersion); diff --git a/src/main/java/com/amazon/ion/impl/IonRawTextWriter_1_1.kt b/src/main/java/com/amazon/ion/impl/IonRawTextWriter_1_1.kt index 32727c76d2..4a947e8831 100644 --- a/src/main/java/com/amazon/ion/impl/IonRawTextWriter_1_1.kt +++ b/src/main/java/com/amazon/ion/impl/IonRawTextWriter_1_1.kt @@ -20,7 +20,7 @@ import java.time.Instant * - To make it easier to concatenate streams, this eagerly emits a top-level separator after each top-level syntax item. */ class IonRawTextWriter_1_1 internal constructor( - private val options: _Private_IonTextWriterBuilder, + private val options: _Private_IonTextWriterBuilder_1_1, private val output: _Private_IonTextAppender, ) : IonRawWriter_1_1 { diff --git a/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder.java b/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder.java index 9d8ae52c2a..b1f7c957ce 100644 --- a/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder.java +++ b/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder.java @@ -1,52 +1,24 @@ -/* - * 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. - */ - +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.impl; -import static com.amazon.ion.impl._Private_Utils.initialSymtab; -import com.amazon.ion.IonCatalog; -import com.amazon.ion.IonSystem; -import com.amazon.ion.IonWriter; -import com.amazon.ion.SymbolTable; -import com.amazon.ion.system.IonSystemBuilder; import com.amazon.ion.system.IonTextWriterBuilder; import com.amazon.ion.system.SimpleCatalog; -import com.amazon.ion.util._Private_FastAppendable; -import java.io.OutputStream; /** + * Contains configuration common to text writers for all Ion versions. * NOT FOR APPLICATION USE! */ -public class _Private_IonTextWriterBuilder +public abstract class _Private_IonTextWriterBuilder> extends IonTextWriterBuilder { private final static CharSequence SPACE_CHARACTER = " "; - public static _Private_IonTextWriterBuilder standard() - { - return new _Private_IonTextWriterBuilder.Mutable(); - } - - public static _Private_IonTextWriterBuilder STANDARD = - standard().immutable(); - //========================================================================= - private boolean _pretty_print; + public boolean _pretty_print; // These options control whether the IonTextWriter will write standard ion or ion that is down-converted json. public boolean _blob_as_string; @@ -62,15 +34,15 @@ public static _Private_IonTextWriterBuilder standard() public boolean _untyped_nulls; public boolean _allow_invalid_sids; - private _Private_CallbackBuilder _callback_builder; + public _Private_CallbackBuilder _callback_builder; - private _Private_IonTextWriterBuilder() + _Private_IonTextWriterBuilder() { super(); } - private _Private_IonTextWriterBuilder(_Private_IonTextWriterBuilder that) + _Private_IonTextWriterBuilder(T that) { super(that); this._callback_builder = that._callback_builder ; @@ -89,40 +61,35 @@ private _Private_IonTextWriterBuilder(_Private_IonTextWriterBuilder that) this._allow_invalid_sids = that._allow_invalid_sids ; } - @Override - public final _Private_IonTextWriterBuilder copy() - { - return new Mutable(this); - } + public abstract T copy(); @Override - public _Private_IonTextWriterBuilder immutable() + public T immutable() { - return this; + return (T) this; } @Override - public _Private_IonTextWriterBuilder mutable() + public T mutable() { return copy(); } - //========================================================================= @Override - public final IonTextWriterBuilder withPrettyPrinting() + public IonTextWriterBuilder withPrettyPrinting() { - _Private_IonTextWriterBuilder b = mutable(); + T b = mutable(); b._pretty_print = true; return b; } @Override - public final IonTextWriterBuilder withJsonDowngrade() + public IonTextWriterBuilder withJsonDowngrade() { - _Private_IonTextWriterBuilder b = mutable(); + T b = mutable(); b.withMinimalSystemData(); @@ -150,8 +117,8 @@ public final IonTextWriterBuilder withJsonDowngrade() * @param allowInvalidSids whether to allow invalid SIDs. * @return the builder. */ - public final _Private_IonTextWriterBuilder withInvalidSidsAllowed(boolean allowInvalidSids) { - _Private_IonTextWriterBuilder b = mutable(); + public final T withInvalidSidsAllowed(boolean allowInvalidSids) { + T b = mutable(); b._allow_invalid_sids = allowInvalidSids; return b; } @@ -179,7 +146,7 @@ final CharSequence topLevelSeparator() //========================================================================= - private _Private_IonTextWriterBuilder fillDefaults() + T fillDefaults() { // Ensure that we don't modify the user's builder. IonTextWriterBuilder b = copy(); @@ -206,87 +173,7 @@ private _Private_IonTextWriterBuilder fillDefaults() )); } - return (_Private_IonTextWriterBuilder) b.immutable(); - } - - - /** Assumes that {@link #fillDefaults()} has been called. */ - private IonWriter build(_Private_FastAppendable appender) - { - IonCatalog catalog = getCatalog(); - SymbolTable[] imports = getImports(); - - // TODO We shouldn't need a system here - IonSystem system = - IonSystemBuilder.standard().withCatalog(catalog).build(); - - SymbolTable defaultSystemSymtab = system.getSystemSymbolTable(); - - IonWriterSystemText systemWriter = - (getCallbackBuilder() == null - ? new IonWriterSystemText(defaultSystemSymtab, - this, - appender) - : new IonWriterSystemTextMarkup(defaultSystemSymtab, - this, - appender)); - - SymbolTable initialSymtab = - initialSymtab(((_Private_ValueFactory)system).getLstFactory(), defaultSystemSymtab, imports); - - return new IonWriterUser(catalog, system, systemWriter, initialSymtab, !_allow_invalid_sids); - } - - - @Override - public final IonWriter build(Appendable out) - { - _Private_IonTextWriterBuilder b = fillDefaults(); - - _Private_FastAppendable fast = new AppendableFastAppendable(out); - - return b.build(fast); - } - - - @Override - public final IonWriter build(OutputStream out) - { - _Private_IonTextWriterBuilder b = fillDefaults(); - - _Private_FastAppendable fast = new OutputStreamFastAppendable(out); - - return b.build(fast); - } - - //========================================================================= - - private static final class Mutable - extends _Private_IonTextWriterBuilder - { - private Mutable() { } - - private Mutable(_Private_IonTextWriterBuilder that) - { - super(that); - } - - @Override - public _Private_IonTextWriterBuilder immutable() - { - return new _Private_IonTextWriterBuilder(this); - } - - @Override - public _Private_IonTextWriterBuilder mutable() - { - return this; - } - - @Override - protected void mutationCheck() - { - } + return (T) b.immutable(); } //------------------------------------------------------------------------- @@ -328,10 +215,9 @@ public void setCallbackBuilder(_Private_CallbackBuilder builder) * @see #getCallbackBuilder() * @see #setCallbackBuilder(_Private_CallbackBuilder) */ - public final _Private_IonTextWriterBuilder - withCallbackBuilder(_Private_CallbackBuilder builder) + public final T withCallbackBuilder(_Private_CallbackBuilder builder) { - _Private_IonTextWriterBuilder b = mutable(); + T b = mutable(); b.setCallbackBuilder(builder); return b; } diff --git a/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder_1_0.java b/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder_1_0.java new file mode 100644 index 0000000000..5fbaf584e3 --- /dev/null +++ b/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder_1_0.java @@ -0,0 +1,124 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion.impl; + +import com.amazon.ion.IonCatalog; +import com.amazon.ion.IonSystem; +import com.amazon.ion.IonWriter; +import com.amazon.ion.SymbolTable; +import com.amazon.ion.system.IonSystemBuilder; +import com.amazon.ion.util._Private_FastAppendable; + +import java.io.OutputStream; + +import static com.amazon.ion.impl._Private_Utils.initialSymtab; + +/** + * Contains configuration for Ion 1.0 text writers. + * NOT FOR APPLICATION USE! + */ +public class _Private_IonTextWriterBuilder_1_0 extends _Private_IonTextWriterBuilder<_Private_IonTextWriterBuilder_1_0> { + + public static _Private_IonTextWriterBuilder_1_0 standard() + { + return new _Private_IonTextWriterBuilder_1_0.Mutable(); + } + + public static final _Private_IonTextWriterBuilder_1_0 STANDARD = standard().immutable(); + + private _Private_IonTextWriterBuilder_1_0() + { + super(); + } + + private _Private_IonTextWriterBuilder_1_0(_Private_IonTextWriterBuilder_1_0 that) + { + super(that); + } + + @Override + public final _Private_IonTextWriterBuilder_1_0 copy() + { + return new Mutable(this); + } + + + /** Assumes that {@link #fillDefaults()} has been called. */ + private IonWriter build(_Private_FastAppendable appender) + { + IonCatalog catalog = getCatalog(); + SymbolTable[] imports = getImports(); + + // TODO We shouldn't need a system here + IonSystem system = + IonSystemBuilder.standard().withCatalog(catalog).build(); + + SymbolTable defaultSystemSymtab = system.getSystemSymbolTable(); + + IonWriterSystemText systemWriter = + (getCallbackBuilder() == null + ? new IonWriterSystemText(defaultSystemSymtab, + this, + appender) + : new IonWriterSystemTextMarkup(defaultSystemSymtab, + this, + appender)); + + SymbolTable initialSymtab = + initialSymtab(((_Private_ValueFactory)system).getLstFactory(), defaultSystemSymtab, imports); + + return new IonWriterUser(catalog, system, systemWriter, initialSymtab, !_allow_invalid_sids); + } + + + @Override + public final IonWriter build(Appendable out) + { + _Private_IonTextWriterBuilder_1_0 b = fillDefaults(); + + _Private_FastAppendable fast = new AppendableFastAppendable(out); + + return b.build(fast); + } + + + @Override + public final IonWriter build(OutputStream out) + { + _Private_IonTextWriterBuilder_1_0 b = fillDefaults(); + + _Private_FastAppendable fast = new OutputStreamFastAppendable(out); + + return b.build(fast); + } + + //========================================================================= + + private static final class Mutable + extends _Private_IonTextWriterBuilder_1_0 + { + private Mutable() { } + + private Mutable(_Private_IonTextWriterBuilder_1_0 that) + { + super(that); + } + + @Override + public _Private_IonTextWriterBuilder_1_0 immutable() + { + return new _Private_IonTextWriterBuilder_1_0(this); + } + + @Override + public _Private_IonTextWriterBuilder_1_0 mutable() + { + return this; + } + + @Override + protected void mutationCheck() + { + } + } +} diff --git a/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder_1_1.java b/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder_1_1.java new file mode 100644 index 0000000000..35a867732d --- /dev/null +++ b/src/main/java/com/amazon/ion/impl/_Private_IonTextWriterBuilder_1_1.java @@ -0,0 +1,188 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion.impl; + +import com.amazon.ion.IonCatalog; +import com.amazon.ion.IonWriter; +import com.amazon.ion.SymbolTable; +import com.amazon.ion.impl.bin.DelimitedContainerStrategy; +import com.amazon.ion.impl.bin.IonManagedWriter_1_1; +import com.amazon.ion.impl.bin.ManagedWriterOptions_1_1; +import com.amazon.ion.impl.bin.SymbolInliningStrategy; +import com.amazon.ion.system.IonTextWriterBuilder_1_1; + +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.Objects; + +/** + * Contains configuration for Ion 1.1 text writers. + * NOT FOR APPLICATION USE! + */ +public class _Private_IonTextWriterBuilder_1_1 + extends _Private_IonTextWriterBuilder<_Private_IonTextWriterBuilder_1_1> implements IonTextWriterBuilder_1_1 { + + public static _Private_IonTextWriterBuilder_1_1 standard() { + return new _Private_IonTextWriterBuilder_1_1.Mutable(); + } + + private SymbolInliningStrategy symbolInliningStrategy = SymbolInliningStrategy.NEVER_INLINE; + + private _Private_IonTextWriterBuilder_1_1() { + super(); + } + + private _Private_IonTextWriterBuilder_1_1(_Private_IonTextWriterBuilder_1_1 that) { + super(that); + symbolInliningStrategy = that.symbolInliningStrategy; + } + + @Override + public SymbolInliningStrategy getSymbolInliningStrategy() { + return symbolInliningStrategy; + } + + @Override + public void setSymbolInliningStrategy(SymbolInliningStrategy symbolInliningStrategy) { + mutationCheck(); + this.symbolInliningStrategy = Objects.requireNonNull(symbolInliningStrategy); + } + + @Override + public IonTextWriterBuilder_1_1 withSymbolInliningStrategy(SymbolInliningStrategy symbolInliningStrategy) { + _Private_IonTextWriterBuilder_1_1 b = mutable(); + b.setSymbolInliningStrategy(symbolInliningStrategy); + return b; + } + + // The following methods are overridden in order to resolve a clashing return type, as they are defined by + // multiple ancestors (version-agnostic abstract classes and the Ion 1.1 interface). + + @Override + public _Private_IonTextWriterBuilder_1_1 copy() + { + return new _Private_IonTextWriterBuilder_1_1.Mutable(this); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 immutable() + { + return this; + } + + @Override + public _Private_IonTextWriterBuilder_1_1 mutable() + { + return copy(); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withCatalog(IonCatalog catalog) { + return (_Private_IonTextWriterBuilder_1_1) super.getCatalog(); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withImports(SymbolTable[] imports) { + return (_Private_IonTextWriterBuilder_1_1) super.getCatalog(); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withPrettyPrinting() { + return (_Private_IonTextWriterBuilder_1_1) super.withPrettyPrinting(); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withJsonDowngrade() { + return (_Private_IonTextWriterBuilder_1_1) super.withJsonDowngrade(); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withCharset(Charset charset) { + return (_Private_IonTextWriterBuilder_1_1) super.withCharset(charset); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withCharsetAscii() { + return (_Private_IonTextWriterBuilder_1_1) super.withCharsetAscii(); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withMinimalSystemData() { + return (_Private_IonTextWriterBuilder_1_1) super.withMinimalSystemData(); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withLstMinimizing(LstMinimizing minimizing) { + return (_Private_IonTextWriterBuilder_1_1) super.withLstMinimizing(minimizing); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withLongStringThreshold(int threshold) { + return (_Private_IonTextWriterBuilder_1_1) super.withLongStringThreshold(threshold); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withNewLineType(NewLineType newLineType) { + return (_Private_IonTextWriterBuilder_1_1) super.withNewLineType(newLineType); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withWriteTopLevelValuesOnNewLines(boolean writeTopLevelValuesOnNewLines) { + return (_Private_IonTextWriterBuilder_1_1) super.withWriteTopLevelValuesOnNewLines(writeTopLevelValuesOnNewLines); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withMaximumTimestampPrecisionDigits(int maximumTimestampPrecisionDigits) { + return (_Private_IonTextWriterBuilder_1_1) super.withMaximumTimestampPrecisionDigits(maximumTimestampPrecisionDigits); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 withIvmMinimizing(IvmMinimizing minimizing) { + return (_Private_IonTextWriterBuilder_1_1) super.withIvmMinimizing(minimizing); + } + + @Override + public IonWriter build(Appendable out) { + if (out == null) { + throw new NullPointerException("Cannot construct a writer with a null Appendable."); + } + _Private_IonTextWriterBuilder_1_1 b = fillDefaults(); + ManagedWriterOptions_1_1 options = new ManagedWriterOptions_1_1(false, symbolInliningStrategy, DelimitedContainerStrategy.ALWAYS_DELIMITED); + return IonManagedWriter_1_1.textWriter(out, options, b); + } + + @Override + public IonWriter build(OutputStream out) { + if (out == null) { + throw new NullPointerException("Cannot construct a writer with a null OutputStream."); + } + + _Private_IonTextWriterBuilder_1_1 b = fillDefaults(); + ManagedWriterOptions_1_1 options = new ManagedWriterOptions_1_1(false, symbolInliningStrategy, DelimitedContainerStrategy.ALWAYS_DELIMITED); + return IonManagedWriter_1_1.textWriter(out, options, b); + } + + //========================================================================= + + private static final class Mutable extends _Private_IonTextWriterBuilder_1_1 { + private Mutable() { } + + private Mutable(_Private_IonTextWriterBuilder_1_1 that) { + super(that); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 immutable() { + return new _Private_IonTextWriterBuilder_1_1(this); + } + + @Override + public _Private_IonTextWriterBuilder_1_1 mutable() { + return this; + } + + @Override + protected void mutationCheck() { + } + } +} diff --git a/src/main/java/com/amazon/ion/impl/bin/IonManagedWriter_1_1.kt b/src/main/java/com/amazon/ion/impl/bin/IonManagedWriter_1_1.kt index 7f1d1c4b34..d709993741 100644 --- a/src/main/java/com/amazon/ion/impl/bin/IonManagedWriter_1_1.kt +++ b/src/main/java/com/amazon/ion/impl/bin/IonManagedWriter_1_1.kt @@ -36,9 +36,8 @@ internal class IonManagedWriter_1_1( companion object { @JvmStatic - fun textWriter(output: OutputStream, managedWriterOptions: ManagedWriterOptions_1_1, textOptions: IonTextWriterBuilder): IonManagedWriter_1_1 { - textOptions as _Private_IonTextWriterBuilder - + fun textWriter(output: OutputStream, managedWriterOptions: ManagedWriterOptions_1_1, textOptions: _Private_IonTextWriterBuilder_1_1): IonManagedWriter_1_1 { + // TODO support all options configurable via IonTextWriterBuilder_1_1 val appender = { val bufferedOutput = BufferedOutputStreamFastAppendable(output, BlockAllocatorProviders.basicProvider().vendAllocator(4096)) _Private_IonTextAppender.forFastAppendable(bufferedOutput, Charsets.UTF_8) @@ -59,9 +58,7 @@ internal class IonManagedWriter_1_1( } @JvmStatic - fun textWriter(output: Appendable, managedWriterOptions: ManagedWriterOptions_1_1, textOptions: IonTextWriterBuilder): IonManagedWriter_1_1 { - textOptions as _Private_IonTextWriterBuilder - + fun textWriter(output: Appendable, managedWriterOptions: ManagedWriterOptions_1_1, textOptions: _Private_IonTextWriterBuilder_1_1): IonManagedWriter_1_1 { val appender = { val bufferedOutput = BufferedAppendableFastAppendable(output) _Private_IonTextAppender.forFastAppendable(bufferedOutput, Charsets.UTF_8) diff --git a/src/main/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1.java b/src/main/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1.java index b0032599a8..df2bf1e578 100644 --- a/src/main/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1.java +++ b/src/main/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1.java @@ -2,13 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.system; -import com.amazon.ion.IonCatalog; import com.amazon.ion.IonWriter; -import com.amazon.ion.SymbolTable; import com.amazon.ion.impl.bin.DelimitedContainerStrategy; -import com.amazon.ion.impl.bin.SymbolInliningStrategy; - -import java.io.OutputStream; /** * The builder for creating {@link IonWriter}s emitting the 1.1 version of the Ion binary format. @@ -20,95 +15,7 @@ * unless they are {@linkplain #immutable() immutable}. * */ -public interface IonBinaryWriterBuilder_1_1 { - - /** - * Gets the catalog to use when building an {@link IonWriter}. - * The catalog is needed to resolve manually-written imports (not common). - * By default, this property is null. - * - * @see #setCatalog(IonCatalog) - * @see #withCatalog(IonCatalog) - */ - IonCatalog getCatalog(); - - /** - * Sets the catalog to use when building an {@link IonWriter}. - * - * @param catalog the catalog to use in built writers. - * If null, the writer will be unable to resolve manually-written imports - * and may throw an exception. - * - * @see #getCatalog() - * @see #withCatalog(IonCatalog) - * - * @throws UnsupportedOperationException if this is immutable. - */ - void setCatalog(IonCatalog catalog); - - /** - * Declares the catalog to use when building an {@link IonWriter}, - * returning a new mutable builder if this is immutable. - * - * @param catalog the catalog to use in built writers. - * If null, the writer will be unable to resolve manually-written imports - * and may throw an exception. - * - * @return this instance, if mutable; - * otherwise a mutable copy of this instance. - * - * @see #getCatalog() - * @see #setCatalog(IonCatalog) - */ - IonBinaryWriterBuilder_1_1 withCatalog(IonCatalog catalog); - - /** - * Gets the imports that will be used to construct the initial local - * symbol table. - * - * @return may be null or empty. - * - * @see #setImports(SymbolTable...) - * @see #withImports(SymbolTable...) - */ - SymbolTable[] getImports(); - - /** - * Sets the shared symbol tables that will be used to construct the - * initial local symbol table. - *

- * If the imports sequence is not null and not empty, the output stream - * will be bootstrapped with a local symbol table that uses the given - * {@code imports}. - * - * @param imports a sequence of shared symbol tables. - * The first (and only the first) may be a system table. - * - * @see #getImports() - * @see #withImports(SymbolTable...) - * - * @throws UnsupportedOperationException if this is immutable. - */ - void setImports(SymbolTable... imports); - - /** - * Declares the imports to use when building an {@link IonWriter}, - * returning a new mutable builder if this is immutable. - *

- * If the imports sequence is not null and not empty, the output stream - * will be bootstrapped with a local symbol table that uses the given - * {@code imports}. - * - * @param imports a sequence of shared symbol tables. - * The first (and only the first) may be a system table. - * - * @return this instance, if mutable; - * otherwise a mutable copy of this instance. - * - * @see #getImports() - * @see #setImports(SymbolTable...) - */ - IonBinaryWriterBuilder_1_1 withImports(SymbolTable... imports); +public interface IonBinaryWriterBuilder_1_1 extends IonWriterBuilder_1_1 { // TODO add auto-flush (see IonBinaryWriterBuilder.withAutoFlushEnabled) // TODO consider adding stream-copy optimization (see IonBinaryWriterBuilder withStreamCopyOptimized) @@ -187,77 +94,6 @@ public interface IonBinaryWriterBuilder_1_1 { */ IonBinaryWriterBuilder_1_1 withDelimitedContainerStrategy(DelimitedContainerStrategy delimitedContainerStrategy); - /** - * Gets the SymbolInliningStrategy that will be used to determine which symbols will be written with inline text. - * - * @return the SymbolInliningStrategy currently configured - * - * @see #setSymbolInliningStrategy(SymbolInliningStrategy) - * @see #withSymbolInliningStrategy(SymbolInliningStrategy) - */ - SymbolInliningStrategy getSymbolInliningStrategy(); - - /** - * Sets the SymbolInliningStrategy that will be used to determine which symbols will be written with inline text. - * - * @param symbolInliningStrategy if unset, the default of {@link SymbolInliningStrategy#NEVER_INLINE} will be used. - * - * @see #getSymbolInliningStrategy() - * @see #withSymbolInliningStrategy(SymbolInliningStrategy) - */ - void setSymbolInliningStrategy(SymbolInliningStrategy symbolInliningStrategy); - - /** - * Declares the SymbolInliningStrategy that will be used to determine which symbols will be written with inline text. - * - * @param symbolInliningStrategy if unset, the default of {@link SymbolInliningStrategy#NEVER_INLINE} will be used. - * - * @return this instance, if mutable; - * otherwise a mutable copy of this instance. - * - * @see #getSymbolInliningStrategy() - * @see #withSymbolInliningStrategy(SymbolInliningStrategy) - */ - IonBinaryWriterBuilder_1_1 withSymbolInliningStrategy(SymbolInliningStrategy symbolInliningStrategy); - - // NOTE: Unlike in Ion 1.0, local symbol table append is always enabled in the Ion 1.1 writers. // NOTE: Unlike in Ion 1.0, writing float 32 is always enabled in the Ion 1.1 writers. - - /** - * Creates a mutable copy of this builder. - * - * @return a new builder with the same configuration as {@code this}. - */ - IonBinaryWriterBuilder_1_1 copy(); - - /** - * Returns an immutable builder configured exactly like this one. - * - * @return this instance, if immutable; - * otherwise an immutable copy of this instance. - */ - IonBinaryWriterBuilder_1_1 immutable(); - - /** - * Returns a mutable builder configured exactly like this one. - * - * @return this instance, if mutable; - * otherwise a mutable copy of this instance. - */ - IonBinaryWriterBuilder_1_1 mutable(); - - /** - * Builds a new writer based on this builder's configuration - * properties. - * - * @param out the stream that will receive Ion data. - * Must not be null. - * - * @return a new {@link IonWriter} instance; not {@code null}. - */ - IonWriter build(OutputStream out); - - // TODO add a build() method that returns a 1.1-specific writer interface, allowing opt-in to new APIs. - } diff --git a/src/main/java/com/amazon/ion/system/IonTextWriterBuilder.java b/src/main/java/com/amazon/ion/system/IonTextWriterBuilder.java index 40785cd1f4..685a4839c1 100644 --- a/src/main/java/com/amazon/ion/system/IonTextWriterBuilder.java +++ b/src/main/java/com/amazon/ion/system/IonTextWriterBuilder.java @@ -1,18 +1,5 @@ -/* - * 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. - */ - +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.system; import static com.amazon.ion.system.IonWriterBuilder.InitialIvmHandling.SUPPRESS; @@ -21,13 +8,15 @@ 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_IonTextWriterBuilder_1_0; 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. + * The builder for creating {@link IonWriter}s emitting the Ion text syntax + * in any encoding version. Subclasses may provide version-specific + * configuration. *

* WARNING: This class should not be extended by code outside of * this library. @@ -161,7 +150,7 @@ public CharSequence getCharSequence() { */ public static IonTextWriterBuilder standard() { - return _Private_IonTextWriterBuilder.standard(); + return _Private_IonTextWriterBuilder_1_0.standard(); } /** @@ -261,13 +250,13 @@ protected IonTextWriterBuilder(IonTextWriterBuilder that) @Override - public final IonTextWriterBuilder withCatalog(IonCatalog catalog) + public IonTextWriterBuilder withCatalog(IonCatalog catalog) { return super.withCatalog(catalog); } @Override - public final IonTextWriterBuilder withImports(SymbolTable... imports) + public IonTextWriterBuilder withImports(SymbolTable... imports) { return super.withImports(imports); } @@ -331,7 +320,7 @@ public void setCharset(Charset charset) * @see #getCharset() * @see #setCharset(Charset) */ - public final IonTextWriterBuilder withCharset(Charset charset) + public IonTextWriterBuilder withCharset(Charset charset) { IonTextWriterBuilder b = mutable(); b.setCharset(charset); @@ -344,7 +333,7 @@ public final IonTextWriterBuilder withCharset(Charset charset) * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ - public final IonTextWriterBuilder withCharsetAscii() + public IonTextWriterBuilder withCharsetAscii() { return withCharset(ASCII); } @@ -370,7 +359,7 @@ public final IonTextWriterBuilder withCharsetAscii() * */ - public final IonTextWriterBuilder withMinimalSystemData() + public IonTextWriterBuilder withMinimalSystemData() { IonTextWriterBuilder b = mutable(); b.setInitialIvmHandling(SUPPRESS); @@ -536,7 +525,7 @@ public void setIvmMinimizing(IvmMinimizing minimizing) * */ - public final IonTextWriterBuilder + public IonTextWriterBuilder withIvmMinimizing(IvmMinimizing minimizing) { IonTextWriterBuilder b = mutable(); @@ -598,7 +587,7 @@ public void setLstMinimizing(LstMinimizing minimizing) * */ - public final IonTextWriterBuilder + public IonTextWriterBuilder withLstMinimizing(LstMinimizing minimizing) { IonTextWriterBuilder b = mutable(); @@ -655,7 +644,7 @@ public void setLongStringThreshold(int threshold) * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ - public final IonTextWriterBuilder withLongStringThreshold(int threshold) + public IonTextWriterBuilder withLongStringThreshold(int threshold) { IonTextWriterBuilder b = mutable(); b.setLongStringThreshold(threshold); @@ -708,7 +697,7 @@ public void setNewLineType(NewLineType newLineType) * @return this instance, if mutable; * otherwise a mutable copy of this instance. */ - public final IonTextWriterBuilder withNewLineType(NewLineType newLineType) + public IonTextWriterBuilder withNewLineType(NewLineType newLineType) { IonTextWriterBuilder b = mutable(); b.setNewLineType(newLineType); @@ -758,7 +747,7 @@ public void setWriteTopLevelValuesOnNewLines(boolean writeTopLevelValuesOnNewLin * @see #getWriteTopLevelValuesOnNewLines() * @see #setWriteTopLevelValuesOnNewLines(boolean) */ - public final IonTextWriterBuilder withWriteTopLevelValuesOnNewLines(boolean writeTopLevelValuesOnNewLines) + public IonTextWriterBuilder withWriteTopLevelValuesOnNewLines(boolean writeTopLevelValuesOnNewLines) { IonTextWriterBuilder b = mutable(); b.setWriteTopLevelValuesOnNewLines(writeTopLevelValuesOnNewLines); @@ -800,7 +789,7 @@ public void setMaximumTimestampPrecisionDigits(int maximumTimestampPrecisionDigi * @see #getMaximumTimestampPrecisionDigits() * @see #setMaximumTimestampPrecisionDigits(int) */ - public final IonTextWriterBuilder withMaximumTimestampPrecisionDigits(int maximumTimestampPrecisionDigits) { + public IonTextWriterBuilder withMaximumTimestampPrecisionDigits(int maximumTimestampPrecisionDigits) { IonTextWriterBuilder b = mutable(); b.setMaximumTimestampPrecisionDigits(maximumTimestampPrecisionDigits); return b; diff --git a/src/main/java/com/amazon/ion/system/IonTextWriterBuilder_1_1.java b/src/main/java/com/amazon/ion/system/IonTextWriterBuilder_1_1.java new file mode 100644 index 0000000000..50ab297c23 --- /dev/null +++ b/src/main/java/com/amazon/ion/system/IonTextWriterBuilder_1_1.java @@ -0,0 +1,368 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion.system; + +import com.amazon.ion.IonWriter; +import com.amazon.ion.Timestamp; + +import java.nio.charset.Charset; + +/** + * The builder for creating {@link IonWriter}s emitting the 1.1 version of the Ion text format. + *

+ * 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}. + * + */ +public interface IonTextWriterBuilder_1_1 extends IonWriterBuilder_1_1 { + // TODO add any configuration specific to writing 1.1 text. + + /** + * 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) + */ + Charset getCharset(); + + /** + * Sets the charset denoting the output encoding. + * Only ASCII and UTF-8 are supported. + * + * @param charset may be null, denoting the default of UTF-8. + * + * @see #getCharset() + * @see #withCharset(Charset) + * + * @throws UnsupportedOperationException if this is immutable. + */ + void setCharset(Charset charset); + + /** + * Declares the charset denoting the output encoding, + * returning a new mutable builder if this is immutable. + * + * @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) + */ + IonTextWriterBuilder_1_1 withCharset(Charset charset); + + /** + * Declares the output encoding to be {@code US-ASCII}. + * + * @return this instance, if mutable; + * otherwise a mutable copy of this instance. + */ + IonTextWriterBuilder_1_1 withCharsetAscii(); + + /** + * Declares that this builder should minimize system-level output + * (Ion version markers and local symbol tables). + *

+ * This is equivalent to: + *

    + *
  • {@link #setIvmMinimizing(IonWriterBuilder.IvmMinimizing) + * setIvmMinimizing}{@code (}{@link IonWriterBuilder.IvmMinimizing#DISTANT DISTANT}{@code )} + *
  • {@link #setLstMinimizing(IonTextWriterBuilder.LstMinimizing) + * setLstMinimizing}{@code (}{@link IonTextWriterBuilder.LstMinimizing#EVERYTHING EVERYTHING}{@code )}. + * This requires all macros to be expanded. + *
+ * + * @return this instance, if mutable; + * otherwise a mutable copy of this instance. + * + */ + IonTextWriterBuilder_1_1 withMinimalSystemData(); + + + /** + * 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. + */ + IonTextWriterBuilder_1_1 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. + */ + IonTextWriterBuilder_1_1 withJsonDowngrade(); + + /** + * {@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) + * + + */ + IonWriterBuilder.IvmMinimizing getIvmMinimizing(); + + /** + * 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. + * + + */ + void setIvmMinimizing(IonWriterBuilder.IvmMinimizing 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() + * + + */ + IonTextWriterBuilder_1_1 withIvmMinimizing(IonWriterBuilder.IvmMinimizing minimizing); + + /** + * 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(IonTextWriterBuilder.LstMinimizing) + * @see #withLstMinimizing(IonTextWriterBuilder.LstMinimizing) + * + + */ + IonTextWriterBuilder.LstMinimizing getLstMinimizing(); + + /** + * 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(IonTextWriterBuilder.LstMinimizing) + * + * @throws UnsupportedOperationException if this is immutable. + * + + */ + void setLstMinimizing(IonTextWriterBuilder.LstMinimizing 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(IonTextWriterBuilder.LstMinimizing) + * + */ + IonTextWriterBuilder_1_1 withLstMinimizing(IonTextWriterBuilder.LstMinimizing minimizing); + + /** + * 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) + */ + int getLongStringThreshold(); + + /** + * 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. + */ + void setLongStringThreshold(int 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. + */ + IonTextWriterBuilder_1_1 withLongStringThreshold(int threshold); + + /** + * Gets the character sequence that will be written as a line separator. + * The default is {@link IonTextWriterBuilder.NewLineType#PLATFORM_DEPENDENT} + * + * @return the character sequence to be written between top-level values; null means the default should be used. + * + * @see #setNewLineType(IonTextWriterBuilder.NewLineType) + * @see #withNewLineType(IonTextWriterBuilder.NewLineType) + */ + IonTextWriterBuilder.NewLineType getNewLineType(); + + /** + * Sets the character sequence that will be written as a line separator. + * The default is {@link IonTextWriterBuilder.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(IonTextWriterBuilder.NewLineType) + * + * @throws UnsupportedOperationException if this is immutable. + */ + void setNewLineType(IonTextWriterBuilder.NewLineType newLineType); + + /** + * Declares the character sequence that will be written as a line separator. + * The default is {@link IonTextWriterBuilder.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(IonTextWriterBuilder.NewLineType) + * + * @return this instance, if mutable; + * otherwise a mutable copy of this instance. + */ + IonTextWriterBuilder_1_1 withNewLineType(IonTextWriterBuilder.NewLineType newLineType); + + /** + * 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) + */ + boolean getWriteTopLevelValuesOnNewLines(); + + /** + * 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) + */ + void setWriteTopLevelValuesOnNewLines(boolean 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) + */ + IonTextWriterBuilder_1_1 withWriteTopLevelValuesOnNewLines(boolean writeTopLevelValuesOnNewLines); + + /** + * 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) + */ + int getMaximumTimestampPrecisionDigits(); + + /** + * 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) + */ + void setMaximumTimestampPrecisionDigits(int 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) + */ + IonTextWriterBuilder_1_1 withMaximumTimestampPrecisionDigits(int maximumTimestampPrecisionDigits); + + IonWriter build(Appendable out); +} diff --git a/src/main/java/com/amazon/ion/system/IonWriterBuilder_1_1.java b/src/main/java/com/amazon/ion/system/IonWriterBuilder_1_1.java new file mode 100644 index 0000000000..669f5a5ca2 --- /dev/null +++ b/src/main/java/com/amazon/ion/system/IonWriterBuilder_1_1.java @@ -0,0 +1,182 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion.system; + +import com.amazon.ion.IonCatalog; +import com.amazon.ion.IonWriter; +import com.amazon.ion.SymbolTable; +import com.amazon.ion.impl.bin.SymbolInliningStrategy; + +import java.io.OutputStream; + + +/** + * The builder for creating {@link IonWriter}s emitting the 1.1 version of either + * the text or binary Ion formats. + *

+ * 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}. + * + */ +public interface IonWriterBuilder_1_1> { + + /** + * Gets the catalog to use when building an {@link IonWriter}. + * The catalog is needed to resolve manually-written imports (not common). + * By default, this property is null. + * + * @see #setCatalog(IonCatalog) + * @see #withCatalog(IonCatalog) + */ + IonCatalog getCatalog(); + + /** + * Sets the catalog to use when building an {@link IonWriter}. + * + * @param catalog the catalog to use in built writers. + * If null, the writer will be unable to resolve manually-written imports + * and may throw an exception. + * + * @see #getCatalog() + * @see #withCatalog(IonCatalog) + * + * @throws UnsupportedOperationException if this is immutable. + */ + void setCatalog(IonCatalog catalog); + + /** + * Declares the catalog to use when building an {@link IonWriter}, + * returning a new mutable builder if this is immutable. + * + * @param catalog the catalog to use in built writers. + * If null, the writer will be unable to resolve manually-written imports + * and may throw an exception. + * + * @return this instance, if mutable; + * otherwise a mutable copy of this instance. + * + * @see #getCatalog() + * @see #setCatalog(IonCatalog) + */ + T withCatalog(IonCatalog catalog); + + /** + * Gets the imports that will be used to construct the initial local + * symbol table. + * + * @return may be null or empty. + * + * @see #setImports(SymbolTable...) + * @see #withImports(SymbolTable...) + */ + SymbolTable[] getImports(); + + /** + * Sets the shared symbol tables that will be used to construct the + * initial local symbol table. + *

+ * If the imports sequence is not null and not empty, the output stream + * will be bootstrapped with a local symbol table that uses the given + * {@code imports}. + * + * @param imports a sequence of shared symbol tables. + * The first (and only the first) may be a system table. + * + * @see #getImports() + * @see #withImports(SymbolTable...) + * + * @throws UnsupportedOperationException if this is immutable. + */ + void setImports(SymbolTable... imports); + + /** + * Declares the imports to use when building an {@link IonWriter}, + * returning a new mutable builder if this is immutable. + *

+ * If the imports sequence is not null and not empty, the output stream + * will be bootstrapped with a local symbol table that uses the given + * {@code imports}. + * + * @param imports a sequence of shared symbol tables. + * The first (and only the first) may be a system table. + * + * @return this instance, if mutable; + * otherwise a mutable copy of this instance. + * + * @see #getImports() + * @see #setImports(SymbolTable...) + */ + T withImports(SymbolTable... imports); + + /** + * Gets the SymbolInliningStrategy that will be used to determine which symbols will be written with inline text. + * + * @return the SymbolInliningStrategy currently configured + * + * @see #setSymbolInliningStrategy(SymbolInliningStrategy) + * @see #withSymbolInliningStrategy(SymbolInliningStrategy) + */ + SymbolInliningStrategy getSymbolInliningStrategy(); + + /** + * Sets the SymbolInliningStrategy that will be used to determine which symbols will be written with inline text. + * + * @param symbolInliningStrategy if unset, the default of {@link SymbolInliningStrategy#NEVER_INLINE} will be used. + * + * @see #getSymbolInliningStrategy() + * @see #withSymbolInliningStrategy(SymbolInliningStrategy) + */ + void setSymbolInliningStrategy(SymbolInliningStrategy symbolInliningStrategy); + + /** + * Declares the SymbolInliningStrategy that will be used to determine which symbols will be written with inline text. + * + * @param symbolInliningStrategy if unset, the default of {@link SymbolInliningStrategy#NEVER_INLINE} will be used. + * + * @return this instance, if mutable; + * otherwise a mutable copy of this instance. + * + * @see #getSymbolInliningStrategy() + * @see #withSymbolInliningStrategy(SymbolInliningStrategy) + */ + T withSymbolInliningStrategy(SymbolInliningStrategy symbolInliningStrategy); + + /** + * Creates a mutable copy of this builder. + * + * @return a new builder with the same configuration as {@code this}. + */ + T copy(); + + /** + * Returns an immutable builder configured exactly like this one. + * + * @return this instance, if immutable; + * otherwise an immutable copy of this instance. + */ + T immutable(); + + /** + * Returns a mutable builder configured exactly like this one. + * + * @return this instance, if mutable; + * otherwise a mutable copy of this instance. + */ + T mutable(); + + /** + * Builds a new writer based on this builder's configuration + * properties. + * + * @param out the stream that will receive Ion data. + * Must not be null. + * + * @return a new {@link IonWriter} instance; not {@code null}. + */ + IonWriter build(OutputStream out); + + // TODO add a build() method that returns a 1.1-specific writer interface, allowing opt-in to new APIs. +} diff --git a/src/main/java/com/amazon/ion/system/_Private_IonBinaryWriterBuilder_1_1.java b/src/main/java/com/amazon/ion/system/_Private_IonBinaryWriterBuilder_1_1.java index b83c67842f..ee179433d3 100644 --- a/src/main/java/com/amazon/ion/system/_Private_IonBinaryWriterBuilder_1_1.java +++ b/src/main/java/com/amazon/ion/system/_Private_IonBinaryWriterBuilder_1_1.java @@ -45,6 +45,8 @@ private _Private_IonBinaryWriterBuilder_1_1() { private _Private_IonBinaryWriterBuilder_1_1(_Private_IonBinaryWriterBuilder_1_1 that) { super(that); blockSize = that.blockSize; + delimitedContainerStrategy = that.delimitedContainerStrategy; + symbolInliningStrategy = that.symbolInliningStrategy; } @Override @@ -139,15 +141,6 @@ public IonWriter build(OutputStream out) { return IonManagedWriter_1_1.binaryWriter(out, options, this); } - // TODO: Replace this hacky method with a proper Ion 1.1 text writer builder - public IonWriter _private_buildTextWriter(OutputStream out, IonTextWriterBuilder textWriterBuilder) { - if (out == null) { - throw new IllegalArgumentException("Cannot construct a writer with a null OutputStream."); - } - ManagedWriterOptions_1_1 options = new ManagedWriterOptions_1_1(false, symbolInliningStrategy, delimitedContainerStrategy); - return IonManagedWriter_1_1.textWriter(out, options, textWriterBuilder); - } - // Note: the copy/immutable/mutable pattern is copied from _Private_IonBinaryWriterBuilder. @Override diff --git a/src/main/java/com/amazon/ion/util/IonTextUtils.java b/src/main/java/com/amazon/ion/util/IonTextUtils.java index 089aa4a89a..6e54a42234 100644 --- a/src/main/java/com/amazon/ion/util/IonTextUtils.java +++ b/src/main/java/com/amazon/ion/util/IonTextUtils.java @@ -1,18 +1,5 @@ -/* - * 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. - */ - +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.util; import static com.amazon.ion.impl._Private_IonConstants.isHighSurrogate; @@ -21,7 +8,7 @@ import static com.amazon.ion.impl._Private_IonTextAppender.ZERO_PADDING; import static com.amazon.ion.impl._Private_IonTextAppender.isIdentifierKeyword; import static com.amazon.ion.impl._Private_IonTextAppender.symbolNeedsQuoting; -import static com.amazon.ion.impl._Private_IonTextWriterBuilder.STANDARD; +import static com.amazon.ion.impl._Private_IonTextWriterBuilder_1_0.STANDARD; import com.amazon.ion.SymbolToken; import com.amazon.ion.impl._Private_IonTextAppender; diff --git a/src/main/java/com/amazon/ion/util/Printer.java b/src/main/java/com/amazon/ion/util/Printer.java index 24379ee6f7..59c2b2d983 100644 --- a/src/main/java/com/amazon/ion/util/Printer.java +++ b/src/main/java/com/amazon/ion/util/Printer.java @@ -1,18 +1,5 @@ -/* - * 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. - */ - +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.util; import static com.amazon.ion.SystemSymbols.IMPORTS; @@ -45,7 +32,7 @@ import com.amazon.ion.Timestamp; import com.amazon.ion.impl._Private_IonSymbol; import com.amazon.ion.impl._Private_IonSystem; -import com.amazon.ion.impl._Private_IonTextWriterBuilder; +import com.amazon.ion.impl._Private_IonTextWriterBuilder_1_0; import com.amazon.ion.impl._Private_IonValue; import com.amazon.ion.impl._Private_IonValue.SymbolTableProvider; import com.amazon.ion.system.IonTextWriterBuilder; @@ -441,8 +428,8 @@ public void print(IonValue value, Appendable out) boolean dg = value instanceof IonDatagram; - _Private_IonTextWriterBuilder o = - _Private_IonTextWriterBuilder.standard(); + _Private_IonTextWriterBuilder_1_0 o = + _Private_IonTextWriterBuilder_1_0.standard(); o.setCharset(IonTextWriterBuilder.ASCII); if (dg) { diff --git a/src/test/java/com/amazon/ion/Ion11Test.kt b/src/test/java/com/amazon/ion/Ion11Test.kt index 9dc772001c..9b88b47250 100644 --- a/src/test/java/com/amazon/ion/Ion11Test.kt +++ b/src/test/java/com/amazon/ion/Ion11Test.kt @@ -13,7 +13,6 @@ import com.amazon.ion.impl.bin.* import com.amazon.ion.system.IonBinaryWriterBuilder import com.amazon.ion.system.IonSystemBuilder import com.amazon.ion.system.IonTextWriterBuilder -import com.amazon.ion.system._Private_IonBinaryWriterBuilder_1_1 import java.io.ByteArrayOutputStream import java.io.FilenameFilter import java.io.OutputStream @@ -76,49 +75,32 @@ class Ion11Test { @ParameterizedTest(name = "{0}") @MethodSource("ionData") fun writeIon11Text(name: String, ion: ByteArray) { - val textOptions = IonTextWriterBuilder - .standard() - .withNewLineType(IonTextWriterBuilder.NewLineType.LF) - textTest(ion) { - val builder = ION_1_1.binaryWriterBuilder() - .withSymbolInliningStrategy(SymbolInliningStrategy.ALWAYS_INLINE) - (builder as _Private_IonBinaryWriterBuilder_1_1)._private_buildTextWriter(it, textOptions) + ION_1_1.textWriterBuilder() + .withNewLineType(IonTextWriterBuilder.NewLineType.LF) + .build(it) } } @ParameterizedTest(name = "{0}") @MethodSource("ionData") fun writeIon11TextToAppendable(name: String, ion: ByteArray) { - val textOptions = IonTextWriterBuilder - .standard() - .withNewLineType(IonTextWriterBuilder.NewLineType.LF) - textTestAppendable(ion) { - IonManagedWriter_1_1.textWriter( - output = it, - managedWriterOptions = ManagedWriterOptions_1_1( - internEncodingDirectiveSymbols = false, - // Test using NEVER_INLINE to make sure that the BufferedAppendableFastAppendable works correctly. - symbolInliningStrategy = SymbolInliningStrategy.NEVER_INLINE, - delimitedContainerStrategy = DelimitedContainerStrategy.ALWAYS_DELIMITED - ), - textOptions = textOptions, - ) + ION_1_1.textWriterBuilder() + .withNewLineType(IonTextWriterBuilder.NewLineType.LF) + .withSymbolInliningStrategy(SymbolInliningStrategy.NEVER_INLINE) + .build(it) } } @ParameterizedTest(name = "{0}") @MethodSource("ionData") fun writeIon11TextWithSymtab(name: String, ion: ByteArray) { - val textOptions = IonTextWriterBuilder - .standard() - .withNewLineType(IonTextWriterBuilder.NewLineType.LF) - textTest(ion) { - val builder = ION_1_1.binaryWriterBuilder() + ION_1_1.textWriterBuilder() + .withNewLineType(IonTextWriterBuilder.NewLineType.LF) .withSymbolInliningStrategy(SymbolInliningStrategy.NEVER_INLINE) - (builder as _Private_IonBinaryWriterBuilder_1_1)._private_buildTextWriter(it, textOptions) + .build(it) } } diff --git a/src/test/java/com/amazon/ion/impl/IonRawTextWriterTest_1_1.kt b/src/test/java/com/amazon/ion/impl/IonRawTextWriterTest_1_1.kt index ec541b128e..4d7ae773d8 100644 --- a/src/test/java/com/amazon/ion/impl/IonRawTextWriterTest_1_1.kt +++ b/src/test/java/com/amazon/ion/impl/IonRawTextWriterTest_1_1.kt @@ -15,18 +15,22 @@ import org.junit.jupiter.params.provider.CsvSource class IonRawTextWriterTest_1_1 { + private fun standardBuilder(): _Private_IonTextWriterBuilder_1_1 { + return _Private_IonTextWriterBuilder_1_1.standard() + } + private inline fun ionWriter( out: StringBuilder = StringBuilder(), - builderConfigurator: IonTextWriterBuilder.() -> Unit = { /* noop */ }, + builderConfigurator: IonTextWriterBuilder_1_1.() -> Unit = { /* noop */ }, block: IonRawTextWriter_1_1.() -> Unit, ): IonRawTextWriter_1_1 { - val b = IonTextWriterBuilder.standard() + val b = standardBuilder() .apply(builderConfigurator) // Always use LF because the tests' expected data uses LF. .withNewLineType(IonTextWriterBuilder.NewLineType.LF) val rawWriter = IonRawTextWriter_1_1( - options = b as _Private_IonTextWriterBuilder, + options = b as _Private_IonTextWriterBuilder_1_1, output = _Private_IonTextAppender.forAppendable(out) ) block.invoke(rawWriter) @@ -34,7 +38,7 @@ class IonRawTextWriterTest_1_1 { } private inline fun writeAsString( - builderConfigurator: IonTextWriterBuilder.() -> Unit = { /* noop */ }, + builderConfigurator: IonTextWriterBuilder_1_1.() -> Unit = { /* noop */ }, autoClose: Boolean = true, block: IonRawTextWriter_1_1.() -> Unit, ): String { @@ -46,7 +50,7 @@ class IonRawTextWriterTest_1_1 { private inline fun assertWriterOutputEquals( text: String, - builderConfigurator: IonTextWriterBuilder.() -> Unit = { /* noop */ }, + builderConfigurator: IonTextWriterBuilder_1_1.() -> Unit = { /* noop */ }, autoClose: Boolean = true, block: IonRawTextWriter_1_1.() -> Unit, ) { diff --git a/src/test/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1_Test.java b/src/test/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1_Test.java index e91cbcc27d..b7551e9e21 100644 --- a/src/test/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1_Test.java +++ b/src/test/java/com/amazon/ion/system/IonBinaryWriterBuilder_1_1_Test.java @@ -42,28 +42,18 @@ public void testBlockSize() { assertEquals(4096, immutable.getBlockSize()); } - // TODO the following tests are currently skipped because the builder's build() method does not yet return - // non-null IonWriter instances. - - @Override - @Test - @Ignore - public void testStandard() { - // TODO remove this override. - } - @Override @Test @Ignore public void testImports() { - // TODO remove this override. + // Note: skipped because IonManagedWriter_1_1 does not implement _Private_IonWriter.getSymbolTable. } @Override @Test @Ignore public void testCustomCatalog() { - // TODO remove this override. + // Note: skipped because IonManagedWriter_1_1 does not implement _Private_IonWriter.getCatalog. } } diff --git a/src/test/java/com/amazon/ion/system/IonTextWriterBuilderTest.java b/src/test/java/com/amazon/ion/system/IonTextWriterBuilderTestBase.java similarity index 68% rename from src/test/java/com/amazon/ion/system/IonTextWriterBuilderTest.java rename to src/test/java/com/amazon/ion/system/IonTextWriterBuilderTestBase.java index 5c819debdf..e8d4b75792 100644 --- a/src/test/java/com/amazon/ion/system/IonTextWriterBuilderTest.java +++ b/src/test/java/com/amazon/ion/system/IonTextWriterBuilderTestBase.java @@ -1,26 +1,11 @@ -/* - * 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. - */ - +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.system; -import static com.amazon.ion.SystemSymbols.ION_1_0; import static com.amazon.ion.system.IonTextWriterBuilder.ASCII; import static com.amazon.ion.system.IonTextWriterBuilder.UTF8; import static com.amazon.ion.system.IonTextWriterBuilder.LstMinimizing.EVERYTHING; import static com.amazon.ion.system.IonTextWriterBuilder.LstMinimizing.LOCALS; -import static com.amazon.ion.system.IonWriterBuilder.InitialIvmHandling.SUPPRESS; import static com.amazon.ion.system.IonWriterBuilder.IvmMinimizing.ADJACENT; import static com.amazon.ion.system.IonWriterBuilder.IvmMinimizing.DISTANT; import static org.junit.Assert.assertArrayEquals; @@ -40,9 +25,15 @@ import org.junit.Assert; import org.junit.Test; - -public class IonTextWriterBuilderTest +/** + * Base tests for classes that inherit from {@link IonTextWriterBuilder}. + */ +public abstract class IonTextWriterBuilderTestBase { + + abstract IonTextWriterBuilder standard(); + abstract String ivm(); + public void testBuildNull(IonTextWriterBuilder b) { try { @@ -61,7 +52,7 @@ public void testBuildNull(IonTextWriterBuilder b) @Test public void testStandard() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); Assert.assertNotNull(b); testBuildNull(b); @@ -70,7 +61,7 @@ public void testStandard() IonWriter writer = b.build(out); Assert.assertNotNull(writer); - assertNotSame(b, IonTextWriterBuilder.standard()); + assertNotSame(b, standard()); } @@ -81,7 +72,7 @@ public void testCustomCatalog() { IonCatalog catalog = new SimpleCatalog(); - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setCatalog(catalog); assertSame(catalog, b.getCatalog()); @@ -114,7 +105,7 @@ public void testCatalogImmutability() { IonCatalog catalog = new SimpleCatalog(); - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setCatalog(catalog); IonTextWriterBuilder b2 = b.immutable(); @@ -124,71 +115,10 @@ public void testCatalogImmutability() //------------------------------------------------------------------------- - @Test - public void testInitialIvmHandling() - { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); - b.setInitialIvmHandling(SUPPRESS); - assertSame(SUPPRESS, b.getInitialIvmHandling()); - - // Test with...() on mutable builder - - IonTextWriterBuilder b2 = b.withInitialIvmHandling(null); - assertSame(b, b2); - assertSame(null, b.getInitialIvmHandling()); - - // Test with...() on immutable builder - - b2 = b.immutable(); - assertSame(null, b2.getInitialIvmHandling()); - IonTextWriterBuilder b3 = b2.withInitialIvmHandling(SUPPRESS); - assertNotSame(b2, b3); - assertSame(null, b2.getInitialIvmHandling()); - assertSame(SUPPRESS, b3.getInitialIvmHandling()); - } - - @Test(expected = UnsupportedOperationException.class) - public void testInitialIvmHandlingImmutability() - { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); - b.setInitialIvmHandling(SUPPRESS); - - IonTextWriterBuilder b2 = b.immutable(); - assertSame(SUPPRESS, b2.getInitialIvmHandling()); - b2.setInitialIvmHandling(null); - } - - @Test - public void testInitialIvmSuppression() - throws IOException - { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); - - StringBuilder out = new StringBuilder(); - IonWriter writer = b.build(out); - writer.writeSymbol(ION_1_0); - writer.writeNull(); - writer.writeSymbol(ION_1_0); - writer.close(); - assertEquals(ION_1_0 + " null " + ION_1_0, out.toString()); - - b.withInitialIvmHandling(SUPPRESS); - out.setLength(0); - writer = b.build(out); - writer.writeSymbol(ION_1_0); - writer.writeSymbol(ION_1_0); - writer.writeNull(); - writer.writeSymbol(ION_1_0); - writer.close(); - assertEquals("null " + ION_1_0, out.toString()); - } - - //------------------------------------------------------------------------- - @Test public void testIvmMinimizing() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); assertEquals(null, b.getIvmMinimizing()); b.setIvmMinimizing(ADJACENT); assertSame(ADJACENT, b.getIvmMinimizing()); @@ -212,7 +142,7 @@ public void testIvmMinimizing() @Test(expected = UnsupportedOperationException.class) public void testIvmMinimizingImmutability() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setIvmMinimizing(ADJACENT); IonTextWriterBuilder b2 = b.immutable(); @@ -224,36 +154,36 @@ public void testIvmMinimizingImmutability() public void testIvmMinimization() throws IOException { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); StringBuilder out = new StringBuilder(); IonWriter writer = b.build(out); - writer.writeSymbol(ION_1_0); - writer.writeSymbol(ION_1_0); + writer.writeSymbol(ivm()); + writer.writeSymbol(ivm()); writer.close(); - assertEquals(ION_1_0 + " " + ION_1_0, out.toString()); + assertEquals(ivm() + " " + ivm(), out.toString()); b.withIvmMinimizing(ADJACENT); out.setLength(0); writer = b.build(out); - writer.writeSymbol(ION_1_0); - writer.writeSymbol(ION_1_0); + writer.writeSymbol(ivm()); + writer.writeSymbol(ivm()); writer.writeNull(); - writer.writeSymbol(ION_1_0); - writer.writeSymbol(ION_1_0); + writer.writeSymbol(ivm()); + writer.writeSymbol(ivm()); writer.close(); - assertEquals(ION_1_0 + " null " + ION_1_0, out.toString()); + assertEquals(ivm() + " null " + ivm(), out.toString()); b.withIvmMinimizing(DISTANT); out.setLength(0); writer = b.build(out); - writer.writeSymbol(ION_1_0); - writer.writeSymbol(ION_1_0); + writer.writeSymbol(ivm()); + writer.writeSymbol(ivm()); writer.writeNull(); - writer.writeSymbol(ION_1_0); - writer.writeSymbol(ION_1_0); + writer.writeSymbol(ivm()); + writer.writeSymbol(ivm()); writer.close(); - assertEquals(ION_1_0 + " null", out.toString()); + assertEquals(ivm() + " null", out.toString()); } //------------------------------------------------------------------------- @@ -261,7 +191,7 @@ public void testIvmMinimization() @Test public void testLstMinimizing() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setLstMinimizing(EVERYTHING); assertSame(EVERYTHING, b.getLstMinimizing()); @@ -284,7 +214,7 @@ public void testLstMinimizing() @Test(expected = UnsupportedOperationException.class) public void testLstMinimizingImmutability() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setLstMinimizing(EVERYTHING); IonTextWriterBuilder b2 = b.immutable(); @@ -297,7 +227,7 @@ public void testLstMinimizingImmutability() @Test public void testCharset() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setCharset(ASCII); assertSame(ASCII, b.getCharset()); b.setCharset(null); @@ -326,7 +256,7 @@ public void testCharset() @Test(expected = UnsupportedOperationException.class) public void testCharsetImmutability() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setCharset(ASCII); assertSame(ASCII, b.getCharset()); @@ -340,7 +270,7 @@ public void testCharsetImmutability() public void testCharsetValidation() { Charset iso = Charset.forName("ISO-8859-1"); - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setCharset(iso); } @@ -355,7 +285,7 @@ public void testImports() SymbolTable[] symtabsF = new SymbolTable[] { f }; SymbolTable[] symtabsG = new SymbolTable[] { g }; - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setImports(f); StringBuilder out = new StringBuilder(); @@ -398,7 +328,7 @@ public void testImportsImmutability() SymbolTable f = Symtabs.CATALOG.getTable("fred", 1); SymbolTable[] symtabs = new SymbolTable[] { f }; - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setImports(f); IonTextWriterBuilder b2 = b.immutable(); @@ -412,7 +342,7 @@ public void testImportsNull() SymbolTable f = Symtabs.CATALOG.getTable("fred", 1); SymbolTable[] symtabs = new SymbolTable[] { f }; - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setImports(symtabs); b.setImports((SymbolTable[])null); assertSame(null, b.getImports()); @@ -427,7 +357,7 @@ public void testImportsNull() @Test(expected = UnsupportedOperationException.class) public void testLongStringThresholdImmutability() { - IonTextWriterBuilder b = IonTextWriterBuilder.standard(); + IonTextWriterBuilder b = standard(); b.setLongStringThreshold(99); IonTextWriterBuilder b2 = b.immutable(); diff --git a/src/test/java/com/amazon/ion/system/IonTextWriterBuilder_1_0_Test.java b/src/test/java/com/amazon/ion/system/IonTextWriterBuilder_1_0_Test.java new file mode 100644 index 0000000000..b104ac57b6 --- /dev/null +++ b/src/test/java/com/amazon/ion/system/IonTextWriterBuilder_1_0_Test.java @@ -0,0 +1,86 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion.system; + +import com.amazon.ion.IonWriter; +import org.junit.Test; + +import java.io.IOException; + +import static com.amazon.ion.SystemSymbols.ION_1_0; +import static com.amazon.ion.system.IonWriterBuilder.InitialIvmHandling.SUPPRESS; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; + +public class IonTextWriterBuilder_1_0_Test extends IonTextWriterBuilderTestBase { + + @Override + IonTextWriterBuilder standard() { + return IonTextWriterBuilder.standard(); + } + + @Override + String ivm() { + return ION_1_0; + } + + @Test + public void testInitialIvmHandling() + { + IonTextWriterBuilder b = standard(); + b.setInitialIvmHandling(SUPPRESS); + assertSame(SUPPRESS, b.getInitialIvmHandling()); + + // Test with...() on mutable builder + + IonTextWriterBuilder b2 = b.withInitialIvmHandling(null); + assertSame(b, b2); + assertSame(null, b.getInitialIvmHandling()); + + // Test with...() on immutable builder + + b2 = b.immutable(); + assertSame(null, b2.getInitialIvmHandling()); + IonTextWriterBuilder b3 = b2.withInitialIvmHandling(SUPPRESS); + assertNotSame(b2, b3); + assertSame(null, b2.getInitialIvmHandling()); + assertSame(SUPPRESS, b3.getInitialIvmHandling()); + } + + @Test(expected = UnsupportedOperationException.class) + public void testInitialIvmHandlingImmutability() + { + IonTextWriterBuilder b = standard(); + b.setInitialIvmHandling(SUPPRESS); + + IonTextWriterBuilder b2 = b.immutable(); + assertSame(SUPPRESS, b2.getInitialIvmHandling()); + b2.setInitialIvmHandling(null); + } + + @Test + public void testInitialIvmSuppression() + throws IOException + { + IonTextWriterBuilder b = standard(); + + StringBuilder out = new StringBuilder(); + IonWriter writer = b.build(out); + writer.writeSymbol(ivm()); + writer.writeNull(); + writer.writeSymbol(ivm()); + writer.close(); + assertEquals(ivm() + " null " + ivm(), out.toString()); + + b.withInitialIvmHandling(SUPPRESS); + out.setLength(0); + writer = b.build(out); + writer.writeSymbol(ivm()); + writer.writeSymbol(ivm()); + writer.writeNull(); + writer.writeSymbol(ivm()); + writer.close(); + assertEquals("null " + ivm(), out.toString()); + } +} diff --git a/src/test/java/com/amazon/ion/system/IonTextWriterBuilder_1_1_Test.java b/src/test/java/com/amazon/ion/system/IonTextWriterBuilder_1_1_Test.java new file mode 100644 index 0000000000..0c06b95487 --- /dev/null +++ b/src/test/java/com/amazon/ion/system/IonTextWriterBuilder_1_1_Test.java @@ -0,0 +1,40 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion.system; + +import com.amazon.ion.impl._Private_IonTextWriterBuilder_1_1; +import org.junit.Ignore; +import org.junit.Test; + +public class IonTextWriterBuilder_1_1_Test extends IonTextWriterBuilderTestBase { + @Override + IonTextWriterBuilder standard() { + return _Private_IonTextWriterBuilder_1_1.standard(); + } + + @Override + String ivm() { + return "$ion_1_1"; + } + + @Override + @Test + @Ignore + public void testImports() { + // TODO: skipped because IonManagedWriter_1_1 does not implement _Private_IonWriter.getSymbolTable. + } + + @Override + @Test + @Ignore + public void testCustomCatalog() { + // TODO: skipped because IonManagedWriter_1_1 does not implement _Private_IonWriter.getCatalog. + } + + @Override + @Test + @Ignore + public void testIvmMinimization() { + // TODO: skipped because the Ion 1.1 text writer does not yet support Ivm minimization. + } +}