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.http.entity; 018 019import static org.apache.juneau.common.utils.IOUtils.*; 020import static org.apache.juneau.common.utils.ThrowableUtils.*; 021import static org.apache.juneau.http.HttpHeaders.*; 022 023import java.io.*; 024import java.nio.charset.*; 025import java.util.function.*; 026 027import org.apache.http.*; 028import org.apache.juneau.*; 029import org.apache.juneau.http.header.*; 030import org.apache.juneau.httppart.*; 031import org.apache.juneau.internal.*; 032import org.apache.juneau.serializer.*; 033 034/** 035 * HttpEntity for serializing POJOs as the body of HTTP requests. 036 * 037 * <h5 class='section'>See Also:</h5><ul> 038 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a> 039 040 * </ul> 041 */ 042public class SerializedEntity extends BasicHttpEntity { 043 044 //----------------------------------------------------------------------------------------------------------------- 045 // Instances 046 //----------------------------------------------------------------------------------------------------------------- 047 048 Serializer serializer; 049 HttpPartSchema schema; 050 051 /** 052 * Constructor. 053 */ 054 public SerializedEntity() { 055 } 056 057 /** 058 * Constructor. 059 * 060 * @param contentType The entity content type. 061 * @param content The entity content. 062 * @param serializer The entity serializer. 063 * @param schema The entity schema. Can be <jk>null</jk>. 064 */ 065 public SerializedEntity(ContentType contentType, Object content, Serializer serializer, HttpPartSchema schema) { 066 super(contentType, content); 067 this.serializer = serializer; 068 this.schema = schema; 069 } 070 071 /** 072 * Copy constructor. 073 * 074 * @param copyFrom The bean being copied. 075 */ 076 public SerializedEntity(SerializedEntity copyFrom) { 077 super(copyFrom); 078 this.serializer = copyFrom.serializer; 079 this.schema = copyFrom.schema; 080 } 081 082 /** 083 * Creates a builder for this class initialized with the contents of this bean. 084 * 085 * <p> 086 * Allows you to create a modifiable copy of this bean. 087 * 088 * @return A new builder bean. 089 */ 090 @Override 091 public SerializedEntity copy() { 092 return new SerializedEntity(this); 093 } 094 095 096 /** 097 * Copies this bean and sets the serializer and schema on it. 098 * 099 * @param serializer The new serializer for the bean. Can be <jk>null</jk>. 100 * @param schema The new schema for the bean. Can be <jk>null</jk>. 101 * @return Either a new bean with the serializer set, or this bean if 102 * both values are <jk>null</jk> or the serializer and schema were already set. 103 */ 104 public SerializedEntity copyWith(Serializer serializer, HttpPartSchema schema) { 105 if ((this.serializer == null && serializer != null) || (this.schema == null && schema != null)) { 106 SerializedEntity h = copy(); 107 if (serializer != null) 108 h.setSerializer(serializer); 109 if (schema != null) 110 h.setSchema(schema); 111 return h; 112 } 113 return this; 114 } 115 116 //----------------------------------------------------------------------------------------------------------------- 117 118 /** 119 * Sets the serializer on this entity bean. 120 * 121 * @param value The entity serializer, can be <jk>null</jk>. 122 * @return This object. 123 */ 124 public SerializedEntity setSerializer(Serializer value) { 125 assertModifiable(); 126 this.serializer = value; 127 return this; 128 } 129 130 /** 131 * Sets the schema on this entity bean. 132 * 133 * <p> 134 * Used to provide instructions to the serializer on how to serialize this object. 135 * 136 * @param value The entity schema, can be <jk>null</jk>. 137 * @return This object. 138 */ 139 public SerializedEntity setSchema(HttpPartSchema value) { 140 assertModifiable(); 141 this.schema = value; 142 return this; 143 } 144 145 146 147 @Override 148 public Header getContentType() { 149 Header x = super.getContentType(); 150 if (x == null && serializer != null) 151 x = contentType(serializer.getPrimaryMediaType()); 152 return x; 153 } 154 155 @Override /* HttpEntity */ 156 public void writeTo(OutputStream os) throws IOException { 157 try { 158 os = new NoCloseOutputStream(os); 159 Object o = contentOrElse(null); 160 if (serializer == null) { 161 try (Writer w = new OutputStreamWriter(os, UTF8)) { 162 w.write(o.toString()); 163 } 164 } else { 165 SerializerSession session = serializer.createSession().schema(schema).build(); 166 try (Closeable c = session.isWriterSerializer() ? new OutputStreamWriter(os, UTF8) : os) { 167 session.serialize(o, c); 168 } 169 } 170 } catch (SerializeException e) { 171 throw new BasicRuntimeException(e, "Serialization error on request body."); 172 } 173 } 174 175 @Override /* BasicHttpEntity */ 176 public boolean isRepeatable() { 177 return true; 178 } 179 180 @Override /* BasicHttpEntity */ 181 public long getContentLength() { 182 return -1; 183 } 184 185 @Override /* BasicHttpEntity */ 186 public InputStream getContent() { 187 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 188 try { 189 writeTo(baos); 190 return new ByteArrayInputStream(baos.toByteArray()); 191 } catch (IOException e) { 192 throw asRuntimeException(e); 193 } 194 } 195 @Override /* Overridden from BasicHttpEntity */ 196 public SerializedEntity setCached() throws IOException{ 197 super.setCached(); 198 return this; 199 } 200 201 @Override /* Overridden from BasicHttpEntity */ 202 public SerializedEntity setCharset(Charset value) { 203 super.setCharset(value); 204 return this; 205 } 206 207 @Override /* Overridden from BasicHttpEntity */ 208 public SerializedEntity setChunked() { 209 super.setChunked(); 210 return this; 211 } 212 213 @Override /* Overridden from BasicHttpEntity */ 214 public SerializedEntity setChunked(boolean value) { 215 super.setChunked(value); 216 return this; 217 } 218 219 @Override /* Overridden from BasicHttpEntity */ 220 public SerializedEntity setContent(Object value) { 221 super.setContent(value); 222 return this; 223 } 224 225 @Override /* Overridden from BasicHttpEntity */ 226 public SerializedEntity setContent(Supplier<?> value) { 227 super.setContent(value); 228 return this; 229 } 230 231 @Override /* Overridden from BasicHttpEntity */ 232 public SerializedEntity setContentEncoding(String value) { 233 super.setContentEncoding(value); 234 return this; 235 } 236 237 @Override /* Overridden from BasicHttpEntity */ 238 public SerializedEntity setContentEncoding(ContentEncoding value) { 239 super.setContentEncoding(value); 240 return this; 241 } 242 243 @Override /* Overridden from BasicHttpEntity */ 244 public SerializedEntity setContentLength(long value) { 245 super.setContentLength(value); 246 return this; 247 } 248 249 @Override /* Overridden from BasicHttpEntity */ 250 public SerializedEntity setContentType(String value) { 251 super.setContentType(value); 252 return this; 253 } 254 255 @Override /* Overridden from BasicHttpEntity */ 256 public SerializedEntity setContentType(ContentType value) { 257 super.setContentType(value); 258 return this; 259 } 260 261 @Override /* Overridden from BasicHttpEntity */ 262 public SerializedEntity setMaxLength(int value) { 263 super.setMaxLength(value); 264 return this; 265 } 266 267 @Override /* Overridden from BasicHttpEntity */ 268 public SerializedEntity setUnmodifiable() { 269 super.setUnmodifiable(); 270 return this; 271 } 272}