1 /* 2 * ==================================================================== 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * ==================================================================== 20 * 21 * This software consists of voluntary contributions made by many 22 * individuals on behalf of the Apache Software Foundation. For more 23 * information on the Apache Software Foundation, please see 24 * <http://www.apache.org/>. 25 * 26 */ 27 28 package org.apache.hc.core5.http.io.entity; 29 30 import java.io.ByteArrayInputStream; 31 import java.io.ByteArrayOutputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.io.ObjectOutputStream; 35 import java.io.OutputStream; 36 import java.io.Serializable; 37 38 import org.apache.hc.core5.annotation.Contract; 39 import org.apache.hc.core5.annotation.ThreadingBehavior; 40 import org.apache.hc.core5.http.ContentType; 41 import org.apache.hc.core5.util.Args; 42 43 /** 44 * A streamed entity that obtains its content from a {@link Serializable}. 45 * <p> 46 * This class contains {@link ThreadingBehavior#IMMUTABLE_CONDITIONAL immutable attributes} but subclasses may contain 47 * additional immutable or mutable attributes. 48 * </p> 49 * 50 * @since 4.0 51 */ 52 @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL) 53 public class SerializableEntity extends AbstractHttpEntity { 54 55 private final Serializable serializable; 56 57 /** 58 * Creates new instance of this class. 59 * <p> 60 * The new instance: 61 * </p> 62 * <ul> 63 * <li>is not chunked.</li> 64 * </ul> 65 * 66 * @param serializable the serializable object. 67 * @param contentType the content type. 68 * @param contentEncoding the content encoding. 69 */ 70 public SerializableEntity( 71 final Serializable serializable, final ContentType contentType, final String contentEncoding) { 72 super(contentType, contentEncoding); 73 this.serializable = Args.notNull(serializable, "Source object"); 74 } 75 76 /** 77 * Creates new instance of this class. 78 * <p> 79 * The new instance: 80 * </p> 81 * <ul> 82 * <li>is not chunked.</li> 83 * <li>does not define a content encoding.</li> 84 * </ul> 85 * 86 * @param serializable the serializable object. 87 * @param contentType the content type. 88 */ 89 public SerializableEntity(final Serializable serializable, final ContentType contentType) { 90 this(serializable, contentType, null); 91 } 92 93 @Override 94 public final InputStream getContent() throws IOException, IllegalStateException { 95 final ByteArrayOutputStream buf = new ByteArrayOutputStream(); 96 writeTo(buf); 97 return new ByteArrayInputStream(buf.toByteArray()); 98 } 99 100 /** 101 * {@inheritDoc} 102 * <p> 103 * This implementation always returns {@code -1}. 104 * </p> 105 */ 106 @Override 107 public final long getContentLength() { 108 return -1; 109 } 110 111 /** 112 * {@inheritDoc} 113 * <p> 114 * This implementation always returns {@code true}. 115 * </p> 116 */ 117 @Override 118 public final boolean isRepeatable() { 119 return true; 120 } 121 122 /** 123 * {@inheritDoc} 124 * <p> 125 * This implementation always returns {@code false}. 126 * </p> 127 */ 128 @Override 129 public final boolean isStreaming() { 130 return false; 131 } 132 133 @Override 134 public final void writeTo(final OutputStream outStream) throws IOException { 135 Args.notNull(outStream, "Output stream"); 136 final ObjectOutputStream out = new ObjectOutputStream(outStream); 137 out.writeObject(this.serializable); 138 out.flush(); 139 } 140 141 /** 142 * {@inheritDoc} 143 * <p> 144 * This implementation is a no-op. 145 * </p> 146 */ 147 @Override 148 public final void close() throws IOException { 149 } 150 151 }