/**
  * Sends the request to CPS
  * @param CPS_Request &$request An object of the class Request
  */
 public function sendRequest(CPS_Request &$request, $json = false)
 {
     $firstSend = true;
     $previousRenderedStorage = '';
     if (isset($this->_connectionSwitcher)) {
         $this->_connectionSwitcher->newRequest($request);
     }
     do {
         $e = NULL;
         if (isset($this->_connectionSwitcher)) {
             $this->_connectionString = $this->_parseConnectionString($this->_connectionSwitcher->getConnectionString($this->_storageName));
         }
         try {
             if (strtolower($request->getCommand()) == 'begin-transaction') {
                 $this->setTransactionId(NULL);
             }
             //reset transaction id to allow failover to another hub in case of failure
             if (!is_null($this->_transactionId)) {
                 $request->setParam('transaction_id', $this->_transactionId);
             }
             if ($firstSend || $previousRenderedStorage != $this->_storageName) {
                 $requestXml = $this->_renderRequest($request);
                 $previousRenderedStorage = $this->_storageName;
                 $this->_lastRequestQuery = $requestXml;
                 if ($this->_debug) {
                     echo $this->getLastRequestQuery();
                 }
                 $this->_lastRequestSize = strlen($requestXml);
             }
             $firstSend = false;
             $this->_lastNetworkDuration = 0;
             $time_start = microtime(true);
             if ($this->_connectionString['type'] == 'socket') {
                 $ssl_options = false;
                 if (isset($this->_connectionString['ssl']) && $this->_connectionString['ssl'] == true) {
                     $ssl_options["enabled"] = true;
                     $ssl_options["ca"] = $this->_sslCustomCA;
                     $ssl_options["cn"] = $this->_sslCustomCN;
                 }
                 $rawResponse = cps2_exchange($this->_connectionString['host'], $this->_connectionString['port'], $requestXml, $this->_storageName, $this->_lastNetworkDuration, $this->_hmacUserKey, $this->_hmacSignKey, $ssl_options);
                 if ($json) {
                     // TODO: Jauzlabo JSON integracija
                     return $rawResponse;
                 }
             } else {
                 // TODO: use curl?
                 $rawResponse = cps_http_data(cps_http_post($this->_connectionString['url'], $requestXml, false, 'Recipient: ' . str_replace(array("\r", "\n"), '', $this->_storageName) . "\r\n", $this->_lastNetworkDuration, $this->_hmacUserKey, $this->_hmacSignKey));
             }
             $time_end = microtime(true);
             $this->_lastRequestDuration = $time_end - $time_start;
             $this->_lastResponseSize = strlen($rawResponse);
             $this->_lastRequestResponse = $rawResponse;
             if ($this->_debug) {
                 echo $this->getLastRequestResponse();
             }
         } catch (CPS_Exception $exception) {
             $e = $exception;
         }
         if (isset($this->_connectionSwitcher)) {
             $quit = !$this->_connectionSwitcher->shouldRetry($rawResponse, $e, $this->getTransactionId());
         } else {
             $quit = true;
         }
         if ($quit && !is_null($e)) {
             throw $e;
         }
     } while (!$quit);
     switch ($request->getCommand()) {
         case 'search':
             $ret = new CPS_SearchResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'update':
         case 'delete':
         case 'replace':
         case 'partial-replace':
         case 'partial-xreplace':
         case 'insert':
         case 'create-alert':
         case 'update-alerts':
         case 'delete-alerts':
             $ret = new CPS_ModifyResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'alternatives':
             $ret = new CPS_AlternativesResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'list-words':
             $ret = new CPS_ListWordsResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'status':
             $ret = new CPS_StatusResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'retrieve':
         case 'list-last':
         case 'list-first':
         case 'retrieve-last':
         case 'retrieve-first':
         case 'lookup':
         case 'similar':
         case 'show-history':
             $ret = new CPS_LookupResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'search-delete':
             $ret = new CPS_SearchDeleteResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'list-paths':
             $ret = new CPS_ListPathsResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'list-facets':
             $ret = new CPS_ListFacetsResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         case 'list-alerts':
             $ret = new CPS_ListAlertsResponse($this, $request, $rawResponse, $this->_noCdata);
             break;
         default:
             $ret = new CPS_Response($this, $request, $rawResponse, $this->_noCdata);
     }
     return $ret;
 }
 /**
  * Sends the request to CPS
  * @param CPS_Request &$request An object of the class Request
  */
 public function sendRequest(CPS_Request &$request)
 {
     $firstSend = true;
     $previousRenderedStorage = '';
     if (isset($this->_connectionSwitcher)) {
         $this->_connectionSwitcher->newRequest($request);
     }
     do {
         $e = NULL;
         if (isset($this->_connectionSwitcher)) {
             $this->_connectionString = $this->_parseConnectionString($this->_connectionSwitcher->getConnectionString($this->_storageName));
         }
         try {
             if (!is_null($this->_transactionId)) {
                 $request->setParam('transaction_id', $this->_transactionId);
             }
             if ($firstSend || $previousRenderedStorage != $this->_storageName) {
                 $requestXml = $this->_renderRequest($request);
                 $previousRenderedStorage = $this->_storageName;
                 if ($this->_debug) {
                     if (php_sapi_name() == 'cli') {
                         echo "Sending:\n" . $requestXml . '\\n';
                     } else {
                         echo 'Sending: <br /><pre>' . htmlspecialchars($requestXml) . '</pre>';
                     }
                 }
                 $this->_lastRequestSize = strlen($requestXml);
             }
             $firstSend = false;
             $this->_lastNetworkDuration = 0;
             $time_start = microtime(true);
             if ($this->_connectionString['type'] == 'socket') {
                 $rawResponse = cps2_exchange($this->_connectionString['host'], $this->_connectionString['port'], $requestXml, $this->_storageName, $this->_lastNetworkDuration);
             } else {
                 // TODO: use curl?
                 $rawResponse = cps_http_data(cps_http_post($this->_connectionString['url'], $requestXml, false, 'Recipient: ' . str_replace(array("\r", "\n"), '', $this->_storageName) . "\r\n", $this->_lastNetworkDuration));
             }
             $time_end = microtime(true);
             $this->_lastRequestDuration = $time_end - $time_start;
             $this->_lastResponseSize = strlen($rawResponse);
             if ($this->_debug) {
                 if (php_sapi_name() == 'cli') {
                     echo "Received:\n" . $rawResponse . '\\n';
                 } else {
                     echo 'Received: <br /><pre>' . htmlspecialchars($rawResponse) . '</pre>';
                 }
             }
         } catch (CPS_Exception $exception) {
             $e = $exception;
         }
         if (isset($this->_connectionSwitcher)) {
             $quit = !$this->_connectionSwitcher->shouldRetry($rawResponse, $e);
         } else {
             $quit = true;
         }
         if ($quit && !is_null($e)) {
             throw $e;
         }
     } while (!$quit);
     switch ($request->getCommand()) {
         case 'search':
             return new CPS_SearchResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'update':
         case 'delete':
         case 'replace':
         case 'partial-replace':
         case 'partial-xreplace':
         case 'insert':
         case 'create-alert':
         case 'update-alerts':
         case 'delete-alerts':
             return new CPS_ModifyResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'alternatives':
             return new CPS_AlternativesResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'list-words':
             return new CPS_ListWordsResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'status':
             return new CPS_StatusResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'retrieve':
         case 'list-last':
         case 'list-first':
         case 'retrieve-last':
         case 'retrieve-first':
         case 'lookup':
         case 'similar':
         case 'show-history':
             return new CPS_LookupResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'search-delete':
             return new CPS_SearchDeleteResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'list-paths':
             return new CPS_ListPathsResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'list-facets':
             return new CPS_ListFacetsResponse($this, $request, $rawResponse, $this->_noCdata);
         case 'list-alerts':
             return new CPS_ListAlertsResponse($this, $request, $rawResponse, $this->_noCdata);
         default:
             return new CPS_Response($this, $request, $rawResponse, $this->_noCdata);
     }
 }