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 org.apache.juneau.*;
016
017/**
018 * Subclass of {@link Serializer} for byte-based serializers.
019 */
020public abstract class OutputStreamSerializer extends Serializer {
021
022   //-------------------------------------------------------------------------------------------------------------------
023   // Configurable properties
024   //-------------------------------------------------------------------------------------------------------------------
025
026   private static final String PREFIX = "OutputStreamSerializer.";
027
028   /**
029    * Configuration property:  Binary output format.
030    *
031    * <h5 class='section'>Property:</h5>
032    * <ul>
033    *    <li><b>Name:</b>  <js>"OutputStreamSerializer.binaryFormat.s"</js>
034    *    <li><b>Data type:</b>  {@link BinaryFormat}
035    *    <li><b>Default:</b>  {@link BinaryFormat#HEX}
036    *    <li><b>Session property:</b>  <jk>false</jk>
037    *    <li><b>Methods:</b>
038    *       <ul>
039    *          <li class='jm'>{@link OutputStreamSerializerBuilder#binaryFormat(BinaryFormat)}
040    *       </ul>
041    * </ul>
042    *
043    * <h5 class='section'>Description:</h5>
044    * <p>
045    * When using the {@link #serializeToString(Object)} method on stream-based serializers, this defines the format to use
046    * when converting the resulting byte array to a string.
047    *
048    *
049    * <h5 class='section'>Example:</h5>
050    * <p class='bcode w800'>
051    *    <jc>// Create a serializer that serializes to BASE64.</jc>
052    *    OutputStreamSerializer s = MsgPackSerializer
053    *       .<jsm>create</jsm>()
054    *       .binaryFormat(<jsf>BASE64</jsf>)
055    *       .build();
056    *
057    *    <jc>// Same, but use property.</jc>
058    *    OutputStreamSerializer s = MsgPackSerializer
059    *       .<jsm>create</jsm>()
060    *       .set(<jsf>SERIALIZER_binaryOutputFormat</jsf>, <js>"BASE64"</js>)
061    *       .build();
062    *
063    *    <jc>// The bean we want to serialize.</jc>
064    *    <jk>public class</jk> MyBean {...}
065    *
066    *    <jc>// MessagePack will generate BASE64-encoded string.</jc>
067    *    String msgPack = s.serializeToString(<jk>new</jk> MyBean());
068    * </p>
069    */
070   public static final String OSSERIALIZER_binaryFormat = PREFIX + "binaryFormat.s";
071
072   static final OutputStreamSerializer DEFAULT = new OutputStreamSerializer(PropertyStore.create().build(), "", "") {
073      @Override
074      public OutputStreamSerializerSession createSession(SerializerSessionArgs args) {
075         throw new NoSuchMethodError();
076      }
077   };
078
079   //-------------------------------------------------------------------------------------------------------------------
080   // Instance
081   //-------------------------------------------------------------------------------------------------------------------
082
083   private final BinaryFormat binaryFormat;
084
085   /**
086    * Constructor.
087    *
088    * @param ps
089    *    The property store containing all the settings for this object.
090    * @param produces
091    *    The media type that this serializer produces.
092    * @param accept
093    *    The accept media types that the serializer can handle.
094    *    <p>
095    *    Can contain meta-characters per the <code>media-type</code> specification of {@doc RFC2616.section14.1}
096    *    <p>
097    *    If empty, then assumes the only media type supported is <code>produces</code>.
098    *    <p>
099    *    For example, if this serializer produces <js>"application/json"</js> but should handle media types of
100    *    <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
101    *    <p class='bcode w800'>
102    *    <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
103    *    </p>
104    *    <br>...or...
105    *    <p class='bcode w800'>
106    *    <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*&#8203;/json"</js>);
107    *    </p>
108    * <p>
109    * The accept value can also contain q-values.
110    */
111   protected OutputStreamSerializer(PropertyStore ps, String produces, String accept) {
112      super(ps, produces, accept);
113
114      binaryFormat = getProperty(OSSERIALIZER_binaryFormat, BinaryFormat.class, BinaryFormat.HEX);
115   }
116
117
118   //-----------------------------------------------------------------------------------------------------------------
119   // Abstract methods
120   //-----------------------------------------------------------------------------------------------------------------
121
122   @Override /* SerializerSession */
123   public abstract OutputStreamSerializerSession createSession(SerializerSessionArgs args);
124
125
126   //-----------------------------------------------------------------------------------------------------------------
127   // Other methods
128   //-----------------------------------------------------------------------------------------------------------------
129
130   @Override /* Serializer */
131   public final boolean isWriterSerializer() {
132      return false;
133   }
134
135   /**
136    * Convenience method for serializing an object to a <code><jk>byte</jk></code>.
137    *
138    * @param o The object to serialize.
139    * @return The output serialized to a byte array.
140    * @throws SerializeException If a problem occurred trying to convert the output.
141    */
142   @Override
143   public final byte[] serialize(Object o) throws SerializeException {
144      return createSession(createDefaultSessionArgs()).serialize(o);
145   }
146
147   //-----------------------------------------------------------------------------------------------------------------
148   // Properties
149   //-----------------------------------------------------------------------------------------------------------------
150
151   /**
152    * Configuration property:  Binary output format.
153    *
154    * @see #OSSERIALIZER_binaryFormat
155    * @return
156    *    The format to use for the {@link #serializeToString(Object)} method on stream-based serializers when converting byte arrays to strings.
157    */
158   protected final BinaryFormat getBinaryFormat() {
159      return binaryFormat;
160   }
161
162   @Override /* Context */
163   public ObjectMap asMap() {
164      return super.asMap()
165         .append("OutputStreamSerializer", new ObjectMap()
166            .append("binaryFormat", binaryFormat)
167         );
168   }
169
170   /**
171    * @deprecated No replacement.
172    */
173   @SuppressWarnings({ "javadoc", "unused" })
174   @Deprecated
175   public final String serializeToHex(Object o) throws SerializeException {
176      return null;
177   }
178}