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.parser;
018
019
020import java.io.*;
021
022import org.apache.juneau.marshall.*;
023import static org.apache.juneau.commons.utils.Shorts.*;
024
025/**
026 * Subclass of parser session objects for byte-based parsers.
027 *
028 * <h5 class='section'>Notes:</h5><ul>
029 *    <li class='warn'>This class is not thread safe and is typically discarded after one use.
030 * </ul>
031 *
032 * <h5 class='section'>See Also:</h5><ul>
033 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SerializersAndParsers">Serializers and Parsers</a>
034 * </ul>
035 */
036@SuppressWarnings({
037   "java:S1192", // Duplicated literals (argument/property names) read more clearly inline than as constants
038   "resource" // Resource management handled by ParserPipe
039})
040public class InputStreamParserSession extends ParserSession {
041
042   /**
043    * Builder class.
044    */
045   @SuppressWarnings({
046      "java:S119" // 'SELF' (CRTP self-type) is intentional and clearer than a single-letter name.
047   })
048   public abstract static class Builder<SELF extends Builder<SELF>> extends ParserSession.Builder<SELF> {
049
050      private final InputStreamParser ctx;
051
052      /**
053       * Constructor
054       *
055       * @param ctx The context creating this session.
056       *    <br>Cannot be <jk>null</jk>.
057       */
058      protected Builder(InputStreamParser ctx) {
059         super(reqnn("ctx", ctx));
060         this.ctx = ctx;
061      }
062
063      @Override
064      public InputStreamParserSession build() {
065         return new InputStreamParserSession(this);
066      }
067
068   }
069
070   /**
071    * Concrete default builder leaf for the non-subclassed {@code create()} path (CRTP terminal).
072    */
073   public static final class DefaultBuilder extends Builder<DefaultBuilder> {
074
075      DefaultBuilder(InputStreamParser ctx) {
076         super(ctx);
077      }
078   }
079
080   /**
081    * Creates a new builder for this object.
082    *
083    * @param ctx The context creating this session.
084    *    <br>Cannot be <jk>null</jk>.
085    * @return A new builder.
086    */
087   @SuppressWarnings({
088      "java:S1452" // Builder<?> wildcard return intentional; callers use it to construct session instances polymorphically
089   })
090   public static Builder<?> create(InputStreamParser ctx) {
091      return new DefaultBuilder(reqnn("ctx", ctx));
092   }
093
094   private final InputStreamParser ctx;
095
096   /**
097    * Constructor.
098    *
099    * @param builder The builder for this object.
100    *    <br>Cannot be <jk>null</jk>.
101    */
102   protected InputStreamParserSession(Builder<?> builder) {
103      super(builder);
104      this.ctx = builder.ctx;
105   }
106
107   /**
108    * Wraps the specified input object into a {@link ParserPipe} object so that it can be easily converted into
109    * a stream or reader.
110    *
111    * @param input
112    *    The input.
113    *    <br>This can be any of the following types:
114    *    <ul>
115    *       <li><jk>null</jk>
116    *       <li>{@link InputStream}
117    *       <li><code><jk>byte</jk>[]</code>
118    *       <li>{@link CharSequence} containing encoded bytes according to the {@link org.apache.juneau.marshall.MarshallingContext.Builder#binaryFormat(BinaryFormat) MarshallingContext.Builder#binaryFormat(BinaryFormat)} setting.
119    *    </ul>
120    * @return
121    *    A new {@link ParserPipe} wrapper around the specified input object.
122    */
123   @Override /* Overridden from ParserSession */
124   public final ParserPipe createPipe(Object input) {
125      return setPipe(new ParserPipe(input, isDebug(), ctx.isAutoCloseStreams(), ctx.isUnbuffered(), getBinaryFormat()));
126   }
127
128   @Override /* Overridden from ParserSession */
129   public final boolean isReaderParser() { return false; }
130
131   /**
132    * Binary input format.
133    *
134    * @see MarshallingContext.Builder#binaryFormat(BinaryFormat)
135    * @return
136    *    The format to use when converting strings to byte arrays.
137    */
138   protected final BinaryFormat getBinaryFormat() { return ctx.getMarshallingContext().getBinaryFormat(); }
139
140   /**
141    * Returns whether this binary parser has a native byte-array wire type.
142    *
143    * <p>
144    * Mirror of {@link org.apache.juneau.marshall.serializer.OutputStreamSerializerSession#hasNativeBytes()}
145    * for the parse side.  When {@code true}, {@code byte[]} payloads are consumed natively from the
146    * binary stream (e.g. MsgPack {@code bin} family, CBOR byte-string major type 2, BSON binary
147    * subtype {@code 0x05}) and {@link org.apache.juneau.marshall.swaps.BinarySwap} skips so the raw bytes
148    * reach the bean property directly.  When {@code false} the parser surfaces {@code byte[]}
149    * payloads as a string (UTF-8 column for Parquet, plain literal for binary RDF) and
150    * {@code BinarySwap} fires to apply the configured {@link BinaryFormat} reverse decoding back
151    * to {@code byte[]}.
152    *
153    * <p>
154    * Defaults to {@code true}.  Subclasses without a native byte-array wire type
155    * (e.g. {@link org.apache.juneau.marshall.parquet.ParquetParserSession} and the binary RDF parser
156    * sessions) override and return {@code false}.
157    *
158    * @return {@code true} if this parser has a native byte-array wire type.
159    */
160   public boolean hasNativeBytes() {
161      return true;
162   }
163}