001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027 028package org.apache.http.entity; 029 030import java.io.IOException; 031import java.io.InputStream; 032import java.io.OutputStream; 033 034import org.apache.http.impl.io.EmptyInputStream; 035import org.apache.http.util.Args; 036import org.apache.http.util.Asserts; 037 038/** 039 * A generic streamed, non-repeatable entity that obtains its content 040 * from an {@link InputStream}. 041 * 042 * @since 4.0 043 */ 044public class BasicHttpEntity extends AbstractHttpEntity { 045 046 private InputStream content; 047 private long length; 048 049 /** 050 * Creates a new basic entity. 051 * The content is initially missing, the content length 052 * is set to a negative number. 053 */ 054 public BasicHttpEntity() { 055 super(); 056 this.length = -1; 057 } 058 059 @Override 060 public long getContentLength() { 061 return this.length; 062 } 063 064 /** 065 * Obtains the content, once only. 066 * 067 * @return the content, if this is the first call to this method 068 * since {@link #setContent setContent} has been called 069 * 070 * @throws IllegalStateException 071 * if the content has not been provided 072 */ 073 @Override 074 public InputStream getContent() throws IllegalStateException { 075 Asserts.check(this.content != null, "Content has not been provided"); 076 return this.content; 077 } 078 079 /** 080 * Tells that this entity is not repeatable. 081 * 082 * @return {@code false} 083 */ 084 @Override 085 public boolean isRepeatable() { 086 return false; 087 } 088 089 /** 090 * Specifies the length of the content. 091 * 092 * @param len the number of bytes in the content, or 093 * a negative number to indicate an unknown length 094 */ 095 public void setContentLength(final long len) { 096 this.length = len; 097 } 098 099 /** 100 * Specifies the content. 101 * 102 * @param instream the stream to return with the next call to 103 * {@link #getContent getContent} 104 */ 105 public void setContent(final InputStream instream) { 106 this.content = instream; 107 } 108 109 @Override 110 public void writeTo(final OutputStream outstream) throws IOException { 111 Args.notNull(outstream, "Output stream"); 112 final InputStream instream = getContent(); 113 try { 114 int l; 115 final byte[] tmp = new byte[OUTPUT_BUFFER_SIZE]; 116 while ((l = instream.read(tmp)) != -1) { 117 outstream.write(tmp, 0, l); 118 } 119 } finally { 120 instream.close(); 121 } 122 } 123 124 @Override 125 public boolean isStreaming() { 126 return this.content != null && this.content != EmptyInputStream.INSTANCE; 127 } 128 129}