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