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 */ 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