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

com.amazon.ion.impl._Private_IonBinaryWriterBuilder 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.impl;

import static com.amazon.ion.impl._Private_Utils.initialSymtab;

import com.amazon.ion.IonBinaryWriter;
import com.amazon.ion.IonCatalog;
import com.amazon.ion.IonException;
import com.amazon.ion.IonSystem;
import com.amazon.ion.IonWriter;
import com.amazon.ion.SubstituteSymbolTableException;
import com.amazon.ion.SymbolTable;
import com.amazon.ion.ValueFactory;
import com.amazon.ion.impl.BlockedBuffer.BufferedOutputStream;
import com.amazon.ion.impl.bin._Private_IonManagedBinaryWriterBuilder;
import com.amazon.ion.impl.bin._Private_IonManagedBinaryWriterBuilder.AllocatorMode;
import com.amazon.ion.system.IonBinaryWriterBuilder;
import com.amazon.ion.system.IonSystemBuilder;
import java.io.IOException;
import java.io.OutputStream;

/**
 * NOT FOR APPLICATION USE!
 */
@SuppressWarnings("deprecation")
public class _Private_IonBinaryWriterBuilder
    extends IonBinaryWriterBuilder
{
    // amazon-ion/ion-java/issues/59 expose configuration points properly and figure out deprecation path for the old writer.
    private final _Private_IonManagedBinaryWriterBuilder myBinaryWriterBuilder;
    private ValueFactory mySymtabValueFactory;

    /** System or local */
    private SymbolTable  myInitialSymbolTable;


    private _Private_IonBinaryWriterBuilder()
    {
        myBinaryWriterBuilder =
            _Private_IonManagedBinaryWriterBuilder
                .create(AllocatorMode.POOLED)
                .withPaddedLengthPreallocation(1)
                ;
    }


    private
    _Private_IonBinaryWriterBuilder(_Private_IonBinaryWriterBuilder that)
    {
        super(that);

        this.mySymtabValueFactory = that.mySymtabValueFactory;
        this.myInitialSymbolTable = that.myInitialSymbolTable;
        this.myBinaryWriterBuilder = that.myBinaryWriterBuilder.copy();
    }


    /**
     * @return a new mutable builder.
     */
    public static _Private_IonBinaryWriterBuilder standard()
    {
        return new _Private_IonBinaryWriterBuilder.Mutable();
    }


    //=========================================================================


    @Override
    public final _Private_IonBinaryWriterBuilder copy()
    {
        return new Mutable(this);
    }

    @Override
    public _Private_IonBinaryWriterBuilder immutable()
    {
        return this;
    }

    @Override
    public _Private_IonBinaryWriterBuilder mutable()
    {
        return copy();
    }


    //=========================================================================

    // TODO The symtab value factory should not be needed.
    //      It's an artifact of how the binary writer gathers symtabs that
    //      are written through it.

    public ValueFactory getSymtabValueFactory()
    {
        return mySymtabValueFactory;
    }

    public void setSymtabValueFactory(ValueFactory factory)
    {
        mutationCheck();
        mySymtabValueFactory = factory;
    }

    public _Private_IonBinaryWriterBuilder
    withSymtabValueFactory(ValueFactory factory)
    {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setSymtabValueFactory(factory);
        return b;
    }


    //=========================================================================


    @Override
    public SymbolTable getInitialSymbolTable()
    {
        return myInitialSymbolTable;
    }

    /**
     * Declares the symbol table to use for encoded data.
     * To avoid conflicts between different data streams, if the given instance
     * is mutable, it will be copied when {@code build()} is called.
     *
     * @param symtab must be a local or system symbol table.
     * May be null, in which case the initial symtab is that of
     * {@code $ion_1_0}.
     *
     * @throws SubstituteSymbolTableException
     * if any imported table is a substitute (see {@link SymbolTable}).
     */
    @Override
    public void setInitialSymbolTable(SymbolTable symtab)
    {
        mutationCheck();

        if (symtab != null)
        {
            if (symtab.isLocalTable())
            {
                SymbolTable[] imports =
                    ((_Private_LocalSymbolTable) symtab).getImportedTablesNoCopy();
                for (SymbolTable imported : imports)
                {
                    if (imported.isSubstitute())
                    {
                        String message =
                            "Cannot encode with substitute symbol table: " +
                            imported.getName();
                        throw new SubstituteSymbolTableException(message);
                    }
                }
            }
            else if (! symtab.isSystemTable())
            {
                String message = "symtab must be local or system table";
                throw new IllegalArgumentException(message);
            }
        }

        myInitialSymbolTable = symtab;
        myBinaryWriterBuilder.withInitialSymbolTable(symtab);
    }

    /**
     * Defaults to $ion_1_0 if null.
     * @param symtab may be null.
     */
    @Override
    public
    _Private_IonBinaryWriterBuilder withInitialSymbolTable(SymbolTable symtab)
    {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setInitialSymbolTable(symtab);
        return b;
    }

    @Override
    public _Private_IonBinaryWriterBuilder withAutoFlushEnabled(boolean autoFlushEnabled) {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setAutoFlushEnabled(autoFlushEnabled);
        return b;
    }

    public void setAutoFlushEnabled(boolean autoFlushEnabled) {
        mutationCheck();
        if (autoFlushEnabled) {
            myBinaryWriterBuilder.withAutoFlushEnabled();
            myBinaryWriterBuilder.withLocalSymbolTableAppendEnabled();
        } else {
            myBinaryWriterBuilder.withAutoFlushDisabled();
        }
    }
    @Override
    public void setLocalSymbolTableAppendEnabled(boolean enabled)
    {
        mutationCheck();
        if (enabled)
        {
            myBinaryWriterBuilder.withLocalSymbolTableAppendEnabled();
        }
        else
        {
            myBinaryWriterBuilder.withLocalSymbolTableAppendDisabled();
        }
    }

    @Override
    public _Private_IonBinaryWriterBuilder withLocalSymbolTableAppendEnabled()
    {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setLocalSymbolTableAppendEnabled(true);
        return b;
    }

    @Override
    public _Private_IonBinaryWriterBuilder withLocalSymbolTableAppendDisabled()
    {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setLocalSymbolTableAppendEnabled(false);
        return b;
    }

    @Override
    public _Private_IonBinaryWriterBuilder withBlockSize(int size) {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setBlockSize(size);
        return b;
    }

    @Override
    public void setIsFloatBinary32Enabled(boolean enabled) {
        mutationCheck();
        if (enabled)
        {
            myBinaryWriterBuilder.withFloatBinary32Enabled();
        }
        else
        {
            myBinaryWriterBuilder.withFloatBinary32Disabled();
        }
    }

    @Override
    public
    _Private_IonBinaryWriterBuilder withFloatBinary32Enabled() {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setIsFloatBinary32Enabled(true);
        return b;
    }

    @Override
    public
    _Private_IonBinaryWriterBuilder withFloatBinary32Disabled() {
        _Private_IonBinaryWriterBuilder b = mutable();
        b.setIsFloatBinary32Enabled(false);
        return b;
    }

    @Override
    public void setImports(final SymbolTable... imports)
    {
        super.setImports(imports);
        myBinaryWriterBuilder.withImports(imports);
    }

    @Override
    public void setCatalog(final IonCatalog catalog)
    {
        super.setCatalog(catalog);
        myBinaryWriterBuilder.withCatalog(catalog);
    }

    @Override
    public void setStreamCopyOptimized(final boolean optimized)
    {
        super.setStreamCopyOptimized(optimized);
        myBinaryWriterBuilder.withStreamCopyOptimization(optimized);
    }

    //=========================================================================

    public void setBlockSize(int size) {
        myBinaryWriterBuilder.withUserBlockSize(size);
        // Adjust the symbol table block size when the user block size is smaller than the default, because in most cases, the symbol table is smaller than the data.
        if (size < myBinaryWriterBuilder.DEFAULT_BLOCK_SIZE) {
            myBinaryWriterBuilder.withSymbolsBlockSize(size);
        }
    }

    /**
     * Fills all properties and returns an immutable builder.
     */
    private _Private_IonBinaryWriterBuilder fillDefaults()
    {
        // Ensure that we don't modify the user's builder.
        _Private_IonBinaryWriterBuilder b = copy();

        if (b.getSymtabValueFactory() == null)
        {
            IonSystem system = IonSystemBuilder.standard().build();
            b.setSymtabValueFactory(system);
        }

        return b.immutable();
    }

    /**
     * Fills all properties and returns an immutable builder.
     */
    private _Private_IonBinaryWriterBuilder fillLegacyDefaults()
    {
        // amazon-ion/ion-java/issues/59 Fix this to use the new writer or eliminate it

        // Ensure that we don't modify the user's builder.
        _Private_IonBinaryWriterBuilder b = copy();

        if (b.getSymtabValueFactory() == null)
        {
            IonSystem system = IonSystemBuilder.standard().build();
            b.setSymtabValueFactory(system);
        }

        SymbolTable initialSymtab = b.getInitialSymbolTable();
        if (initialSymtab == null)
        {
            initialSymtab = initialSymtab(LocalSymbolTable.DEFAULT_LST_FACTORY,
                                          _Private_Utils.systemSymtab(1),
                                          b.getImports());
            b.setInitialSymbolTable(initialSymtab);
        }
        else if (initialSymtab.isSystemTable())
        {
            initialSymtab = initialSymtab(LocalSymbolTable.DEFAULT_LST_FACTORY,
                                          initialSymtab,
                                          b.getImports());
            b.setInitialSymbolTable(initialSymtab);
        }

        return b.immutable();
    }


    private IonWriterSystemBinary buildSystemWriter(OutputStream out)
    {
        SymbolTable defaultSystemSymtab =
            myInitialSymbolTable.getSystemSymbolTable();

        return new IonWriterSystemBinary(defaultSystemSymtab,
                                         out,
                                         false /* autoFlush */,
                                         true /* ensureInitialIvm */);
    }


    /**
     * Returns a symtab usable in a local context.
     * This copies {@link #myInitialSymbolTable} if symbols have been added to
     * it since {@link #setInitialSymbolTable(SymbolTable)} was called.
     */
    SymbolTable buildContextSymbolTable()
    {
        if (myInitialSymbolTable.isReadOnly())
        {
            return myInitialSymbolTable;
        }

        return ((_Private_LocalSymbolTable) myInitialSymbolTable).makeCopy();
    }


    @Override
    public final IonWriter build(OutputStream out)
    {
        _Private_IonBinaryWriterBuilder b = fillDefaults();
        try
        {
            return b.myBinaryWriterBuilder.newWriter(out);
        }
        catch (final IOException e)
        {
            throw new IonException("I/O Error", e);
        }
    }


    @Deprecated
    public final IonBinaryWriter buildLegacy()
    {
        // amazon-ion/ion-java/issues/59 Fix this to use the new writer or eliminate it
        _Private_IonBinaryWriterBuilder b = fillLegacyDefaults();

        IonWriterSystemBinary systemWriter =
            b.buildSystemWriter(new BufferedOutputStream());

        return new _Private_IonBinaryWriterImpl(b, systemWriter);
    }


    //=========================================================================


    private static final class Mutable
        extends _Private_IonBinaryWriterBuilder
    {
        private Mutable() { }

        private Mutable(_Private_IonBinaryWriterBuilder that)
        {
            super(that);
        }

        @Override
        public _Private_IonBinaryWriterBuilder immutable()
        {
            return new _Private_IonBinaryWriterBuilder(this);
        }

        @Override
        public _Private_IonBinaryWriterBuilder mutable()
        {
            return this;
        }

        @Override
        protected void mutationCheck()
        {
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy