/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */
package org.kurento.jsonrpc.internal.client;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.kurento.jsonrpc.JsonRpcException;
import org.kurento.jsonrpc.client.Continuation;
import org.kurento.jsonrpc.client.JsonRpcClient;
import org.kurento.jsonrpc.internal.JsonRpcRequestSender;
import org.kurento.jsonrpc.message.Request;
import org.kurento.jsonrpc.message.Response;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class ClientSession extends AbstractSession {

	private final JsonRpcRequestSender requestSender;
	private volatile ConcurrentMap<String, Object> attributes;

	public ClientSession(String sessionId, Object registerInfo,
			JsonRpcRequestSender jsonRpcRequestSender) {
		super(sessionId, registerInfo);
		this.requestSender = jsonRpcRequestSender;
	}

	@Override
	public void close() throws IOException {
		if (requestSender instanceof JsonRpcClient) {
			((JsonRpcClient) requestSender).close();
		}
	}

	@Override
	public <R> R sendRequest(String method, Class<R> resultClass)
			throws IOException {
		return requestSender.sendRequest(method, resultClass);
	}

	@Override
	public <R> R sendRequest(String method, Object params, Class<R> resultClass)
			throws IOException {
		return requestSender.sendRequest(method, params, resultClass);
	}

	@Override
	public JsonElement sendRequest(String method) throws IOException {
		return requestSender.sendRequest(method);
	}

	@Override
	public JsonElement sendRequest(String method, Object params)
			throws IOException {
		return requestSender.sendRequest(method, params);
	}

	@Override
	public void sendNotification(String method, Object params)
			throws IOException {
		requestSender.sendNotification(method, params);
	}

	@Override
	public void sendNotification(String method) throws IOException {
		requestSender.sendNotification(method);
	}

	@Override
	public void sendRequest(String method, JsonObject params,
			Continuation<JsonElement> continuation) {
		requestSender.sendRequest(method, params, continuation);
	}

	@Override
	public void sendNotification(String method, Object params,
			Continuation<JsonElement> continuation) throws IOException {
		requestSender.sendNotification(method, params, continuation);
	}
	
	public Response<JsonElement> sendRequest(Request<JsonObject> request)
			throws IOException {
		return requestSender.sendRequest(request);
	}

	public void sendRequest(Request<JsonObject> request,
			Continuation<Response<JsonElement>> continuation)
			throws IOException {
		requestSender.sendRequest(request, continuation);
	}
	
	public void sendRequestHonorId(Request<JsonObject> request,
			Continuation<Response<JsonElement>> continuation)
			throws IOException {
		requestSender.sendRequestHonorId(request, continuation);
	}
	
	@Override
	public Response<JsonElement> sendRequestHonorId(Request<JsonObject> request)
			throws IOException {
		return requestSender.sendRequestHonorId(request);
	}

	@Override
	public void setReconnectionTimeout(long millis) {
		throw new JsonRpcException(
				"Reconnection timeout can't be configured in the client");
	}

	@Override
	public Map<String, Object> getAttributes() {
		if (attributes == null) {
			synchronized (this) {
				if (attributes == null) {
					attributes = new ConcurrentHashMap<>();
				}
			}
		}

		return attributes;
	}
}

@@ -1200,14 +1200,8 @@
 ate 
-final 
 Json
@@ -1481,24 +1481,235 @@
 Sender;%0A%09%7D%0A%0A
+%09public ClientSession(String sessionId, Object registerInfo) %7B%0A%09%09super(sessionId, registerInfo);%0A%09%7D%0A%0A%09public void setRequestSender(JsonRpcRequestSender requestSender) %7B%0A%09%09this.requestSender = requestSender;%0A%09%7D%0A%0A
 %09@Override%0A%09
@@ -3114,34 +3114,33 @@
 ntinuation);%0A%09%7D%0A
-%09
 %0A
+
 %09public Response
@@ -3366,32 +3366,34 @@
 %3E continuation)%0A
+%09%09
 %09%09%09throws IOExce
@@ -3392,32 +3392,32 @@
 s IOException %7B%0A
-
 %09%09requestSender.
@@ -3455,18 +3455,17 @@
 on);%0A%09%7D%0A
-%09
 %0A
+
 %09public 
@@ -3570,16 +3570,18 @@
 uation)%0A
+%09%09
 %09%09%09throw
@@ -3588,32 +3588,32 @@
 s IOException %7B%0A
-
 %09%09requestSender.
@@ -3658,17 +3658,16 @@
 on);%0A%09%7D%0A
-%09
 %0A%09@Overr

Add new constructor in ClientSession