001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.marshall.stream;
018
019import java.io.*;
020
021/**
022 * Public low-level whole-value push generator over a Juneau-formatted document.
023 *
024 * <p>
025 * Format-neutral cursor that emits one whole-value record per {@link #write(Object)} call.
026 * Single-rooted formats accept exactly one call (subsequent calls throw); multi-rooted formats
027 * (jsonl, csv, sse) emit one line / row / event per call.
028 *
029 * <h5 class='section'>Usage:</h5>
030 * <p class='bjava'>
031 *    StringBuilder <jv>sb</jv> = <jk>new</jk> StringBuilder();
032 *    <jk>try</jk> (RecordWriter <jv>w</jv> = Json.<jsf>DEFAULT</jsf>.writeRecords(<jv>sb</jv>)) {
033 *       <jv>w</jv>.write(<jv>bean</jv>);
034 *    }
035 * </p>
036 *
037 * <h5 class='section'>Streaming quality:</h5>
038 * <ul>
039 *    <li>{@link #isStreaming()} == <jk>true</jk> &mdash; O(1)-memory streaming.  FULL-token formats
040 *       return a cursor that is also a {@link TokenWriter} (the structural surface).
041 *    <li>{@link #isStreaming()} == <jk>false</jk> &mdash; buffered whole-value cursor (backed by
042 *       {@link RecordAdapter}); {@link #write(Object)} delegates to the format's existing
043 *       serializer and the structural surface is not available.
044 * </ul>
045 *
046 * <h5 class='section'>Resource ownership:</h5>
047 * <p>
048 * Every {@link RecordReader} / {@code RecordWriter} produced by a factory method
049 * <b>closes what it was handed</b> &mdash; if the underlying input/output is {@link Closeable},
050 * {@link #close()} closes it.  This contract is symmetric across all factory methods.
051 *
052 * <h5 class='section'>See Also:</h5><ul>
053 *    <li>{@link RecordReader} &mdash; the pull-side counterpart.
054 *    <li>{@link TokenWriter} &mdash; structural extension for FULL-capability formats.
055 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SerializersAndParsers">Serializers and Parsers</a>
056 * </ul>
057 */
058public interface RecordWriter extends Closeable, Flushable {
059
060   /**
061    * Emits one whole-value record.
062    *
063    * @param value The value.  May be <jk>null</jk>.
064    * @return This object.
065    * @throws IOException If a problem occurred writing to the underlying stream.
066    */
067   RecordWriter write(Object value) throws IOException;
068
069   /**
070    * Returns <jk>true</jk> if this cursor is an O(1)-memory streaming cursor, or <jk>false</jk> if
071    * it is a buffered whole-value cursor (backed by {@link RecordAdapter}).
072    *
073    * @return <jk>true</jk> if this cursor streams; <jk>false</jk> if it buffers.
074    */
075   boolean isStreaming();
076
077   /**
078    * Flushes any buffered output to the underlying stream.
079    *
080    * @throws IOException If a problem occurred flushing the underlying stream.
081    */
082   @Override
083   void flush() throws IOException;
084
085   /**
086    * Closes the writer, flushing any buffered output first.
087    *
088    * <p>
089    * Implementations should be idempotent &mdash; closing a closed writer is a no-op.
090    */
091   @Override
092   void close() throws IOException;
093}