001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.serializer;
014
015import java.io.*;
016import java.lang.reflect.*;
017import java.util.*;
018import java.util.function.*;
019
020import org.apache.juneau.*;
021import org.apache.juneau.common.internal.*;
022import org.apache.juneau.httppart.*;
023import org.apache.juneau.internal.*;
024import org.apache.juneau.svl.*;
025
026/**
027 * Subclass of {@link SerializerSession} for stream-based serializers.
028 *
029 * <h5 class='topic'>Description</h5>
030 *
031 * This class is the parent class of all byte-based serializers.
032 * <br>It has 1 abstract method to implement...
033 * <ul>
034 *    <li>{@link #doSerialize(SerializerPipe, Object)}
035 * </ul>
036 *
037 * <h5 class='section'>Notes:</h5><ul>
038 *    <li class='warn'>This class is not thread safe and is typically discarded after one use.
039 * </ul>
040 *
041 * <h5 class='section'>See Also:</h5><ul>
042 *    <li class='link'><a class="doclink" href="../../../../index.html#jm.SerializersAndParsers">Serializers and Parsers</a>
043 * </ul>
044 */
045public class OutputStreamSerializerSession extends SerializerSession {
046
047   //-----------------------------------------------------------------------------------------------------------------
048   // Static
049   //-----------------------------------------------------------------------------------------------------------------
050
051   /**
052    * Creates a new builder for this object.
053    *
054    * @param ctx The context creating this session.
055    * @return A new builder.
056    */
057   public static Builder create(OutputStreamSerializer ctx) {
058      return new Builder(ctx);
059   }
060
061   //-----------------------------------------------------------------------------------------------------------------
062   // Builder
063   //-----------------------------------------------------------------------------------------------------------------
064
065   /**
066    * Builder class.
067    */
068   @FluentSetters
069   public static class Builder extends SerializerSession.Builder {
070
071      OutputStreamSerializer ctx;
072
073      /**
074       * Constructor
075       *
076       * @param ctx The context creating this session.
077       */
078      protected Builder(OutputStreamSerializer ctx) {
079         super(ctx);
080         this.ctx = ctx;
081      }
082
083      @Override
084      public OutputStreamSerializerSession build() {
085         return new OutputStreamSerializerSession(this);
086      }
087
088      // <FluentSetters>
089
090      @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */
091      public <T> Builder apply(Class<T> type, Consumer<T> apply) {
092         super.apply(type, apply);
093         return this;
094      }
095
096      @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */
097      public Builder debug(Boolean value) {
098         super.debug(value);
099         return this;
100      }
101
102      @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */
103      public Builder properties(Map<String,Object> value) {
104         super.properties(value);
105         return this;
106      }
107
108      @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */
109      public Builder property(String key, Object value) {
110         super.property(key, value);
111         return this;
112      }
113
114      @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */
115      public Builder unmodifiable() {
116         super.unmodifiable();
117         return this;
118      }
119
120      @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */
121      public Builder locale(Locale value) {
122         super.locale(value);
123         return this;
124      }
125
126      @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */
127      public Builder localeDefault(Locale value) {
128         super.localeDefault(value);
129         return this;
130      }
131
132      @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */
133      public Builder mediaType(MediaType value) {
134         super.mediaType(value);
135         return this;
136      }
137
138      @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */
139      public Builder mediaTypeDefault(MediaType value) {
140         super.mediaTypeDefault(value);
141         return this;
142      }
143
144      @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */
145      public Builder timeZone(TimeZone value) {
146         super.timeZone(value);
147         return this;
148      }
149
150      @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */
151      public Builder timeZoneDefault(TimeZone value) {
152         super.timeZoneDefault(value);
153         return this;
154      }
155
156      @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */
157      public Builder javaMethod(Method value) {
158         super.javaMethod(value);
159         return this;
160      }
161
162      @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */
163      public Builder resolver(VarResolverSession value) {
164         super.resolver(value);
165         return this;
166      }
167
168      @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */
169      public Builder schema(HttpPartSchema value) {
170         super.schema(value);
171         return this;
172      }
173
174      @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */
175      public Builder schemaDefault(HttpPartSchema value) {
176         super.schemaDefault(value);
177         return this;
178      }
179
180      @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */
181      public Builder uriContext(UriContext value) {
182         super.uriContext(value);
183         return this;
184      }
185
186      // </FluentSetters>
187   }
188
189   //-----------------------------------------------------------------------------------------------------------------
190   // Instance
191   //-----------------------------------------------------------------------------------------------------------------
192
193   private final OutputStreamSerializer ctx;
194
195   /**
196    * Constructor.
197    *
198    * @param builder The builder for this object.
199    */
200   protected OutputStreamSerializerSession(Builder builder) {
201      super(builder);
202      ctx = builder.ctx;
203   }
204
205   @Override /* SerializerSession */
206   public final boolean isWriterSerializer() {
207      return false;
208   }
209
210   @Override /* SerializerSession */
211   protected SerializerPipe createPipe(Object output) {
212      return new SerializerPipe(output);
213   }
214
215   /**
216    * Convenience method for serializing an object to a <code><jk>byte</jk></code>.
217    *
218    * @param o The object to serialize.
219    * @return The output serialized to a byte array.
220    * @throws SerializeException If a problem occurred trying to convert the output.
221    */
222   @Override /* SerializerSession */
223   public final byte[] serialize(Object o) throws SerializeException {
224      ByteArrayOutputStream baos = new ByteArrayOutputStream();
225      try {
226         serialize(o, baos);
227         baos.flush();
228      } catch (IOException e) {
229         throw new SerializeException(e); // Should never happen.
230      }
231      return baos.toByteArray();
232   }
233
234   @Override /* SerializerSession */
235   public final String serializeToString(Object o) throws SerializeException {
236      byte[] b = serialize(o);
237      switch(getBinaryFormat()) {
238         case SPACED_HEX:  return StringUtils.toSpacedHex(b);
239         case HEX:  return StringUtils.toHex(b);
240         case BASE64:  return StringUtils.base64Encode(b);
241         default: return null;
242      }
243   }
244
245   //-----------------------------------------------------------------------------------------------------------------
246   // Properties
247   //-----------------------------------------------------------------------------------------------------------------
248
249   /**
250    * Binary output format.
251    *
252    * @see OutputStreamSerializer.Builder#binaryFormat(BinaryFormat)
253    * @return
254    *    The format to use for the {@link #serializeToString(Object)} method on stream-based serializers when converting byte arrays to strings.
255    */
256   protected final BinaryFormat getBinaryFormat() {
257      return ctx.getBinaryFormat();
258   }
259}