1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.reqres;
21
22 import java.util.NoSuchElementException;
23 import java.util.concurrent.BlockingQueue;
24 import java.util.concurrent.LinkedBlockingQueue;
25 import java.util.concurrent.ScheduledFuture;
26 import java.util.concurrent.TimeUnit;
27
28
29
30
31
32 public class Request {
33 private final Object id;
34
35 private final Object message;
36
37 private final long timeoutMillis;
38
39 private volatile Runnable timeoutTask;
40
41 private volatile ScheduledFuture<?> timeoutFuture;
42
43 private final BlockingQueue<Object> responses;
44
45 private volatile boolean endOfResponses;
46
47 public Request(Object id, Object message, long timeoutMillis) {
48 this(id, message, true, timeoutMillis);
49 }
50
51 public Request(Object id, Object message, boolean useResponseQueue,
52 long timeoutMillis) {
53 this(id, message, useResponseQueue, timeoutMillis,
54 TimeUnit.MILLISECONDS);
55 }
56
57 public Request(Object id, Object message, long timeout, TimeUnit unit) {
58 this(id, message, true, timeout, unit);
59 }
60
61 public Request(Object id, Object message, boolean useResponseQueue,
62 long timeout, TimeUnit unit) {
63 if (id == null) {
64 throw new NullPointerException("id");
65 }
66 if (message == null) {
67 throw new NullPointerException("message");
68 }
69 if (timeout < 0) {
70 throw new IllegalArgumentException("timeout: " + timeout
71 + " (expected: 0+)");
72 } else if (timeout == 0) {
73 timeout = Long.MAX_VALUE;
74 }
75
76 if (unit == null) {
77 throw new NullPointerException("unit");
78 }
79
80 this.id = id;
81 this.message = message;
82 this.responses = useResponseQueue ? new LinkedBlockingQueue<Object>() : null;
83 this.timeoutMillis = unit.toMillis(timeout);
84 }
85
86 public Object getId() {
87 return id;
88 }
89
90 public Object getMessage() {
91 return message;
92 }
93
94 public long getTimeoutMillis() {
95 return timeoutMillis;
96 }
97
98 public boolean isUseResponseQueue() {
99 return responses != null;
100 }
101
102 public boolean hasResponse() {
103 checkUseResponseQueue();
104 return !responses.isEmpty();
105 }
106
107 public Response awaitResponse() throws RequestTimeoutException,
108 InterruptedException {
109 checkUseResponseQueue();
110 chechEndOfResponses();
111 return convertToResponse(responses.take());
112 }
113
114 public Response awaitResponse(long timeout, TimeUnit unit)
115 throws RequestTimeoutException, InterruptedException {
116 checkUseResponseQueue();
117 chechEndOfResponses();
118 return convertToResponse(responses.poll(timeout, unit));
119 }
120
121 private Response convertToResponse(Object o) {
122 if (o instanceof Response) {
123 return (Response) o;
124 }
125
126 if (o == null) {
127 return null;
128 }
129
130 throw (RequestTimeoutException) o;
131 }
132
133 public Response awaitResponseUninterruptibly()
134 throws RequestTimeoutException {
135 for (; ;) {
136 try {
137 return awaitResponse();
138 } catch (InterruptedException e) {
139 }
140 }
141 }
142
143 private void chechEndOfResponses() {
144 if (responses != null && endOfResponses && responses.isEmpty()) {
145 throw new NoSuchElementException(
146 "All responses has been retrieved already.");
147 }
148 }
149
150 private void checkUseResponseQueue() {
151 if (responses == null) {
152 throw new UnsupportedOperationException(
153 "Response queue is not available; useResponseQueue is false.");
154 }
155 }
156
157 void signal(Response response) {
158 signal0(response);
159 if (response.getType() != ResponseType.PARTIAL) {
160 endOfResponses = true;
161 }
162 }
163
164 void signal(RequestTimeoutException e) {
165 signal0(e);
166 endOfResponses = true;
167 }
168
169 private void signal0(Object answer) {
170 if (responses != null) {
171 responses.add(answer);
172 }
173 }
174
175 @Override
176 public int hashCode() {
177 return getId().hashCode();
178 }
179
180 @Override
181 public boolean equals(Object o) {
182 if (o == this) {
183 return true;
184 }
185
186 if (o == null) {
187 return false;
188 }
189
190 if (!(o instanceof Request)) {
191 return false;
192 }
193
194 Request that = (Request) o;
195 return this.getId().equals(that.getId());
196 }
197
198 @Override
199 public String toString() {
200 String timeout = getTimeoutMillis() == Long.MAX_VALUE ? "max"
201 : String.valueOf(getTimeoutMillis());
202
203 return "request: { id=" + getId() + ", timeout=" + timeout
204 + ", message=" + getMessage() + " }";
205 }
206
207 Runnable getTimeoutTask() {
208 return timeoutTask;
209 }
210
211 void setTimeoutTask(Runnable timeoutTask) {
212 this.timeoutTask = timeoutTask;
213 }
214
215 ScheduledFuture<?> getTimeoutFuture() {
216 return timeoutFuture;
217 }
218
219 void setTimeoutFuture(ScheduledFuture<?> timeoutFuture) {
220 this.timeoutFuture = timeoutFuture;
221 }
222 }