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