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.serializer;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import org.apache.juneau.commons.function.*;
022import org.apache.juneau.marshall.*;
023
024/**
025 * Subclass of {@link Serializer} for byte-based serializers.
026 *
027 * <h5 class='section'>Notes:</h5><ul>
028 *    <li class='note'>This class is thread safe and reusable.
029 * </ul>
030 *
031 * <h5 class='section'>See Also:</h5><ul>
032 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SerializersAndParsers">Serializers and Parsers</a>
033
034 * </ul>
035 */
036@SuppressWarnings({
037   "java:S1192", // Duplicated literals (argument/property names) read more clearly inline than as constants
038   "java:S9149" // Per-format static factories intentionally shadow the parent's.
039})
040public class OutputStreamSerializer extends Serializer implements ThrowingFunction<Object,byte[]> {
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 Serializer.Builder<SELF> {
049
050      /**
051       * Constructor, default settings.
052       */
053      protected Builder() {}
054
055      /**
056       * Copy constructor.
057       *
058       * @param copyFrom The builder to copy from.
059       *    <br>Cannot be <jk>null</jk>.
060       */
061      protected Builder(Builder<?> copyFrom) {
062         super(reqnn("copyFrom", copyFrom));
063      }
064
065      /**
066       * Copy constructor.
067       *
068       * @param copyFrom The bean to copy from.
069       *    <br>Cannot be <jk>null</jk>.
070       */
071      protected Builder(OutputStreamSerializer copyFrom) {
072         super(reqnn("copyFrom", copyFrom));
073      }
074
075      @Override /* Overridden from Context.Builder<?> */
076      public OutputStreamSerializer build() {
077         return build(OutputStreamSerializer.class);
078      }
079
080      @Override /* Overridden from Context.Builder<?> */
081      public abstract SELF copy();
082
083
084   }
085
086   /**
087    * Concrete default builder leaf for the non-subclassed {@link OutputStreamSerializer#create()} / {@link OutputStreamSerializer#copy()} path.
088    */
089   @SuppressWarnings({
090      "java:S110" // Inheritance depth follows the serializer builder chain; intentional layered design
091   })
092   public static final class DefaultBuilder extends Builder<DefaultBuilder> {
093
094      DefaultBuilder() {}
095
096      DefaultBuilder(OutputStreamSerializer copyFrom) {
097         super(copyFrom);
098      }
099
100      DefaultBuilder(Builder<?> copyFrom) {
101         super(copyFrom);
102      }
103
104      @Override /* Overridden from Context.Builder<?> */
105      public DefaultBuilder copy() {
106         return new DefaultBuilder(this);
107      }
108   }
109
110   /**
111    * Creates a new builder for this object.
112    *
113    * @return A new builder.
114    */
115   @SuppressWarnings({
116      "java:S1452" // Builder<?> wildcard return intentional; callers chain via fluent API without needing the concrete type
117   })
118   public static Builder<?> create() {
119      return new DefaultBuilder();
120   }
121
122   /**
123    * Constructor.
124    *
125    * @param builder
126    *    The builder for this object.
127    *    <br>Cannot be <jk>null</jk>.
128    */
129   protected OutputStreamSerializer(Builder<?> builder) {
130      super(builder);
131   }
132
133   @Override /* Overridden from Context */
134   public OutputStreamSerializerSession.Builder<?> createSession() {
135      return OutputStreamSerializerSession.create(this);
136   }
137
138   @Override /* Overridden from Context */
139   public OutputStreamSerializerSession getSession() { return createSession().build(); }
140
141   @Override /* Overridden from Serializer */
142   public final boolean isWriterSerializer() { return false; }
143
144   /**
145    * Convenience method for serializing an object to a <code><jk>byte</jk></code>.
146    *
147    * @param o The object to serialize.
148    * @return The output serialized to a byte array.
149    * @throws SerializeException If a problem occurred trying to convert the output.
150    */
151   @Override
152   public final byte[] write(Object o) throws SerializeException {
153      return getSession().write(o);
154   }
155
156   /**
157    * Allows this serializer to be used as a {@link ThrowingFunction} that converts an object to its serialized byte array form.
158    *
159    * <p>
160    * Because {@link OutputStreamSerializer} implements {@link ThrowingFunction ThrowingFunction&lt;Object,byte[]&gt;}, a
161    * serializer instance can be passed directly wherever a {@link java.util.function.Function Function} or
162    * {@link ThrowingFunction} is expected (e.g. assertion transform methods).
163    *
164    * @param o The object to serialize.
165    * @return The output serialized to a byte array.
166    * @throws Exception If a problem occurred trying to convert the output.
167    */
168   @Override /* Overridden from ThrowingFunction */
169   public final byte[] applyThrows(Object o) throws Exception {
170      return write(o);
171   }
172
173   /**
174    * Binary output format.
175    *
176    * <p>
177    * Resolves from the configured {@link MarshallingContext#getBinaryFormat()}.
178    *
179    * @return The binary wire format used by this serializer.
180    */
181   protected final BinaryFormat getBinaryFormat() { return getMarshallingContext().getBinaryFormat(); }
182}