// Path: src/main/java/org/springframework/social/salesforce/api/ApiOperations.java
// public interface ApiOperations {
// 
//     static final String DEFAULT_API_VERSION = "v37.0";
//     
//     List<ApiVersion> getVersions();
// 
//     Map<String, String> getServices(String version);
//     
//     Map<String, String> getServices();
//     
//     void setVersion(String version)
//             throws InvalidSalesforceApiVersionException;
//     
//     String getVersion();
// }
// 
// Path: src/main/java/org/springframework/social/salesforce/api/ApiVersion.java
// public class ApiVersion implements Serializable {
// 
//     private String label;
// 
//     private String version;
// 
//     private String url;
// 
// 
//     public ApiVersion(String version, String label, String url) {
//         this.version = version;
//         this.label = label;
//         this.url = url;
//     }
// 
// 
//     public String getLabel() {
//         return label;
//     }
// 
//     public String getVersion() {
//         return version;
//     }
// 
//     public String getUrl() {
//         return url;
//     }
// 
//     @Override
//     public String toString() {
//         return "ApiVersion{" +
//                 "label='" + label + '\'' +
//                 ", version='" + version + '\'' +
//                 ", url='" + url + '\'' +
//                 '}';
//     }
// 
// }
// 
// Path: src/main/java/org/springframework/social/salesforce/api/InvalidSalesforceApiVersionException.java
// public class InvalidSalesforceApiVersionException 
//         extends Throwable
// {
//     public InvalidSalesforceApiVersionException()
//     {
//         //NOOP
//     }
//     
//     public InvalidSalesforceApiVersionException(String version)
//     {
//         super(version + " is not a valid Salesforce Api version.");
//     }
// }
// 
// Path: src/main/java/org/springframework/social/salesforce/api/Salesforce.java
// public interface Salesforce extends ApiBinding {
// 
//     public ApiOperations apiOperations();
// 
//     public ApiOperations apiOperations(String instanceUrl);
// 
//     public ChatterOperations chatterOperations();
// 
//     public ChatterOperations chatterOperations(String instanceUrl);
// 
//     public QueryOperations queryOperations();
// 
//     public QueryOperations queryOperations(String instanceUrl);
// 
//     public RecentOperations recentOperations();
// 
//     public RecentOperations recentOperations(String instanceUrl);
// 
//     public SearchOperations searchOperations();
// 
//     public SearchOperations searchOperations(String instanceUrl);
// 
//     public SObjectOperations sObjectsOperations();
// 
//     public SObjectOperations sObjectsOperations(String instanceUrl);
// 
//     public UserOperations userOperations();
// 
//     public UserOperations userOperations(String gatewayUrl);
// 
//     public LimitsOperations limitsOperations();
// 
//     public LimitsOperations limitsOperations(String instanceUrl);
// 
//     public <T> List<T> readList(JsonNode jsonNode, Class<T> type);
// 
//     public <T> T readObject(JsonNode jsonNode, Class<T> type);
// 
//     public String getBaseUrl();
// 
//     public String getInstanceUrl();
// 
//     public void setInstanceUrl(String instanceUrl);
// 
//     public String getUserInfoUrl();
// 
//     public String getAuthGatewayUrl();
// 
//     public void setAuthGatewayBaseUrl(String gatewayUrl);
// 
//     public ConnectOperations connectOperations();
// 
//     public ConnectOperations connectOperations(String instanceUrl);
//     
//     public CustomApiOperations customApiOperations();
// 
//     public CustomApiOperations customApiOperations(String instanceUrl);
// }


import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.social.salesforce.api.ApiOperations;
import org.springframework.social.salesforce.api.ApiVersion;
import org.springframework.social.salesforce.api.InvalidSalesforceApiVersionException;
import org.springframework.social.salesforce.api.Salesforce;
import org.springframework.social.support.URIBuilder;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Copyright (C) 2017 https://github.com/jottley/spring-social-salesforce
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.social.salesforce.api.impl;




/**
 * Default implementation of ApiOperations.
 *
 * @author Umut Utkan
 * @author Jared Ottley
 */
public class ApiTemplate extends AbstractSalesForceOperations<Salesforce> implements ApiOperations {

    private RestTemplate restTemplate;
    private String version;
    
    
    String versionRegEx = "v[0-9][0-9]\\.[0-9]";


    public ApiTemplate(Salesforce api, RestTemplate restTemplate) {
        super(api);
        this.restTemplate = restTemplate;
    }


    public List<ApiVersion> getVersions() {
        URI uri = URIBuilder.fromUri(api.getBaseUrl()).build();
        JsonNode dataNode = restTemplate.getForObject(uri, JsonNode.class);
        return api.readList(dataNode, ApiVersion.class);
    }

