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.nio.protocol; 029 030import java.io.IOException; 031 032import org.apache.http.HttpEntity; 033import org.apache.http.HttpResponse; 034import org.apache.http.nio.ContentEncoder; 035import org.apache.http.nio.IOControl; 036import org.apache.http.nio.entity.EntityAsyncContentProducer; 037import org.apache.http.nio.entity.HttpAsyncContentProducer; 038import org.apache.http.protocol.HttpContext; 039import org.apache.http.util.Args; 040 041/** 042 * Basic implementation of {@link HttpAsyncResponseProducer}. The producer 043 * can make use of the {@link HttpAsyncContentProducer} interface to 044 * efficiently stream out message content to the underlying non-blocking HTTP 045 * connection, if it is implemented by the {@link HttpEntity} inclosed in 046 * the response. 047 * 048 * @see HttpAsyncContentProducer 049 * 050 * @since 4.2 051 */ 052public class BasicAsyncResponseProducer implements HttpAsyncResponseProducer { 053 054 private final HttpResponse response; 055 private final HttpAsyncContentProducer producer; 056 057 /** 058 * Creates a producer that can be used to transmit the given response 059 * message. The given content producer will be used to stream out message 060 * content. Please note that the response message is expected to enclose 061 * an {@link HttpEntity} whose properties are consistent with the behavior 062 * of the content producer. 063 * 064 * @param response response message. 065 * @param producer response content producer. 066 */ 067 protected BasicAsyncResponseProducer( 068 final HttpResponse response, 069 final HttpAsyncContentProducer producer) { 070 super(); 071 Args.notNull(response, "HTTP response"); 072 Args.notNull(producer, "HTTP content producer"); 073 this.response = response; 074 this.producer = producer; 075 } 076 077 /** 078 * Creates a producer that can be used to transmit the given response 079 * message. If the response message encloses an {@link HttpEntity} 080 * it is also expected to implement {@link HttpAsyncContentProducer}. 081 * 082 * @param response response message. 083 */ 084 public BasicAsyncResponseProducer(final HttpResponse response) { 085 super(); 086 Args.notNull(response, "HTTP response"); 087 this.response = response; 088 final HttpEntity entity = response.getEntity(); 089 if (entity != null) { 090 if (entity instanceof HttpAsyncContentProducer) { 091 this.producer = (HttpAsyncContentProducer) entity; 092 } else { 093 this.producer = new EntityAsyncContentProducer(entity); 094 } 095 } else { 096 this.producer = null; 097 } 098 } 099 100 @Override 101 public HttpResponse generateResponse() { 102 return this.response; 103 } 104 105 @Override 106 public void produceContent( 107 final ContentEncoder encoder, final IOControl ioctrl) throws IOException { 108 if (this.producer != null) { 109 this.producer.produceContent(encoder, ioctrl); 110 if (encoder.isCompleted()) { 111 this.producer.close(); 112 } 113 } 114 } 115 116 @Override 117 public void responseCompleted(final HttpContext context) { 118 } 119 120 @Override 121 public void failed(final Exception ex) { 122 } 123 124 @Override 125 public void close() throws IOException { 126 if (this.producer != null) { 127 this.producer.close(); 128 } 129 } 130 131 @Override 132 public String toString() { 133 final StringBuilder buf = new StringBuilder(); 134 buf.append(this.response); 135 if (this.producer != null) { 136 buf.append(" ").append(this.producer); 137 } 138 return buf.toString(); 139 } 140 141}