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