• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2009 Mike Cumings
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.kenai.jbosh;
18 
19 import java.util.concurrent.locks.Condition;
20 import java.util.concurrent.locks.Lock;
21 import java.util.concurrent.locks.ReentrantLock;
22 import java.util.logging.Level;
23 import java.util.logging.Logger;
24 
25 /**
26  * A request and response pair representing a single exchange with a remote
27  * content manager.  This is primarily a container class intended to maintain
28  * the relationship between the request and response but allows the response
29  * to be added after the fact.
30  */
31 final class HTTPExchange {
32 
33     /**
34      * Logger.
35      */
36     private static final Logger LOG =
37             Logger.getLogger(HTTPExchange.class.getName());
38 
39     /**
40      * Request body.
41      */
42     private final AbstractBody request;
43 
44     /**
45      * Lock instance used to protect and provide conditions.
46      */
47     private final Lock lock = new ReentrantLock();
48 
49     /**
50      * Condition used to signal when the response has been set.
51      */
52     private final Condition ready = lock.newCondition();
53 
54     /**
55      * HTTPResponse instance.
56      */
57     private HTTPResponse response;
58 
59     ///////////////////////////////////////////////////////////////////////////
60     // Constructor:
61 
62     /**
63      * Create a new request/response pair object.
64      *
65      * @param req request message body
66      */
HTTPExchange(final AbstractBody req)67     HTTPExchange(final AbstractBody req) {
68         if (req == null) {
69             throw(new IllegalArgumentException("Request body cannot be null"));
70         }
71         request = req;
72     }
73 
74     ///////////////////////////////////////////////////////////////////////////
75     // Package-private methods:
76 
77     /**
78      * Get the original request message.
79      *
80      * @return request message body.
81      */
getRequest()82     AbstractBody getRequest() {
83         return request;
84     }
85 
86     /**
87      * Set the HTTPResponse instance.
88      *
89      * @return HTTPResponse instance associated with the request.
90      */
setHTTPResponse(HTTPResponse resp)91     void setHTTPResponse(HTTPResponse resp) {
92         lock.lock();
93         try {
94             if (response != null) {
95                 throw(new IllegalStateException(
96                         "HTTPResponse was already set"));
97             }
98             response = resp;
99             ready.signalAll();
100         } finally {
101             lock.unlock();
102         }
103     }
104 
105     /**
106      * Get the HTTPResponse instance.
107      *
108      * @return HTTPResponse instance associated with the request.
109      */
getHTTPResponse()110     HTTPResponse getHTTPResponse() {
111         lock.lock();
112         try {
113             while (response == null) {
114                 try {
115                     ready.await();
116                 } catch (InterruptedException intx) {
117                     LOG.log(Level.FINEST, "Interrupted", intx);
118                 }
119             }
120             return response;
121         } finally {
122             lock.unlock();
123         }
124     }
125 
126 }
127