HTTPExchange.java revision d7955ce24d294fb2014c59d11fca184471056f44
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
17package com.kenai.jbosh;
18
19import java.util.concurrent.locks.Condition;
20import java.util.concurrent.locks.Lock;
21import java.util.concurrent.locks.ReentrantLock;
22import java.util.logging.Level;
23import 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 */
31final 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     */
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     */
82    AbstractBody getRequest() {
83        return request;
84    }
85
86    /**
87     * Set the HTTPResponse instance.
88     *
89     * @return HTTPResponse instance associated with the request.
90     */
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     */
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