    @SuppressWarnings("unchecked")
    public Map<String, String> getServices(String version) {
        requireAuthorization();
        return restTemplate.getForObject(api.getBaseUrl() + "/{version}", Map.class, version);
    }
    
    
    @SuppressWarnings("unchecked")
    public Map<String, String> getServices() {
        requireAuthorization();
        return this.getServices(getVersion());
    }
    
    
    public void setVersion(String version)
// Path: src/main/java/org/springframework/social/salesforce/api/ApiOperations.java
// public interface ApiOperations {
// 
//     static final String DEFAULT_API_VERSION = "v37.0";
//     
//     List<ApiVersion> getVersions();
// 
//     Map<String, String> getServices(String version);
//     
//     Map<String, String> getServices();
//     
//     void setVersion(String version)
//             throws InvalidSalesforceApiVersionException;
//     
//     String getVersion();
// }
// 
// Path: src/main/java/org/springframework/social/salesforce/api/ApiVersion.java
// public class ApiVersion implements Serializable {
// 
//     private String label;
// 
//     private String version;
// 
//     private String url;
// 
// 
//     public ApiVersion(String version, String label, String url) {
//         this.version = version;
//         this.label = label;
//         this.url = url;
//     }
// 
// 
//     public String getLabel() {
//         return label;
//     }
// 
//     public String getVersion() {
//         return version;
//     }
// 
//     public String getUrl() {
//         return url;
//     }
// 
//     @Override
//     public String toString() {
//         return "ApiVersion{" +
//                 "label='" + label + '\'' +
//                 ", version='" + version + '\'' +
//                 ", url='" + url + '\'' +
//                 '}';
//     }
// 
// }
// 
// Path: src/main/java/org/springframework/social/salesforce/api/InvalidSalesforceApiVersionException.java
// public class InvalidSalesforceApiVersionException 
//         extends Throwable
// {
//     public InvalidSalesforceApiVersionException()
//     {
//         //NOOP
//     }
//     
//     public InvalidSalesforceApiVersionException(String version)
//     {
//         super(version + " is not a valid Salesforce Api version.");
//     }
// }
// 
// Path: src/main/java/org/springframework/social/salesforce/api/Salesforce.java
// public interface Salesforce extends ApiBinding {
// 
//     public ApiOperations apiOperations();
// 
//     public ApiOperations apiOperations(String instanceUrl);
// 
//     public ChatterOperations chatterOperations();
// 
//     public ChatterOperations chatterOperations(String instanceUrl);
// 
//     public QueryOperations queryOperations();
// 
//     public QueryOperations queryOperations(String instanceUrl);
// 
//     public RecentOperations recentOperations();
// 
//     public RecentOperations recentOperations(String instanceUrl);
// 
//     public SearchOperations searchOperations();
// 
//     public SearchOperations searchOperations(String instanceUrl);
// 
//     public SObjectOperations sObjectsOperations();
// 
//     public SObjectOperations sObjectsOperations(String instanceUrl);
// 
//     public UserOperations userOperations();
// 
//     public UserOperations userOperations(String gatewayUrl);
// 
//     public LimitsOperations limitsOperations();
// 
//     public LimitsOperations limitsOperations(String instanceUrl);
// 
//     public <T> List<T> readList(JsonNode jsonNode, Class<T> type);
// 
//     public <T> T readObject(JsonNode jsonNode, Class<T> type);
// 
//     public String getBaseUrl();
// 
//     public String getInstanceUrl();
// 
//     public void setInstanceUrl(String instanceUrl);
// 
//     public String getUserInfoUrl();
// 
//     public String getAuthGatewayUrl();
// 
//     public void setAuthGatewayBaseUrl(String gatewayUrl);
// 
//     public ConnectOperations connectOperations();
// 
//     public ConnectOperations connectOperations(String instanceUrl);
//     
//     public CustomApiOperations customApiOperations();
// 
//     public CustomApiOperations customApiOperations(String instanceUrl);
// }


// Path: src/main/java/org/springframework/social/salesforce/api/impl/ApiTemplate.java
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.social.salesforce.api.ApiOperations;
import org.springframework.social.salesforce.api.ApiVersion;
import org.springframework.social.salesforce.api.InvalidSalesforceApiVersionException;
import org.springframework.social.salesforce.api.Salesforce;
import org.springframework.social.support.URIBuilder;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Copyright (C) 2017 https://github.com/jottley/spring-social-salesforce
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.social.salesforce.api.impl;




/**
 * Default implementation of ApiOperations.
 *
 * @author Umut Utkan
 * @author Jared Ottley
 */
public class ApiTemplate extends AbstractSalesForceOperations<Salesforce> implements ApiOperations {

    private RestTemplate restTemplate;
    private String version;
    
    
    String versionRegEx = "v[0-9][0-9]\\.[0-9]";


    public ApiTemplate(Salesforce api, RestTemplate restTemplate) {
        super(api);
        this.restTemplate = restTemplate;
    }


    public List<ApiVersion> getVersions() {
        URI uri = URIBuilder.fromUri(api.getBaseUrl()).build();
        JsonNode dataNode = restTemplate.getForObject(uri, JsonNode.class);
        return api.readList(dataNode, ApiVersion.class);
    }

    @SuppressWarnings("unchecked")
    public Map<String, String> getServices(String version) {
        requireAuthorization();
        return restTemplate.getForObject(api.getBaseUrl() + "/{version}", Map.class, version);
    }
    
    
    @SuppressWarnings("unchecked")
    public Map<String, String> getServices() {
        requireAuthorization();
        return this.getServices(getVersion());
    }
    
    
    public void setVersion(String version)
            throws InvalidSalesforceApiVersionException