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 static org.apache.juneau.collections.JsonMap.*; 016 017import java.io.*; 018import java.lang.reflect.*; 019import java.nio.charset.*; 020import java.util.*; 021import java.util.function.*; 022 023import org.apache.juneau.*; 024import org.apache.juneau.collections.*; 025import org.apache.juneau.httppart.*; 026import org.apache.juneau.internal.*; 027import org.apache.juneau.svl.*; 028 029/** 030 * Subclass of {@link SerializerSession} for character-based serializers. 031 * 032 * <h5 class='topic'>Description</h5> 033 * 034 * This class is typically the parent class of all character-based serializers. 035 * <br>It has 1 abstract method to implement... 036 * <ul class='spaced-list'> 037 * <li> 038 * {@link #doSerialize(SerializerPipe, Object)} 039 * </ul> 040 * 041 * <h5 class='section'>Notes:</h5><ul> 042 * <li class='warn'>This class is not thread safe and is typically discarded after one use. 043 * </ul> 044 * 045 * <h5 class='section'>See Also:</h5><ul> 046 * <li class='link'><a class="doclink" href="../../../../index.html#jm.SerializersAndParsers">Serializers and Parsers</a> 047 * </ul> 048 */ 049public class WriterSerializerSession extends SerializerSession { 050 051 //------------------------------------------------------------------------------------------------------------------- 052 // Static 053 //------------------------------------------------------------------------------------------------------------------- 054 055 /** 056 * Creates a new builder for this object. 057 * 058 * @param ctx The context creating this session. 059 * @return A new builder. 060 */ 061 public static Builder create(WriterSerializer ctx) { 062 return new Builder(ctx); 063 } 064 065 //----------------------------------------------------------------------------------------------------------------- 066 // Builder 067 //----------------------------------------------------------------------------------------------------------------- 068 069 /** 070 * Builder class. 071 */ 072 @FluentSetters 073 public static class Builder extends SerializerSession.Builder { 074 075 WriterSerializer ctx; 076 boolean useWhitespace; 077 Charset fileCharset, streamCharset; 078 079 /** 080 * Constructor 081 * 082 * @param ctx The context creating this session. 083 */ 084 protected Builder(WriterSerializer ctx) { 085 super(ctx); 086 this.ctx = ctx; 087 useWhitespace = ctx.useWhitespace; 088 fileCharset = ctx.fileCharset; 089 streamCharset = ctx.streamCharset; 090 } 091 092 @Override 093 public WriterSerializerSession build() { 094 return new WriterSerializerSession(this); 095 } 096 097 /** 098 * File charset. 099 * 100 * <p> 101 * The character set to use for writing Files to the file system. 102 * 103 * <p> 104 * Used when passing in files to {@link Serializer#serialize(Object, Object)}. 105 * 106 * <p> 107 * If not specified, defaults to the JVM system default charset. 108 * 109 * @param value 110 * The new property value. 111 * <br>Can be <jk>null</jk>. 112 * @return This object. 113 */ 114 @FluentSetter 115 public Builder fileCharset(Charset value) { 116 if (value != null) 117 fileCharset = value; 118 return this; 119 } 120 121 /** 122 * Output stream charset. 123 * 124 * <p> 125 * The character set to use when writing to OutputStreams. 126 * 127 * <p> 128 * Used when passing in output streams and byte arrays to {@link WriterSerializer#serialize(Object, Object)}. 129 * 130 * <p> 131 * If not specified, defaults to UTF-8. 132 * 133 * @param value 134 * The new property value. 135 * <br>Can be <jk>null</jk>. 136 * @return This object. 137 */ 138 @FluentSetter 139 public Builder streamCharset(Charset value) { 140 if (value != null) 141 streamCharset = value; 142 return this; 143 } 144 145 /** 146 * Use whitespace. 147 * 148 * <p> 149 * If true, whitespace is added to the output to improve readability. 150 * 151 * @param value 152 * The new property value. 153 * <br>Can be <jk>null</jk>. 154 * @return This object. 155 */ 156 @FluentSetter 157 public Builder useWhitespace(Boolean value) { 158 if (value != null) 159 useWhitespace = value; 160 return this; 161 } 162 163 // <FluentSetters> 164 165 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 166 public <T> Builder apply(Class<T> type, Consumer<T> apply) { 167 super.apply(type, apply); 168 return this; 169 } 170 171 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 172 public Builder debug(Boolean value) { 173 super.debug(value); 174 return this; 175 } 176 177 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 178 public Builder properties(Map<String,Object> value) { 179 super.properties(value); 180 return this; 181 } 182 183 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 184 public Builder property(String key, Object value) { 185 super.property(key, value); 186 return this; 187 } 188 189 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 190 public Builder unmodifiable() { 191 super.unmodifiable(); 192 return this; 193 } 194 195 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 196 public Builder locale(Locale value) { 197 super.locale(value); 198 return this; 199 } 200 201 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 202 public Builder localeDefault(Locale value) { 203 super.localeDefault(value); 204 return this; 205 } 206 207 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 208 public Builder mediaType(MediaType value) { 209 super.mediaType(value); 210 return this; 211 } 212 213 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 214 public Builder mediaTypeDefault(MediaType value) { 215 super.mediaTypeDefault(value); 216 return this; 217 } 218 219 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 220 public Builder timeZone(TimeZone value) { 221 super.timeZone(value); 222 return this; 223 } 224 225 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 226 public Builder timeZoneDefault(TimeZone value) { 227 super.timeZoneDefault(value); 228 return this; 229 } 230 231 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 232 public Builder javaMethod(Method value) { 233 super.javaMethod(value); 234 return this; 235 } 236 237 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 238 public Builder resolver(VarResolverSession value) { 239 super.resolver(value); 240 return this; 241 } 242 243 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 244 public Builder schema(HttpPartSchema value) { 245 super.schema(value); 246 return this; 247 } 248 249 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 250 public Builder schemaDefault(HttpPartSchema value) { 251 super.schemaDefault(value); 252 return this; 253 } 254 255 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 256 public Builder uriContext(UriContext value) { 257 super.uriContext(value); 258 return this; 259 } 260 261 // </FluentSetters> 262 } 263 264 //----------------------------------------------------------------------------------------------------------------- 265 // Instance 266 //----------------------------------------------------------------------------------------------------------------- 267 268 private final WriterSerializer ctx; 269 private final boolean useWhitespace; 270 private final Charset streamCharset, fileCharset; 271 272 /** 273 * Constructor. 274 * 275 * @param builder The builder for this object. 276 */ 277 protected WriterSerializerSession(Builder builder) { 278 super(builder); 279 ctx = builder.ctx; 280 streamCharset = builder.streamCharset; 281 fileCharset = builder.fileCharset; 282 useWhitespace = builder.useWhitespace; 283 } 284 285 @Override /* SerializerSession */ 286 public final boolean isWriterSerializer() { 287 return true; 288 } 289 290 @Override /* SerializerSession */ 291 protected SerializerPipe createPipe(Object output) { 292 return new SerializerPipe(output, streamCharset, fileCharset); 293 } 294 295 /** 296 * Convenience method for serializing an object to a <c>String</c>. 297 * 298 * @param o The object to serialize. 299 * @return The output serialized to a string. 300 * @throws SerializeException If a problem occurred trying to convert the output. 301 */ 302 @Override /* SerializerSession */ 303 public final String serialize(Object o) throws SerializeException { 304 StringWriter w = new StringWriter(); 305 try { 306 serialize(o, w); 307 } catch (IOException e) { 308 throw new SerializeException(e); // Shouldn't happen. 309 } 310 return w.toString(); 311 } 312 313 @Override /* SerializerSession */ 314 public final String serializeToString(Object o) throws SerializeException { 315 return serialize(o); 316 } 317 318 //----------------------------------------------------------------------------------------------------------------- 319 // Properties 320 //----------------------------------------------------------------------------------------------------------------- 321 322 /** 323 * Maximum indentation. 324 * 325 * @see WriterSerializer.Builder#maxIndent(int) 326 * @return 327 * The maximum indentation level in the serialized document. 328 */ 329 protected final int getMaxIndent() { 330 return ctx.getMaxIndent(); 331 } 332 333 /** 334 * Quote character. 335 * 336 * @see WriterSerializer.Builder#quoteChar(char) 337 * @return 338 * The character used for quoting attributes and values. 339 */ 340 protected char getQuoteChar() { 341 return ctx.getQuoteChar(); 342 } 343 344 /** 345 * Use whitespace. 346 * 347 * @see WriterSerializer.Builder#useWhitespace() 348 * @return 349 * The character used for quoting attributes and values. 350 */ 351 protected final boolean isUseWhitespace() { 352 return useWhitespace; 353 } 354 355 /** 356 * Returns the file charset defined on this session. 357 * 358 * @return the file charset defined on this session. 359 */ 360 public Charset getFileCharset() { 361 return fileCharset; 362 } 363 364 /** 365 * Returns the stream charset defined on this session. 366 * 367 * @return the stream charset defined on this session. 368 */ 369 public Charset getStreamCharset() { 370 return streamCharset; 371 } 372 373 //----------------------------------------------------------------------------------------------------------------- 374 // Other methods 375 //----------------------------------------------------------------------------------------------------------------- 376 377 @Override /* ContextSession */ 378 protected JsonMap properties() { 379 return filteredMap("fileCharset", fileCharset, "streamCharset", streamCharset, "useWhitespace", useWhitespace); 380 } 381}