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