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.http.nio.protocol;
29
30 import java.io.IOException;
31
32 import org.apache.http.HttpEntity;
33 import org.apache.http.HttpResponse;
34 import org.apache.http.annotation.ThreadSafe;
35 import org.apache.http.nio.ContentEncoder;
36 import org.apache.http.nio.IOControl;
37 import org.apache.http.nio.entity.EntityAsyncContentProducer;
38 import org.apache.http.nio.entity.HttpAsyncContentProducer;
39 import org.apache.http.protocol.HttpContext;
40
41 /**
42 * Basic implementation of {@link HttpAsyncResponseProducer}. The producer
43 * can make use of the {@link HttpAsyncContentProducer} interface to
44 * efficiently stream out message content to the underlying non-blocking HTTP
45 * connection, if it is implemented by the {@link HttpEntity} inclosed in
46 * the response.
47 *
48 * @see HttpAsyncContentProducer
49 *
50 * @since 4.2
51 */
52 @ThreadSafe
53 public class BasicAsyncResponseProducer implements HttpAsyncResponseProducer {
54
55 private final HttpResponse response;
56 private final HttpAsyncContentProducer producer;
57
58 /**
59 * Creates a producer that can be used to transmit the given response
60 * message. The given content producer will be used to stream out message
61 * content. Please note that the response message is expected to enclose
62 * an {@link HttpEntity} whose properties are consistent with the behavior
63 * of the content producer.
64 *
65 * @param response response message.
66 * @param producer response content producer.
67 */
68 protected BasicAsyncResponseProducer(
69 final HttpResponse response,
70 final HttpAsyncContentProducer producer) {
71 super();
72 if (response == null) {
73 throw new IllegalArgumentException("HTTP response may not be null");
74 }
75 if (producer == null) {
76 throw new IllegalArgumentException("HTTP content producer may not be null");
77 }
78 this.response = response;
79 this.producer = producer;
80 }
81
82 /**
83 * Creates a producer that can be used to transmit the given response
84 * message. If the response message encloses an {@link HttpEntity}
85 * it is also expected to implement {@link HttpAsyncContentProducer}.
86 *
87 * @param response response message.
88 */
89 public BasicAsyncResponseProducer(final HttpResponse response) {
90 super();
91 if (response == null) {
92 throw new IllegalArgumentException("HTTP response may not be null");
93 }
94 this.response = response;
95 HttpEntity entity = response.getEntity();
96 if (entity != null) {
97 if (entity instanceof HttpAsyncContentProducer) {
98 this.producer = (HttpAsyncContentProducer) entity;
99 } else {
100 this.producer = new EntityAsyncContentProducer(entity);
101 }
102 } else {
103 this.producer = null;
104 }
105 }
106
107 public synchronized HttpResponse generateResponse() {
108 return this.response;
109 }
110
111 public synchronized void produceContent(
112 final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
113 if (this.producer != null) {
114 this.producer.produceContent(encoder, ioctrl);
115 if (encoder.isCompleted()) {
116 this.producer.close();
117 }
118 }
119 }
120
121 public void responseCompleted(final HttpContext context) {
122 }
123
124 public void failed(final Exception ex) {
125 }
126
127 public synchronized void close() throws IOException {
128 if (this.producer != null) {
129 this.producer.close();
130 }
131 }
132
133 }