Salesforce.com interface to directly access Salesforce.com

Dependencies:   HTTPClient-SSL MbedJSONValue

Dependents:   df-2014-salesforce-hrm-k64f

Fork of SalesforceInterface by Doug Anson

Committer:
ansond
Date:
Tue Sep 23 05:40:18 2014 +0000
Revision:
9:a254fcd904be
Parent:
8:47db53cd5884
Child:
10:845ea6d00b65
updates for create,read,update,delete methods

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:518b1ca956fc 1 /* Copyright C2014 ARM, MIT License
ansond 0:518b1ca956fc 2 *
ansond 9:a254fcd904be 3 * Author: Doug Anson (doug.anson@arm.com)
ansond 9:a254fcd904be 4 *
ansond 0:518b1ca956fc 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
ansond 0:518b1ca956fc 6 * and associated documentation files the "Software", to deal in the Software without restriction,
ansond 0:518b1ca956fc 7 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
ansond 0:518b1ca956fc 8 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
ansond 0:518b1ca956fc 9 * furnished to do so, subject to the following conditions:
ansond 0:518b1ca956fc 10 *
ansond 0:518b1ca956fc 11 * The above copyright notice and this permission notice shall be included in all copies or
ansond 0:518b1ca956fc 12 * substantial portions of the Software.
ansond 0:518b1ca956fc 13 *
ansond 0:518b1ca956fc 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
ansond 0:518b1ca956fc 15 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ansond 0:518b1ca956fc 16 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
ansond 0:518b1ca956fc 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ansond 0:518b1ca956fc 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ansond 0:518b1ca956fc 19 */
ansond 0:518b1ca956fc 20
ansond 0:518b1ca956fc 21 // Tuneables
ansond 0:518b1ca956fc 22 #define SF_OAUTH_TOKEN_URL "https://login.salesforce.com/services/oauth2/token"
ansond 0:518b1ca956fc 23 #define SF_OAUTH_REQUEST_BODY "grant_type=password&client_id=%s&client_secret=%s&username=%s&password=%s"
ansond 0:518b1ca956fc 24 #define SF_HTTP_AUTH_HEADER "Authorization: Bearer %s"
ansond 0:518b1ca956fc 25
ansond 8:47db53cd5884 26 // search tokens for URLS in salesforce ID
ansond 8:47db53cd5884 27 #define SF_URLS_START_TOKEN "\"urls\":"
ansond 8:47db53cd5884 28 #define SF_URLS_STOP_TOKEN "},"
ansond 8:47db53cd5884 29
ansond 8:47db53cd5884 30 // salesforce QUERY specifier within URL
ansond 8:47db53cd5884 31 #define SF_QUERY_URL_SPECIFIER "q="
ansond 8:47db53cd5884 32
ansond 8:47db53cd5884 33 // salesforce URL API version token
ansond 8:47db53cd5884 34 #define SF_URL_API_VER_TOKEN "{version}"
ansond 8:47db53cd5884 35
ansond 0:518b1ca956fc 36 // include class definition
ansond 0:518b1ca956fc 37 #include "SalesforceInterface.h"
ansond 0:518b1ca956fc 38
ansond 0:518b1ca956fc 39 // Supported DataTypes for HTTPClient
ansond 0:518b1ca956fc 40 #include "HTTPMap.h"
ansond 0:518b1ca956fc 41 #include "HTTPJson.h"
ansond 0:518b1ca956fc 42
ansond 0:518b1ca956fc 43 // default constructor
ansond 0:518b1ca956fc 44 SalesforceInterface::SalesforceInterface(ErrorHandler *logger,HTTPClient *http) {
ansond 0:518b1ca956fc 45 this->m_logger = logger;
ansond 0:518b1ca956fc 46 this->m_http = http;
ansond 0:518b1ca956fc 47 this->m_username = NULL;
ansond 0:518b1ca956fc 48 this->m_password = NULL;
ansond 0:518b1ca956fc 49 this->m_client_id = NULL;
ansond 0:518b1ca956fc 50 this->m_client_secret = NULL;
ansond 0:518b1ca956fc 51 this->m_have_creds = false;
ansond 7:97ea5ef906f7 52 this->m_http_status = HTTP_OK;
ansond 7:97ea5ef906f7 53 this->m_http_response_code = -1;
ansond 7:97ea5ef906f7 54 RESET_BUFFER(this->m_http_redirection_url);
ansond 8:47db53cd5884 55 memset(this->m_salesforce_api,0,SALESFORCE_API_VERSION_LENGTH);
ansond 8:47db53cd5884 56 strcpy(this->m_salesforce_api,SALESFORCE_API_VERSION);
ansond 9:a254fcd904be 57 this->resetSalesforceID();
ansond 0:518b1ca956fc 58 }
ansond 0:518b1ca956fc 59
ansond 0:518b1ca956fc 60 // destructor
ansond 0:518b1ca956fc 61 SalesforceInterface::~SalesforceInterface() {
ansond 0:518b1ca956fc 62 }
ansond 0:518b1ca956fc 63
ansond 0:518b1ca956fc 64 // set credentials
ansond 0:518b1ca956fc 65 void SalesforceInterface::setCredentials(char *username,char *password,char *client_id,char *client_secret) {
ansond 0:518b1ca956fc 66 this->m_username = NULL;
ansond 0:518b1ca956fc 67 this->m_password = NULL;
ansond 0:518b1ca956fc 68 this->m_client_id = NULL;
ansond 0:518b1ca956fc 69 this->m_client_secret = NULL;
ansond 0:518b1ca956fc 70 this->m_have_creds = false;
ansond 0:518b1ca956fc 71
ansond 0:518b1ca956fc 72 if (username != NULL) {
ansond 0:518b1ca956fc 73 this->m_username = username;
ansond 0:518b1ca956fc 74 if (password != NULL) {
ansond 0:518b1ca956fc 75 this->m_password = password;
ansond 0:518b1ca956fc 76 if (client_id != NULL) {
ansond 0:518b1ca956fc 77 this->m_client_id = client_id;
ansond 0:518b1ca956fc 78 if (client_secret != NULL) {
ansond 0:518b1ca956fc 79 this->m_client_secret = client_secret;
ansond 0:518b1ca956fc 80 this->m_have_creds = true;
ansond 0:518b1ca956fc 81 }
ansond 0:518b1ca956fc 82 }
ansond 0:518b1ca956fc 83 }
ansond 0:518b1ca956fc 84 }
ansond 0:518b1ca956fc 85 }
ansond 0:518b1ca956fc 86
ansond 0:518b1ca956fc 87 // convenience accessors
ansond 0:518b1ca956fc 88 ErrorHandler *SalesforceInterface::logger() { return this->m_logger; }
ansond 0:518b1ca956fc 89 HTTPClient *SalesforceInterface::http() { return this->m_http; }
ansond 7:97ea5ef906f7 90 OauthToken *SalesforceInterface::oauth() { return &this->m_oauth_token; }
ansond 0:518b1ca956fc 91 bool SalesforceInterface::haveCreds() { return this->m_have_creds; }
ansond 7:97ea5ef906f7 92 HTTPResult SalesforceInterface::httpStatus() { return this->m_http_status; }
ansond 7:97ea5ef906f7 93 int SalesforceInterface::httpResponseCode() { return this->m_http_response_code; }
ansond 8:47db53cd5884 94 void SalesforceInterface::setSalesforceAPIVersion(int version) { sprintf(this->m_salesforce_api,"%d",version); }
ansond 8:47db53cd5884 95 void SalesforceInterface::setSalesforceAPIVersion(char *version) { if (version != NULL && strlen(version) > 0 && strlen(version) < SALESFORCE_API_VERSION_LENGTH) strcpy(this->m_salesforce_api,version); }
ansond 8:47db53cd5884 96 char *SalesforceInterface::getSalesforceAPIVersion() { return this->m_salesforce_api; }
ansond 7:97ea5ef906f7 97
ansond 7:97ea5ef906f7 98 // reset our oauth token
ansond 7:97ea5ef906f7 99 void SalesforceInterface::resetOauthToken() {
ansond 9:a254fcd904be 100 DEBUG("resetting OAUTH token...");
ansond 7:97ea5ef906f7 101 this->m_oauth_token.valid = false;
ansond 7:97ea5ef906f7 102 this->m_oauth_token.id = "";
ansond 7:97ea5ef906f7 103 this->m_oauth_token.issued_at = "";
ansond 7:97ea5ef906f7 104 this->m_oauth_token.token_type = "";
ansond 7:97ea5ef906f7 105 this->m_oauth_token.instance_url = "";
ansond 7:97ea5ef906f7 106 this->m_oauth_token.signature = "";
ansond 7:97ea5ef906f7 107 this->m_oauth_token.access_token = "";
ansond 9:a254fcd904be 108 if (this->http() != NULL) this->http()->oauthToken(NULL);
ansond 7:97ea5ef906f7 109 }
ansond 7:97ea5ef906f7 110
ansond 7:97ea5ef906f7 111 // fill our oauth token
ansond 7:97ea5ef906f7 112 void SalesforceInterface::fillOauthToken(char *token) {
ansond 7:97ea5ef906f7 113 if (token != NULL && strlen(token) > 0) {
ansond 7:97ea5ef906f7 114 // parse JSON
ansond 7:97ea5ef906f7 115 MbedJSONValue parsed_token;
ansond 7:97ea5ef906f7 116 parse(parsed_token,token);
ansond 7:97ea5ef906f7 117
ansond 7:97ea5ef906f7 118 // fill our OAUTH token
ansond 7:97ea5ef906f7 119 this->m_oauth_token.id = parsed_token["id"].get<std::string>();
ansond 7:97ea5ef906f7 120 this->m_oauth_token.issued_at = parsed_token["issued_at"].get<std::string>();
ansond 7:97ea5ef906f7 121 this->m_oauth_token.token_type = parsed_token["token_type"].get<std::string>();
ansond 7:97ea5ef906f7 122 this->m_oauth_token.instance_url = parsed_token["instance_url"].get<std::string>();
ansond 7:97ea5ef906f7 123 this->m_oauth_token.signature = parsed_token["signature"].get<std::string>();
ansond 7:97ea5ef906f7 124 this->m_oauth_token.access_token = parsed_token["access_token"].get<std::string>();
ansond 7:97ea5ef906f7 125
ansond 7:97ea5ef906f7 126 // we have an OAUTH token now
ansond 7:97ea5ef906f7 127 this->m_oauth_token.valid = true;
ansond 7:97ea5ef906f7 128 DEBUG("valid OAUTH token acquired.");
ansond 7:97ea5ef906f7 129 return;
ansond 7:97ea5ef906f7 130 }
ansond 7:97ea5ef906f7 131 DEBUG("error: invalid or null OAUTH token fill attempt.");
ansond 7:97ea5ef906f7 132 }
ansond 7:97ea5ef906f7 133
ansond 7:97ea5ef906f7 134 // is our OAUTH token valid?
ansond 9:a254fcd904be 135 bool SalesforceInterface::validOauthToken(bool fetch) {
ansond 7:97ea5ef906f7 136 // make sure we have a valid OAUTH Token
ansond 9:a254fcd904be 137 this->checkAndGetOauthToken(fetch);
ansond 7:97ea5ef906f7 138 return this->m_oauth_token.valid;
ansond 8:47db53cd5884 139 }
ansond 9:a254fcd904be 140
ansond 9:a254fcd904be 141 // reset our salesforce ID and OAUTH tokens
ansond 9:a254fcd904be 142 void SalesforceInterface::resetSalesforceID() {
ansond 9:a254fcd904be 143 this->resetOauthToken();
ansond 9:a254fcd904be 144 RESET_BUFFER(this->m_salesforce_id);
ansond 9:a254fcd904be 145 }
ansond 8:47db53cd5884 146
ansond 8:47db53cd5884 147 // do we have a valid salesforce.com ID?
ansond 9:a254fcd904be 148 bool SalesforceInterface::haveSalesforceID(bool fetch) {
ansond 8:47db53cd5884 149 if (this->m_salesforce_id != NULL && strlen(this->m_salesforce_id) > 0) return true;
ansond 9:a254fcd904be 150 if (fetch) {
ansond 9:a254fcd904be 151 this->logger()->log("No Salesforce ID found... fetching...");
ansond 9:a254fcd904be 152 this->getSalesforceID();
ansond 9:a254fcd904be 153 return this->haveSalesforceID(false);
ansond 9:a254fcd904be 154 }
ansond 8:47db53cd5884 155 return false;
ansond 8:47db53cd5884 156 }
ansond 7:97ea5ef906f7 157
ansond 7:97ea5ef906f7 158 // check and get our OAUTH token
ansond 9:a254fcd904be 159 void SalesforceInterface::checkAndGetOauthToken(bool fetch) {
ansond 7:97ea5ef906f7 160 DEBUG("checking for valid OAUTH token...");
ansond 9:a254fcd904be 161
ansond 9:a254fcd904be 162 // reset the token structure for sanity...
ansond 9:a254fcd904be 163 if (this->m_oauth_token.valid == false) this->resetOauthToken();
ansond 9:a254fcd904be 164
ansond 9:a254fcd904be 165 // should go fetch our token if we dont have one?
ansond 9:a254fcd904be 166 // just pass through if we already have a token
ansond 9:a254fcd904be 167 if (this->m_oauth_token.valid == true) {
ansond 9:a254fcd904be 168 DEBUG("valid OAUTH token found.");
ansond 9:a254fcd904be 169 }
ansond 9:a254fcd904be 170 else if (this->m_oauth_token.valid == false && fetch == true) {
ansond 9:a254fcd904be 171 // get our OAUTH token
ansond 9:a254fcd904be 172 DEBUG("No OAUTH token found. Acquiring OAUTH token...");
ansond 7:97ea5ef906f7 173 ALLOC_BUFFER(output_buffer);
ansond 7:97ea5ef906f7 174 char *token = this->getOauthToken(output_buffer,MAX_BUFFER_LENGTH);
ansond 9:a254fcd904be 175 if (token != NULL && strlen(token) > 0) {
ansond 9:a254fcd904be 176 // fill
ansond 9:a254fcd904be 177 DEBUG("Saving OAUTH token...");
ansond 9:a254fcd904be 178 this->fillOauthToken(token);
ansond 9:a254fcd904be 179 return;
ansond 9:a254fcd904be 180 }
ansond 9:a254fcd904be 181 else {
ansond 9:a254fcd904be 182 // unable to get the token (reset for sanity)
ansond 9:a254fcd904be 183 this->logger()->log("error in acquiring OAUTH token http_code=%d status=%d",this->httpResponseCode(),this->httpStatus());
ansond 9:a254fcd904be 184 this->resetOauthToken();
ansond 9:a254fcd904be 185 }
ansond 7:97ea5ef906f7 186 }
ansond 9:a254fcd904be 187
ansond 9:a254fcd904be 188 // else report that we dont have a token
ansond 9:a254fcd904be 189 else {
ansond 9:a254fcd904be 190 this->logger()->log("No OAUTH token found (fetch=false).");
ansond 9:a254fcd904be 191 }
ansond 9:a254fcd904be 192 }
ansond 0:518b1ca956fc 193
ansond 0:518b1ca956fc 194 //
ansond 0:518b1ca956fc 195 // get OAUTH2 Token - taken from here:
ansond 0:518b1ca956fc 196 // https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com#Obtaining_a_Token_in_an_Autonomous_Client_.28Username_and_Password_Flow.29
ansond 0:518b1ca956fc 197 //
ansond 0:518b1ca956fc 198 char *SalesforceInterface::getOauthToken(char *output_buffer,int output_buffer_length) {
ansond 1:a7dca096e47d 199 if (this->haveCreds()) {
ansond 0:518b1ca956fc 200 // construct the OAUTH2 Token request body
ansond 0:518b1ca956fc 201 HTTPMap input;
ansond 0:518b1ca956fc 202
ansond 0:518b1ca956fc 203 //
ansond 0:518b1ca956fc 204 // FORMAT: Taken from URL above method signature:
ansond 0:518b1ca956fc 205 //
ansond 0:518b1ca956fc 206 // grant_type=password&client_id=<your_client_id>&client_secret=<your_client_secret>&username=<your_username>&password=<your_password>
ansond 0:518b1ca956fc 207 //
ansond 0:518b1ca956fc 208 // ContentType: application/x-www-form-urlencoded
ansond 0:518b1ca956fc 209 //
ansond 0:518b1ca956fc 210 input.put("grant_type","password");
ansond 0:518b1ca956fc 211 input.put("client_id",this->m_client_id);
ansond 0:518b1ca956fc 212 input.put("client_secret",this->m_client_secret);
ansond 0:518b1ca956fc 213 input.put("username",this->m_username);
ansond 0:518b1ca956fc 214 input.put("password",this->m_password);
ansond 1:a7dca096e47d 215
ansond 0:518b1ca956fc 216 // prepare the output buffer
ansond 0:518b1ca956fc 217 HTTPText output(output_buffer,output_buffer_length);
ansond 0:518b1ca956fc 218
ansond 0:518b1ca956fc 219 // HTTP POST call to gett he token
ansond 7:97ea5ef906f7 220 DEBUG("Getting OAUTH Token...");
ansond 7:97ea5ef906f7 221 this->m_http_status = this->http()->post(SF_OAUTH_TOKEN_URL,input,&output);
ansond 7:97ea5ef906f7 222
ansond 0:518b1ca956fc 223 // check the result and return the token
ansond 9:a254fcd904be 224 if (this->httpStatus() == HTTP_OK || this->httpResponseCode() == 200) return output_buffer;
ansond 9:a254fcd904be 225 this->logger()->log("acquire oauth FAILED. URL: %s http_code=%d status=%d",SF_OAUTH_TOKEN_URL,this->httpResponseCode(),this->httpStatus());
ansond 0:518b1ca956fc 226 }
ansond 0:518b1ca956fc 227 else {
ansond 0:518b1ca956fc 228 // no credentials
ansond 0:518b1ca956fc 229 this->logger()->log("no/incomplete salesforce.com credentials provided. Unable to acquire OAUTH2 token...");
ansond 0:518b1ca956fc 230 }
ansond 0:518b1ca956fc 231 return NULL;
ansond 0:518b1ca956fc 232 }
ansond 0:518b1ca956fc 233
ansond 7:97ea5ef906f7 234 // Salesforce.com: Get our ID
ansond 9:a254fcd904be 235 char *SalesforceInterface::getSalesforceID(bool fetch) {
ansond 7:97ea5ef906f7 236 // proceed only if we have a valid OAUTH Token
ansond 9:a254fcd904be 237 if (this->validOauthToken(fetch) == true) {
ansond 7:97ea5ef906f7 238 // pull the ID from salesforce
ansond 8:47db53cd5884 239 RESET_BUFFER(this->m_salesforce_id);
ansond 8:47db53cd5884 240 char *id = this->invoke(this->oauth()->id.c_str(),this->m_salesforce_id,MAX_BUFFER_LENGTH);
ansond 7:97ea5ef906f7 241
ansond 7:97ea5ef906f7 242 // log any error status and return what we have...
ansond 7:97ea5ef906f7 243 if (this->httpStatus() != HTTP_OK) this->logger()->log("Unable to get Salesforce ID: status=%d httpCode=%d",this->httpStatus(),this->httpResponseCode());
ansond 7:97ea5ef906f7 244 return id;
ansond 7:97ea5ef906f7 245 }
ansond 7:97ea5ef906f7 246 else {
ansond 7:97ea5ef906f7 247 // unable to get ID - no OAUTH token
ansond 7:97ea5ef906f7 248 this->logger()->log("Unable to get Salesforce ID: no valid OAUTH token.");
ansond 7:97ea5ef906f7 249 }
ansond 7:97ea5ef906f7 250 return NULL;
ansond 7:97ea5ef906f7 251 }
ansond 7:97ea5ef906f7 252
ansond 8:47db53cd5884 253 // QUERY: Salesforce.com
ansond 8:47db53cd5884 254 char *SalesforceInterface::query(char *query_str,char *output_buffer,int output_buffer_length) {
ansond 8:47db53cd5884 255 // first we have to ensure that we have valid salesforce ID
ansond 8:47db53cd5884 256 if (this->haveSalesforceID()) {
ansond 9:a254fcd904be 257 // get the query url
ansond 8:47db53cd5884 258 ALLOC_BUFFER(url);
ansond 8:47db53cd5884 259 char *sf_url = this->getSalesforceURL("query",url,MAX_BUFFER_LENGTH);
ansond 8:47db53cd5884 260 if (sf_url != NULL && strlen(sf_url) > 0) {
ansond 8:47db53cd5884 261 // make sure that the query string is ready to ship...
ansond 8:47db53cd5884 262 ALLOC_SML_BUFFER(tmp_query);
ansond 8:47db53cd5884 263
ansond 8:47db53cd5884 264 // replace all spaces in query with "+"
ansond 8:47db53cd5884 265 strcpy(tmp_query,query_str);
ansond 8:47db53cd5884 266 this->replace(tmp_query,' ','+'); // will modify tmp_query directly...
ansond 8:47db53cd5884 267
ansond 8:47db53cd5884 268 // customize the URL with our (formatted) query string
ansond 8:47db53cd5884 269 string str_url(sf_url);
ansond 8:47db53cd5884 270 str_url[str_url.length()-1] = '?'; // remove the slash and add a ?
ansond 8:47db53cd5884 271 str_url = str_url + SF_QUERY_URL_SPECIFIER + tmp_query; // add the query specifier
ansond 8:47db53cd5884 272
ansond 8:47db53cd5884 273 // DEBUG - show the query URL
ansond 8:47db53cd5884 274 DEBUG("query URL: %s",str_url.c_str());
ansond 8:47db53cd5884 275
ansond 8:47db53cd5884 276 // invoke with GET
ansond 8:47db53cd5884 277 return this->invoke((const char *)str_url.c_str(),output_buffer,output_buffer_length);
ansond 8:47db53cd5884 278 }
ansond 8:47db53cd5884 279 else {
ansond 8:47db53cd5884 280 // unable to find the query URL...
ansond 8:47db53cd5884 281 this->logger()->log("query: error - unable to find query URL in salesforce ID...");
ansond 8:47db53cd5884 282 }
ansond 8:47db53cd5884 283 }
ansond 8:47db53cd5884 284 else {
ansond 8:47db53cd5884 285 // dont have a valid salesforce ID
ansond 8:47db53cd5884 286 this->logger()->log("query: error - no valid salesforced ID was found...");
ansond 8:47db53cd5884 287 }
ansond 8:47db53cd5884 288 return NULL;
ansond 8:47db53cd5884 289 }
ansond 8:47db53cd5884 290
ansond 9:a254fcd904be 291 // CREATE: a field in Salesforce.com
ansond 9:a254fcd904be 292 MbedJSONValue SalesforceInterface::createField(char *object_name,MbedJSONValue &field) {
ansond 9:a254fcd904be 293 ALLOC_BUFFER(output_buffer);
ansond 9:a254fcd904be 294 char *reply = this->createField(object_name,(char *)field.serialize().c_str(),output_buffer,MAX_BUFFER_LENGTH);
ansond 9:a254fcd904be 295 MbedJSONValue response;
ansond 9:a254fcd904be 296 if (reply != NULL && strlen(reply) > 0) parse(response,reply);
ansond 9:a254fcd904be 297 return response;
ansond 9:a254fcd904be 298 }
ansond 9:a254fcd904be 299
ansond 9:a254fcd904be 300 // READ: a specific field in Salesforce.com
ansond 9:a254fcd904be 301 MbedJSONValue SalesforceInterface::readField(char *object_name,char *object_id) {
ansond 9:a254fcd904be 302 ALLOC_BUFFER(output_buffer);
ansond 9:a254fcd904be 303 char *reply = this->readField(object_name,object_id,output_buffer,MAX_BUFFER_LENGTH);
ansond 9:a254fcd904be 304 MbedJSONValue response;
ansond 9:a254fcd904be 305 if (reply != NULL && strlen(reply) > 0) parse(response,reply);
ansond 9:a254fcd904be 306 return response;
ansond 9:a254fcd904be 307 }
ansond 9:a254fcd904be 308
ansond 9:a254fcd904be 309 // UPDATE: a specific field in Salesforce.com
ansond 9:a254fcd904be 310 bool SalesforceInterface::updateField(char *object_name,char *object_id,MbedJSONValue &field) {
ansond 9:a254fcd904be 311 return this->updateField(object_name,object_id,(char *)field.serialize().c_str());
ansond 9:a254fcd904be 312 }
ansond 9:a254fcd904be 313
ansond 9:a254fcd904be 314 // CREATE: a field in Salesforce.com
ansond 9:a254fcd904be 315 char *SalesforceInterface::createField(char *object_name,char *json_data,char *output_buffer,int output_buffer_length) {
ansond 9:a254fcd904be 316 // parameter check
ansond 9:a254fcd904be 317 if (object_name != NULL && strlen(object_name) > 0 && json_data != NULL && strlen(json_data) > 0 && output_buffer != NULL && output_buffer_length > 0) {
ansond 9:a254fcd904be 318 // first we have to ensure that we have valid salesforce ID
ansond 9:a254fcd904be 319 if (this->haveSalesforceID()) {
ansond 9:a254fcd904be 320 // get the sobjects url
ansond 9:a254fcd904be 321 ALLOC_BUFFER(url);
ansond 9:a254fcd904be 322 char *sf_url = this->getSalesforceURL("sobjects",url,MAX_BUFFER_LENGTH);
ansond 9:a254fcd904be 323 if (sf_url != NULL && strlen(sf_url) > 0) {
ansond 9:a254fcd904be 324 // convert to string
ansond 9:a254fcd904be 325 string str_url(sf_url);
ansond 9:a254fcd904be 326
ansond 9:a254fcd904be 327 // add object name that we want to create a field in
ansond 9:a254fcd904be 328 str_url += object_name;
ansond 9:a254fcd904be 329
ansond 9:a254fcd904be 330 // DEBUG
ansond 9:a254fcd904be 331 DEBUG("createField: URL: %s DATA: %s",str_url.c_str(),json_data);
ansond 9:a254fcd904be 332
ansond 9:a254fcd904be 333 // now invoke with POST with JSON data type
ansond 9:a254fcd904be 334 return this->invoke(str_url.c_str(),json_data,strlen(json_data)+1,output_buffer,output_buffer_length);
ansond 9:a254fcd904be 335 }
ansond 9:a254fcd904be 336 }
ansond 9:a254fcd904be 337 else {
ansond 9:a254fcd904be 338 // dont have a valid salesforce ID
ansond 9:a254fcd904be 339 this->logger()->log("createField: error - no valid salesforced ID was found...");
ansond 9:a254fcd904be 340 }
ansond 9:a254fcd904be 341 }
ansond 9:a254fcd904be 342 else {
ansond 9:a254fcd904be 343 // invalid or NULL parameters
ansond 9:a254fcd904be 344 this->logger()->log("createField: error - invalid or NULL parameters...");
ansond 9:a254fcd904be 345 }
ansond 9:a254fcd904be 346 return NULL;
ansond 9:a254fcd904be 347 }
ansond 9:a254fcd904be 348
ansond 9:a254fcd904be 349 // READ: a specific field in Salesforce.com
ansond 9:a254fcd904be 350 char *SalesforceInterface::readField(char *object_name,char *object_id,char *output_buffer,int output_buffer_length) {
ansond 9:a254fcd904be 351 // parameter check
ansond 9:a254fcd904be 352 if (object_name != NULL && strlen(object_name) > 0 && object_id != NULL && strlen(object_id) > 0 && output_buffer != NULL && output_buffer_length > 0) {
ansond 9:a254fcd904be 353 // first we have to ensure that we have valid salesforce ID
ansond 9:a254fcd904be 354 if (this->haveSalesforceID()) {
ansond 9:a254fcd904be 355 // get the sobjects url
ansond 9:a254fcd904be 356 ALLOC_BUFFER(url);
ansond 9:a254fcd904be 357 char *sf_url = this->getSalesforceURL("sobjects",url,MAX_BUFFER_LENGTH);
ansond 9:a254fcd904be 358 if (sf_url != NULL && strlen(sf_url) > 0) {
ansond 9:a254fcd904be 359 // convert to string
ansond 9:a254fcd904be 360 string str_url(sf_url);
ansond 9:a254fcd904be 361
ansond 9:a254fcd904be 362 // add object name that we want to create a field in
ansond 9:a254fcd904be 363 str_url += object_name;
ansond 9:a254fcd904be 364
ansond 9:a254fcd904be 365 // add the field ID
ansond 9:a254fcd904be 366 str_url += "/";
ansond 9:a254fcd904be 367 str_url += object_id;
ansond 9:a254fcd904be 368
ansond 9:a254fcd904be 369 // DEBUG
ansond 9:a254fcd904be 370 DEBUG("readField: URL: %s",str_url.c_str());
ansond 9:a254fcd904be 371
ansond 9:a254fcd904be 372 // now invoke with GET with JSON data type
ansond 9:a254fcd904be 373 return this->invoke(str_url.c_str(),output_buffer,output_buffer_length);
ansond 9:a254fcd904be 374 }
ansond 9:a254fcd904be 375 }
ansond 9:a254fcd904be 376 else {
ansond 9:a254fcd904be 377 // dont have a valid salesforce ID
ansond 9:a254fcd904be 378 this->logger()->log("readField: error - no valid salesforced ID was found...");
ansond 9:a254fcd904be 379 }
ansond 9:a254fcd904be 380 }
ansond 9:a254fcd904be 381 else {
ansond 9:a254fcd904be 382 // invalid or NULL parameters
ansond 9:a254fcd904be 383 this->logger()->log("readField: error - invalid or NULL parameters...");
ansond 9:a254fcd904be 384 }
ansond 9:a254fcd904be 385 return NULL;
ansond 9:a254fcd904be 386 }
ansond 9:a254fcd904be 387
ansond 9:a254fcd904be 388 // UPDATE: a specific field in Salesforce.com
ansond 9:a254fcd904be 389 bool SalesforceInterface::updateField(char *object_name,char *object_id,char *json_data) {
ansond 9:a254fcd904be 390 // parameter check
ansond 9:a254fcd904be 391 if (object_name != NULL && strlen(object_name) > 0 && json_data != NULL && strlen(json_data) > 0) {
ansond 9:a254fcd904be 392 // first we have to ensure that we have valid salesforce ID
ansond 9:a254fcd904be 393 if (this->haveSalesforceID()) {
ansond 9:a254fcd904be 394 // get the sobjects url
ansond 9:a254fcd904be 395 ALLOC_BUFFER(url);
ansond 9:a254fcd904be 396 char *sf_url = this->getSalesforceURL("sobjects",url,MAX_BUFFER_LENGTH);
ansond 9:a254fcd904be 397 if (sf_url != NULL && strlen(sf_url) > 0) {
ansond 9:a254fcd904be 398 // convert to string
ansond 9:a254fcd904be 399 string str_url(sf_url);
ansond 9:a254fcd904be 400
ansond 9:a254fcd904be 401 // add object name that we want to create a field in
ansond 9:a254fcd904be 402 str_url += object_name;
ansond 9:a254fcd904be 403
ansond 9:a254fcd904be 404 // add the field ID
ansond 9:a254fcd904be 405 str_url += "/";
ansond 9:a254fcd904be 406 str_url += object_id;
ansond 9:a254fcd904be 407
ansond 9:a254fcd904be 408 // HTTPClient does not support PATCH, so we have to use POST with a special added parameter
ansond 9:a254fcd904be 409 str_url += "?_HttpMethod=PATCH";
ansond 9:a254fcd904be 410
ansond 9:a254fcd904be 411 // DEBUG
ansond 9:a254fcd904be 412 DEBUG("updateField: URL: %s DATA: %s",str_url.c_str(),json_data);
ansond 9:a254fcd904be 413
ansond 9:a254fcd904be 414 // now invoke with POST with JSON data type
ansond 9:a254fcd904be 415 ALLOC_SML_BUFFER(output_buffer);
ansond 9:a254fcd904be 416 char *reply = this->invoke(str_url.c_str(),json_data,strlen(json_data)+1,output_buffer,MAX_SMALL_BUFFER_LENGTH);
ansond 9:a254fcd904be 417
ansond 9:a254fcd904be 418 // DEBUG
ansond 9:a254fcd904be 419 DEBUG("updateField: http status=%d",this->httpResponseCode());
ansond 9:a254fcd904be 420
ansond 9:a254fcd904be 421 // return our status
ansond 9:a254fcd904be 422 if (this->httpResponseCode() == 204) return true;
ansond 9:a254fcd904be 423 return false;
ansond 9:a254fcd904be 424 }
ansond 9:a254fcd904be 425 }
ansond 9:a254fcd904be 426 else {
ansond 9:a254fcd904be 427 // dont have a valid salesforce ID
ansond 9:a254fcd904be 428 this->logger()->log("updateField: error - no valid salesforced ID was found...");
ansond 9:a254fcd904be 429 }
ansond 9:a254fcd904be 430 }
ansond 9:a254fcd904be 431 else {
ansond 9:a254fcd904be 432 // invalid or NULL parameters
ansond 9:a254fcd904be 433 this->logger()->log("updateField: error - invalid or NULL parameters...");
ansond 9:a254fcd904be 434 }
ansond 9:a254fcd904be 435 return false;
ansond 9:a254fcd904be 436 }
ansond 9:a254fcd904be 437
ansond 9:a254fcd904be 438 // DELETE: a specific field in Salesforce.com
ansond 9:a254fcd904be 439 bool SalesforceInterface::deleteField(char *object_name,char *object_id) {
ansond 9:a254fcd904be 440 // parameter check
ansond 9:a254fcd904be 441 if (object_name != NULL && strlen(object_name) > 0 && object_id != NULL && strlen(object_id) > 0) {
ansond 9:a254fcd904be 442 // first we have to ensure that we have valid salesforce ID
ansond 9:a254fcd904be 443 if (this->haveSalesforceID()) {
ansond 9:a254fcd904be 444 // get the sobjects url
ansond 9:a254fcd904be 445 ALLOC_BUFFER(url);
ansond 9:a254fcd904be 446 char *sf_url = this->getSalesforceURL("sobjects",url,MAX_BUFFER_LENGTH);
ansond 9:a254fcd904be 447 if (sf_url != NULL && strlen(sf_url) > 0) {
ansond 9:a254fcd904be 448 // convert to string
ansond 9:a254fcd904be 449 string str_url(sf_url);
ansond 9:a254fcd904be 450
ansond 9:a254fcd904be 451 // add object name that we want to create a field in
ansond 9:a254fcd904be 452 str_url += object_name;
ansond 9:a254fcd904be 453
ansond 9:a254fcd904be 454 // add the field ID
ansond 9:a254fcd904be 455 str_url += "/";
ansond 9:a254fcd904be 456 str_url += object_id;
ansond 9:a254fcd904be 457
ansond 9:a254fcd904be 458 // DEBUG
ansond 9:a254fcd904be 459 DEBUG("deleteField: URL: %s",str_url.c_str());
ansond 9:a254fcd904be 460
ansond 9:a254fcd904be 461 // now invoke with DELETE
ansond 9:a254fcd904be 462 ALLOC_SML_BUFFER(output_buffer);
ansond 9:a254fcd904be 463 char *reply = this->invoke(str_url.c_str(),output_buffer,MAX_SMALL_BUFFER_LENGTH,DELETE);
ansond 9:a254fcd904be 464
ansond 9:a254fcd904be 465 // DEBUG
ansond 9:a254fcd904be 466 DEBUG("deleteField: http status=%d",this->httpResponseCode());
ansond 9:a254fcd904be 467
ansond 9:a254fcd904be 468 // return our status
ansond 9:a254fcd904be 469 if (this->httpResponseCode() == 204) return true;
ansond 9:a254fcd904be 470 return false;
ansond 9:a254fcd904be 471 }
ansond 9:a254fcd904be 472 }
ansond 9:a254fcd904be 473 else {
ansond 9:a254fcd904be 474 // dont have a valid salesforce ID
ansond 9:a254fcd904be 475 this->logger()->log("deleteField: error - no valid salesforced ID was found...");
ansond 9:a254fcd904be 476 }
ansond 9:a254fcd904be 477 }
ansond 9:a254fcd904be 478 else {
ansond 9:a254fcd904be 479 // invalid or NULL parameters
ansond 9:a254fcd904be 480 this->logger()->log("deleteField: error - invalid or NULL parameters...");
ansond 9:a254fcd904be 481 }
ansond 9:a254fcd904be 482 return false;
ansond 9:a254fcd904be 483 }
ansond 9:a254fcd904be 484
ansond 0:518b1ca956fc 485 // Salesforce.com Invoke: defaults to GET
ansond 9:a254fcd904be 486 char *SalesforceInterface::invoke(const char *url,char *output_buffer,int output_buffer_length) {
ansond 9:a254fcd904be 487 return this->invoke(url,output_buffer,output_buffer_length,GET);
ansond 9:a254fcd904be 488 }
ansond 9:a254fcd904be 489
ansond 9:a254fcd904be 490 // Salesforce.com Invoke: GET or DELETE with simple output
ansond 9:a254fcd904be 491 char *SalesforceInterface::invoke(const char *url,char *output_buffer,int output_buffer_length,HttpVerb verb) {
ansond 9:a254fcd904be 492 char *response = NULL;
ansond 9:a254fcd904be 493 switch(verb) {
ansond 9:a254fcd904be 494 case GET:
ansond 9:a254fcd904be 495 case DELETE:
ansond 9:a254fcd904be 496 // GET and DELETE only require an output buffer...
ansond 9:a254fcd904be 497 response = this->invoke(url,NUM_TYPES,NULL,0,output_buffer,output_buffer_length,verb);
ansond 9:a254fcd904be 498 break;
ansond 9:a254fcd904be 499 default:
ansond 9:a254fcd904be 500 // wrong verb for this call interface...
ansond 9:a254fcd904be 501 this->logger()->log("invoke: invalid call: must be either GET or DELETE verb if only output buffer is provided");
ansond 9:a254fcd904be 502 break;
ansond 9:a254fcd904be 503 }
ansond 9:a254fcd904be 504 return response;
ansond 0:518b1ca956fc 505 }
ansond 0:518b1ca956fc 506
ansond 0:518b1ca956fc 507 // Salesforce.com Invoke: defaults to POST with JSON input data type
ansond 9:a254fcd904be 508 char *SalesforceInterface::invoke(const char *url,const char *input_data,const int input_data_len,char *output_buffer,int output_buffer_length) {
ansond 9:a254fcd904be 509 return this->invoke(url,JSON,input_data,input_data_len,output_buffer,output_buffer_length);
ansond 0:518b1ca956fc 510 }
ansond 0:518b1ca956fc 511
ansond 0:518b1ca956fc 512 // Salesforce.com Invoke: defaults to POST with variable input data type
ansond 9:a254fcd904be 513 char *SalesforceInterface::invoke(const char *url,const InputDataTypes input_type,const char *input_data,const int input_data_len,char *output_buffer,int output_buffer_length) {
ansond 9:a254fcd904be 514 return this->invoke(url,input_type,input_data,input_data_len,output_buffer,output_buffer_length,POST);
ansond 0:518b1ca956fc 515 }
ansond 0:518b1ca956fc 516
ansond 0:518b1ca956fc 517 // Salesforce.com Invoke: full fidelity method
ansond 9:a254fcd904be 518 char *SalesforceInterface::invoke(const char *url,const InputDataTypes input_type,const char *input_data,const int input_data_len,char *output_buffer,int output_buffer_length,const HttpVerb verb) {
ansond 7:97ea5ef906f7 519 // initialize our invocation status and response code
ansond 7:97ea5ef906f7 520 this->m_http_response_code = -1;
ansond 7:97ea5ef906f7 521 this->m_http_status = HTTP_ERROR;
ansond 7:97ea5ef906f7 522
ansond 7:97ea5ef906f7 523 // param check: make sure that we at least have an output buffer and URL
ansond 9:a254fcd904be 524 if (url != NULL && strlen(url) > 0 && output_buffer != NULL && output_buffer_length > 0) {
ansond 7:97ea5ef906f7 525 // proceed only if we have a valid OAUTH Token
ansond 7:97ea5ef906f7 526 if (this->validOauthToken() == true) {
ansond 7:97ea5ef906f7 527 // use OAUTH headers
ansond 7:97ea5ef906f7 528 this->http()->oauthToken(this->oauth()->access_token.c_str());
ansond 0:518b1ca956fc 529
ansond 7:97ea5ef906f7 530 // reset the redirection url buffer in case we get a redirect...
ansond 7:97ea5ef906f7 531 RESET_BUFFER(this->m_http_redirection_url);
ansond 7:97ea5ef906f7 532 this->http()->setLocationBuf((char *)this->m_http_redirection_url,MAX_BUFFER_LENGTH);
ansond 7:97ea5ef906f7 533
ansond 0:518b1ca956fc 534 // create our output/response buffer
ansond 9:a254fcd904be 535 HTTPText output(output_buffer,output_buffer_length);
ansond 0:518b1ca956fc 536
ansond 0:518b1ca956fc 537 // now make the HTTP(S) request
ansond 0:518b1ca956fc 538 switch(verb) {
ansond 0:518b1ca956fc 539 case GET:
ansond 9:a254fcd904be 540 DEBUG("invoke (GET) URL: %s...",url);
ansond 7:97ea5ef906f7 541 this->m_http_status = this->http()->get(url,&output);
ansond 7:97ea5ef906f7 542 this->m_http_response_code = this->http()->getHTTPResponseCode();
ansond 0:518b1ca956fc 543 break;
ansond 0:518b1ca956fc 544 case DELETE:
ansond 9:a254fcd904be 545 DEBUG("invoke (DEL) URL: %s...",url);
ansond 7:97ea5ef906f7 546 this->m_http_status = this->http()->del(url,&output);
ansond 7:97ea5ef906f7 547 this->m_http_response_code = this->http()->getHTTPResponseCode();
ansond 0:518b1ca956fc 548 break;
ansond 0:518b1ca956fc 549 case POST:
ansond 0:518b1ca956fc 550 if (input_data != NULL && input_data_len > 0) {
ansond 0:518b1ca956fc 551 if (input_type == JSON) {
ansond 9:a254fcd904be 552 DEBUG("invoke (POST-JSON) URL: %s...",url);
ansond 7:97ea5ef906f7 553 HTTPJson input_json((char *)input_data,(int)input_data_len);
ansond 7:97ea5ef906f7 554 this->m_http_status = this->http()->post(url,input_json,&output);
ansond 7:97ea5ef906f7 555 this->m_http_response_code = this->http()->getHTTPResponseCode();
ansond 0:518b1ca956fc 556 }
ansond 0:518b1ca956fc 557 else {
ansond 9:a254fcd904be 558 DEBUG("invoke (POST-TEXT) URL: %s...",url);
ansond 7:97ea5ef906f7 559 HTTPText input_text((char *)input_data,(int)input_data_len);
ansond 7:97ea5ef906f7 560 this->m_http_status = this->http()->post(url,input_text,&output);
ansond 7:97ea5ef906f7 561 this->m_http_response_code = this->http()->getHTTPResponseCode();
ansond 0:518b1ca956fc 562 }
ansond 0:518b1ca956fc 563 }
ansond 0:518b1ca956fc 564 else {
ansond 0:518b1ca956fc 565 // no input buffer!
ansond 0:518b1ca956fc 566 this->logger()->log("invoke: ERROR HTTP(POST) requested but no input data provided... returning NULL");
ansond 0:518b1ca956fc 567 }
ansond 0:518b1ca956fc 568 break;
ansond 0:518b1ca956fc 569 case PUT:
ansond 0:518b1ca956fc 570 if (input_data != NULL && input_data_len > 0) {
ansond 0:518b1ca956fc 571 if (input_type == JSON) {
ansond 9:a254fcd904be 572 DEBUG("invoke (PUT-JSON) URL: %s...",url);
ansond 7:97ea5ef906f7 573 HTTPJson input_json((char *)input_data,(int)input_data_len);
ansond 7:97ea5ef906f7 574 this->m_http_status = this->http()->put(url,input_json,&output);
ansond 7:97ea5ef906f7 575 this->m_http_response_code = this->http()->getHTTPResponseCode();
ansond 0:518b1ca956fc 576 }
ansond 0:518b1ca956fc 577 else {
ansond 9:a254fcd904be 578 DEBUG("invoke (PUT-TEXT) URL: %s...",url);
ansond 7:97ea5ef906f7 579 HTTPText input_text((char *)input_data,(int)input_data_len);
ansond 7:97ea5ef906f7 580 this->m_http_status = this->http()->put(url,input_text,&output);
ansond 7:97ea5ef906f7 581 this->m_http_response_code = this->http()->getHTTPResponseCode();
ansond 0:518b1ca956fc 582 }
ansond 0:518b1ca956fc 583 }
ansond 0:518b1ca956fc 584 else {
ansond 0:518b1ca956fc 585 // no input buffer!
ansond 0:518b1ca956fc 586 this->logger()->log("invoke: ERROR HTTP(PUT) requested but no input data provided... returning NULL");
ansond 0:518b1ca956fc 587 }
ansond 0:518b1ca956fc 588 break;
ansond 0:518b1ca956fc 589 default:
ansond 0:518b1ca956fc 590 // invalid HTTP verb
ansond 0:518b1ca956fc 591 this->logger()->log("invoke: ERROR invalid HTTP verb (%d) provided... returning NULL",verb);
ansond 0:518b1ca956fc 592 break;
ansond 0:518b1ca956fc 593 }
ansond 0:518b1ca956fc 594 }
ansond 7:97ea5ef906f7 595 else {
ansond 7:97ea5ef906f7 596 // no OAUTH Token
ansond 7:97ea5ef906f7 597 this->logger()->log("unable to acquire OAUTH token for credentials provided. Unable to invoke API...");
ansond 7:97ea5ef906f7 598 }
ansond 0:518b1ca956fc 599 }
ansond 0:518b1ca956fc 600 else {
ansond 0:518b1ca956fc 601 // no credentials
ansond 0:518b1ca956fc 602 this->logger()->log("no/incomplete salesforce.com credentials provided. Unable to invoke API...");
ansond 0:518b1ca956fc 603 }
ansond 0:518b1ca956fc 604
ansond 7:97ea5ef906f7 605 // process any return results that we have
ansond 7:97ea5ef906f7 606 if (this->httpStatus() == HTTP_OK || this->httpStatus() == HTTP_REDIRECT) {
ansond 7:97ea5ef906f7 607 // do we have any redirections?
ansond 7:97ea5ef906f7 608 if (this->httpResponseCode() == 302 /* REDIRECT */ && strlen(this->m_http_redirection_url) > 0) {
ansond 7:97ea5ef906f7 609 // we have a redirect - so reset the output buffer
ansond 9:a254fcd904be 610 memset(output_buffer,0,output_buffer_length);
ansond 7:97ea5ef906f7 611
ansond 7:97ea5ef906f7 612 // we have to make a copy of the redirection URL - this is because the subsequent invoke() will wipe our current one clean
ansond 7:97ea5ef906f7 613 ALLOC_BUFFER(redirect_url);
ansond 7:97ea5ef906f7 614 strcpy(redirect_url,this->m_http_redirection_url);
ansond 7:97ea5ef906f7 615
ansond 7:97ea5ef906f7 616 // repeat with the redirection URL
ansond 7:97ea5ef906f7 617 DEBUG("invoke: redirecting to: %s",redirect_url);
ansond 9:a254fcd904be 618 return this->invoke((const char *)redirect_url,input_type,input_data,input_data_len,output_buffer,output_buffer_length,verb);
ansond 7:97ea5ef906f7 619 }
ansond 7:97ea5ef906f7 620 else if (this->httpResponseCode() == 302 /* REDIRECT */) {
ansond 7:97ea5ef906f7 621 // error - got a redirect but have no URL
ansond 7:97ea5ef906f7 622 this->logger()->log("invoke error: received redirect but no URL...");
ansond 7:97ea5ef906f7 623 this->m_http_status = HTTP_ERROR;
ansond 7:97ea5ef906f7 624 }
ansond 7:97ea5ef906f7 625 }
ansond 7:97ea5ef906f7 626
ansond 0:518b1ca956fc 627 // return the response in the output buffer
ansond 9:a254fcd904be 628 if (this->httpStatus() == HTTP_OK || this->httpStatus() == HTTP_REDIRECT) return output_buffer;
ansond 7:97ea5ef906f7 629 else this->logger()->log("invocation failed with HTTP error code=%d status=%d",this->httpResponseCode(),this->httpStatus());
ansond 0:518b1ca956fc 630 return NULL;
ansond 0:518b1ca956fc 631 }
ansond 8:47db53cd5884 632
ansond 8:47db53cd5884 633 // find the specific URL in our salesforce ID
ansond 8:47db53cd5884 634 char *SalesforceInterface::getSalesforceURL(char *key,char *url_buffer,int url_buffer_length) {
ansond 8:47db53cd5884 635 // due to MbedJSONValue limitations - we have to manually pull out the specific JSON from our salesforce ID
ansond 8:47db53cd5884 636 int start = (int)strstr(this->m_salesforce_id,SF_URLS_START_TOKEN);
ansond 8:47db53cd5884 637 if (start >= 0) {
ansond 8:47db53cd5884 638 start += strlen(SF_URLS_START_TOKEN);
ansond 8:47db53cd5884 639 int stop = (int)strstr((char *)start,SF_URLS_STOP_TOKEN);
ansond 8:47db53cd5884 640 if (stop >= 0 && stop > start) {
ansond 8:47db53cd5884 641 // calculate the length
ansond 8:47db53cd5884 642 int length = stop - start + 1;
ansond 8:47db53cd5884 643
ansond 8:47db53cd5884 644 // copy over the "urls" json from the salesforce ID
ansond 8:47db53cd5884 645 ALLOC_BUFFER(urls);
ansond 8:47db53cd5884 646 int start_index = (start - (int)this->m_salesforce_id);
ansond 8:47db53cd5884 647 for(int i=0;i<length;++i) urls[i] = this->m_salesforce_id[start_index+i];
ansond 8:47db53cd5884 648
ansond 8:47db53cd5884 649 // use MbedJSONValue to parse the "urls" json
ansond 8:47db53cd5884 650 MbedJSONValue parsed_urls;
ansond 8:47db53cd5884 651 parse(parsed_urls,urls);
ansond 8:47db53cd5884 652
ansond 8:47db53cd5884 653 // find the appropriate URL and copy it
ansond 8:47db53cd5884 654 string target_url = parsed_urls[key].get<std::string>();
ansond 8:47db53cd5884 655
ansond 8:47db53cd5884 656 // replace the version of the string with our selected salesforce API version
ansond 8:47db53cd5884 657 string sf_version(this->getSalesforceAPIVersion());
ansond 8:47db53cd5884 658 string version_tag(SF_URL_API_VER_TOKEN);
ansond 8:47db53cd5884 659 this->replace(target_url,version_tag,sf_version);
ansond 8:47db53cd5884 660
ansond 8:47db53cd5884 661 // copy the final URL to our putput
ansond 8:47db53cd5884 662 memset(url_buffer,0,url_buffer_length);
ansond 8:47db53cd5884 663 strcpy(url_buffer,target_url.c_str());
ansond 8:47db53cd5884 664
ansond 8:47db53cd5884 665 // return the URL
ansond 8:47db53cd5884 666 return url_buffer;
ansond 8:47db53cd5884 667 }
ansond 8:47db53cd5884 668 }
ansond 8:47db53cd5884 669 return NULL;
ansond 8:47db53cd5884 670 }
ansond 8:47db53cd5884 671
ansond 8:47db53cd5884 672 // simple char array replacement (modifies input string!)
ansond 8:47db53cd5884 673 void SalesforceInterface::replace(char *str,char orig_char,char new_char) {
ansond 8:47db53cd5884 674 int length = strlen(str);
ansond 8:47db53cd5884 675 for(int i=0;i<length;++i) if (str[i] == orig_char) str[i] = new_char;
ansond 8:47db53cd5884 676 }
ansond 8:47db53cd5884 677
ansond 8:47db53cd5884 678 //
ansond 8:47db53cd5884 679 // substring replacement
ansond 8:47db53cd5884 680 // Credit: http://stackoverflow.com/questions/4643512/replace-substring-with-another-substring-c
ansond 8:47db53cd5884 681 //
ansond 8:47db53cd5884 682 void SalesforceInterface::replace(string& line, string& oldString, string& newString) {
ansond 8:47db53cd5884 683 const size_t oldSize = oldString.length();
ansond 8:47db53cd5884 684
ansond 8:47db53cd5884 685 // do nothing if line is shorter than the string to find
ansond 8:47db53cd5884 686 if( oldSize > line.length() ) return;
ansond 8:47db53cd5884 687
ansond 8:47db53cd5884 688 const size_t newSize = newString.length();
ansond 8:47db53cd5884 689 for( size_t pos = 0; ; pos += newSize ) {
ansond 8:47db53cd5884 690
ansond 8:47db53cd5884 691 // Locate the substring to replace
ansond 8:47db53cd5884 692 pos = line.find( oldString, pos );
ansond 8:47db53cd5884 693 if( pos == string::npos ) return;
ansond 8:47db53cd5884 694 if( oldSize == newSize ) {
ansond 8:47db53cd5884 695
ansond 8:47db53cd5884 696 // if they're same size, use std::string::replace
ansond 8:47db53cd5884 697 line.replace( pos, oldSize, newString );
ansond 8:47db53cd5884 698 }
ansond 8:47db53cd5884 699 else {
ansond 8:47db53cd5884 700
ansond 8:47db53cd5884 701 // if not same size, replace by erasing and inserting
ansond 8:47db53cd5884 702 line.erase( pos, oldSize );
ansond 8:47db53cd5884 703 line.insert( pos, newString );
ansond 8:47db53cd5884 704 }
ansond 8:47db53cd5884 705 }
ansond 9:a254fcd904be 706 }