Package com.force.sdk.connector

Source Code of com.force.sdk.connector.ForceServiceConnector

/**
* Copyright (c) 2011, salesforce.com, inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
*    Redistributions of source code must retain the above copyright notice, this list of conditions and the
*    following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*    the following disclaimer in the documentation and/or other materials provided with the distribution.
*
*    Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
*    promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

package com.force.sdk.connector;

import static com.force.sdk.connector.ForceConnectorUtils.LOGGER;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.SocketAddress;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

import com.force.sdk.connector.threadlocal.ForceThreadLocalStore;
import com.sforce.async.AsyncApiException;
import com.sforce.async.BulkConnection;
import com.sforce.soap.metadata.DescribeMetadataResult;
import com.sforce.soap.metadata.MetadataConnection;
import com.sforce.soap.partner.CallOptions_element;
import com.sforce.soap.partner.Connector;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.SessionHeader_element;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;
import com.sforce.ws.SessionRenewer;

/**
* A connector to the Force.com service.
* <p>
* This connector will manage and provide connections to the Force.com service. It can
* provide the following connection types:
* <p>
* <ul>
*   <li>PartnerConnection - Used for SOAP API calls</li>
*   <li>MetadataConnection - Used for the Force.com Metadata API</li>
*   <li>BulkConnection - Used for the Force.com Bulk API</li>
* </ul>
* Connectors require a {@link ForceConnectorConfig} to provide connection
* properties.  They can handle {@code ForceConnectorConfig}s from the following
* sources (Note that sources will be checked in this order):
* <p>
* <ol>
*   <li>An injected {@code ForceConnectorConfig}</li>
*   <li>A named source (see {@link ForceConnectorUtils#loadConnectorPropsFromName(String)})</li>
*   <li>A {@code ForceConnectorConfig} stored in the connector's {@code ThreadLocal} cache</li>
* </ol>
* Connectors are capable of caching {@code ForceConnectorConfig} objects both in a {@code ThreadLocalCache}
* and an in-memory cache.  The {@code ThreadLocalCache} is directly controlled by the caller.  The in-memory
* cache is controlled internally by the connector.  By default, a connector will cache a {@code ForceConnectorConfig}
* in memory whenever it constructs a connection.  However, this can be turned off by the caller.
* <p>
* A {@code ForceServiceConnector} provides several additional features beyond the traditional
* Force.com API {@code Connector}.  Namely:
* <p>
* <ul>
*   <li>
*   Force.com connection endpoint building with automatic version binding
*   (see {@link ForceConnectorConfig#setAuthEndpoint(String)} and {@link ForceConnectorUtils#buildForceApiEndpoint(String)})
*   </li>
*   <li>Automatic session renewal</li>
*   <li>Convenient setting of Force.com connection client identifiers (clientId)</li>
* </ul>
*
* @author Tim Kral
* @author Fiaz Hossain
*/
public class ForceServiceConnector implements ForceConnector, SessionRenewer {

    /**
     * The qualified name for session SOAP requests.
     */
    public static final javax.xml.namespace.QName SESSION_HEADER_QNAME =
        new javax.xml.namespace.QName("urn:partner.soap.sforce.com", "SessionHeader");
   
    // This is used to create a Metadata API uri (i.e. */services/Soap/u/* -> */services/Soap/m/*)
    private static final Pattern METADATA_URI_PATTERN = Pattern.compile("(.*/Soap)/./(.*)");
   
    // This is used to create a Bulk (REST) API uri (i.e. */services/Soap/u/*/<orgId> -> */services/async/*)
    // The Bulk API was the first "REST API", hence the var name. This is different from the REST API, which came later.
    private static final Pattern RESTAPI_URI_PATTERN = Pattern.compile("(.*)/Soap/./(.*)/(.*)$");
   
    // Version under which we will get Metadata describe results
    static final double DESCRIBE_METADATA_VERSION = 16.0;
   
    private static final Proxy DEFAULT_PROXY;

    /**
     * The version of the sdk e.g. sdk-22.0.1-BETA that will be set in the User-Agent header for API requests
     */
    public static final String API_USER_AGENT;

    static {
        if (PROXY_HOST != null) {
            SocketAddress addr = new InetSocketAddress(PROXY_HOST, PROXY_PORT);
            DEFAULT_PROXY = new Proxy(Proxy.Type.HTTP, addr);
        } else {
            DEFAULT_PROXY = null;
        }

        String sdkVersion = null;
        Properties projectProps = new Properties();
        try {
            projectProps.load(ForceServiceConnector.class.getClassLoader().getResource("sdk.properties").openStream());
            sdkVersion = projectProps.getProperty("force.sdk.version");
        } catch (IOException e) {
            LOGGER.error("Unable to load project properties. Logs will not include sdk version!");
        }
        if (sdkVersion == null) sdkVersion = "";
        API_USER_AGENT = String.format("sdk-%s", sdkVersion);
    }
   
    /**
     * Retrieves the {@code ForceConnectorConfig} found in the
     * {@code ForceServiceConnector} {@code ThreadLocal} cache.
     *
     * @return the {@code ForceConnectorConfig} from the {@code ThreadLocal};
     *         {@code null} if no such {@code ForceConnectorConfig} exists
     */
    public static ForceConnectorConfig getThreadLocalConnectorConfig() {
        return ForceThreadLocalStore.getConnectorConfig();
    }

    /**
     * Sets the {@code ForceConnectorConfig} in the {@code ForceServiceConnector}
     * {@code ThreadLocal}.
     *
     * @param config the {@code ForceConnectorConfig} to be set in the {@code ThreadLocal}
     */
    public static void setThreadLocalConnectorConfig(ForceConnectorConfig config) {
        ForceThreadLocalStore.setConnectorConfig(config);
    }
   
    // Cache for saved configs
    private static final Map<String, ForceConnectorConfig> CACHED_CONFIGS =
        new ConcurrentHashMap<String, ForceConnectorConfig>();
    // map a connection name to a config id
    private static final Map<String, String> CONN_NAME_TO_CACHED_CONFIGS = new ConcurrentHashMap<String, String>();
    private boolean skipCache = false; // Flag which tells us whether to check the config cache or not
   
    // The ForceConnectorConfig used to construct a connection
    private ForceConnectorConfig config;
   
    // State that can be used to construct config
    private String connectionName;               // Named connections can look up connection construction state       
    private ForceConnectorConfig externalConfig; // ForceConnectorConfig injected from an external source

    // Extra state used to initialize config (and the connection)
    private String clientId;
    private String externalClientId; // A clientId coming from an external source (see getConfig)

    private int timeout;
   
    // Saved connection state for multiple getConnection calls
    private PartnerConnection connection;
    private MetadataConnection metadataConnection;
    private BulkConnection bulkConnection;
   
    /**
     * Initializes a {@code ForceServiceConnector} with no {@code ForceConnectorConfig} source.
     * <p>
     * If using this constructor, the caller must provider a {@code ForceConnetorConfig} source
     * via setters before getting a Force.com connection.
     *
     * @see ForceServiceConnector#setConnectorConfig(ForceConnectorConfig)
     * @see ForceServiceConnector#setConnectionName(String)
     * @see ForceServiceConnector#setThreadLocalConnectorConfig(ForceConnectorConfig)
     */
    public ForceServiceConnector() {  }
   
    /**
     * Initializes a {@code ForceServiceConnector} with a named {@code ForceConnectorConfig} source .
     *
     * @param connectionName the named {@code ForceConnectorConfig} source from which a valid {@code ForceConnectorConfig}
     *                       can be constructed and used to get Force.com connections
     * @see ForceConnectorUtils#loadConnectorPropsFromName(String)
     */
    // Constructor that will retrieve saved connection construction state
    public ForceServiceConnector(String connectionName) {
        this.connectionName = connectionName;
    }

    /**
     * Initializes a {@code ForceServiceConnector} that uses the given {@code ForceConnectorConfig}
     * to get Force.com connections.
     *
     * @param config the {@code ForceConnectorConfig} to be used when getting Force.com connections
     * @throws IllegalArgumentException if the given {@code ForceConnectorConfig} is {@code null}
     * @throws ConnectionException if the given {@code ForceConnectorConfig} is incomplete (i.e.
     *                             cannot be used to get a Force.com connection)
     */
    public ForceServiceConnector(ForceConnectorConfig config) throws ConnectionException {
        if (config == null) {
            throw new IllegalArgumentException("Cannot construct ForceServiceConnector with null ConnectorConfig.");
        }
       
        // Fail early if the ConnectorConfig is not valid
        validateConnectorConfig(config);
        this.externalConfig = config;
    }
   
    /**
     * Returns a Force.com API {@code PartnerConnection}.
     * <p>
     * This connection type can be use to make SOAP API calls to the Force.com
     * service.  The {@code PartnerConnection} will be lazily constructed and
     * stored in this {@code ForceServiceConnector}'s state.  This state
     * can be cleared with a call to {@code close}
     *
     * @return a Force.com API {@code PartnerConnection} from the {@code ForceConnectorConfig}
     *         state found in this {@code ForceServiceConnector}
     * @throws ConnectionException if the {@code ForceConnectorConfig} state cannot be found
     *                             or otherwise constructed
     * @throws ConnectionException if this {@code ForceServiceConnector} cannot get a connection
     *                             to the Force.com service with its {@code ForceConnectorConfig} state
     * @see ForceServiceConnector#renewSession(ConnectorConfig)
     * @see ForceServiceConnector#close
     */
    public PartnerConnection getConnection() throws ConnectionException {
        if (this.connection == null) {
            initConnection();
        }
       
        return this.connection;
    }

    private void initConnection() throws ConnectionException {
        if (config == null) {
            config = getConfig();
            initConfig();
        }

        config.setRequestHeader("User-Agent", API_USER_AGENT);
        this.connection = Connector.newConnection(config);

        CallOptions_element co = new CallOptions_element();
       
        // Give the connection a client id if we have one
        if (this.clientId != null) {
            co.setClient(this.clientId);
        } else if (this.externalClientId != null) {
            // Check for any external client id we might
            // have come across (see getConfig)
            co.setClient(this.externalClientId);
        } else {
            co.setClient(API_USER_AGENT); //just default it to the version of the sdk
        }

        this.connection.__setCallOptions(co);
    }
   
    // Constructs and returns config.
    private ForceConnectorConfig getConfig() throws ConnectionException {
       
        // First, look for construction state in this object's state.
        if (externalConfig != null) {
             // Save the client id for possible later use (see initConnection)
            externalClientId = externalConfig.getClientId();
            // Clone the config in case it gets cached.  This will prevent
            // the caller from modifying the cached object.
            return checkConfigCache((ForceConnectorConfig) externalConfig.clone());
        }
       
        // Next, try to retrieve saved connection construction state using the connection name
        if (connectionName != null) {
            final ForceConnectorConfig cachedConfig = getCachedConfig(getCacheIdForConnectionName(connectionName));
            if (cachedConfig != null) {
                return cachedConfig;
            }

            ForceConnectorConfig loadedConfig;
            try {
                loadedConfig = ForceConnectorConfig.loadFromName(connectionName);
            } catch (IOException e) {
                throw new ConnectionException("Unable to load ForceConnectorConfig for name " + connectionName, e);
            }
           
            if (loadedConfig != null) {
                // Save the client id for possible later use (see initConnection)
                externalClientId = loadedConfig.getClientId();
                return checkConfigCache(loadedConfig, connectionName);
            }
        }
       
        // Finally, try to get config from ThreadLocal
        if ((config = ForceThreadLocalStore.getConnectorConfig()) != null) return config;
       
        // Out of options.  There's not enough here to construct config.
        StringBuffer errorMsg = new StringBuffer();
        errorMsg.append("No state was found to construct a connection.")
                .append(" Please provide a ForceConnectorConfig.");
       
        if (connectionName != null) {
            errorMsg.append(" Or create a classpath properties file, environment variable or java property for the name '")
                    .append(connectionName).append("'");
        }

        throw new ConnectionException(errorMsg.toString());
    }

    private String getCacheIdForConnectionName(String cachedConnectionName) {
        return CONN_NAME_TO_CACHED_CONFIGS.get(cachedConnectionName);
    }

    private void setCacheIdForConnectionName(String cacheConnectionName, String cacheId) {
        if (cacheConnectionName != null && cacheId != null) {
            LOGGER.trace("ForceServiceConnector Cache: Mapping connectionName: "
                    + cacheConnectionName + " to cacheId: " + cacheId);
            CONN_NAME_TO_CACHED_CONFIGS.put(cacheConnectionName, cacheId);
        }
    }

    private ForceConnectorConfig checkConfigCache(ForceConnectorConfig configToCheck) throws ConnectionException {
        return checkConfigCache(configToCheck, null);
    }

    private ForceConnectorConfig checkConfigCache(ForceConnectorConfig configToCheck, String cachedConnectionName)
            throws ConnectionException {
        validateConnectorConfig(configToCheck);

        String cacheId = configToCheck.getCacheId();
        if (cacheId != null && !skipCache) {
            LOGGER.trace("ForceServiceConnector Cache: Checking for id: " + cacheId);
           
            ForceConnectorConfig cachedConfig = getCachedConfig(cacheId);
            setCacheIdForConnectionName(cachedConnectionName, cacheId);
            if (cachedConfig  != null) {
                LOGGER.trace("ForceServiceConnector Cache: HIT for id: " + cacheId);
                return cachedConfig;
            }

            LOGGER.trace("ForceServiceConnector Cache: MISS for id: " + cacheId);
            CACHED_CONFIGS.put(cacheId, configToCheck);
        }
       
        return configToCheck;
    }

    private void validateConnectorConfig(ForceConnectorConfig configToValidate) throws ConnectionException {
        if (configToValidate.getSessionId() == null && configToValidate.getAuthEndpoint() == null) {
            throw new ConnectionException("ForceConnectorConfig must have an AuthEndpoint");
        }
       
        if (configToValidate.getSessionId() == null && configToValidate.getUsername() == null) {
            throw new ConnectionException("ForceConnectorConfig must have a Username");
        }
    }

    // Initiates config.  We assume that config is non-null.
    private void initConfig() {
        if (config.getSessionRenewer() == null) {
            config.setSessionRenewer(this);
        }
       
        // Add proxy information to config
        if (DEFAULT_PROXY != null && (config.getProxy() != Proxy.NO_PROXY || config.getProxy().type() == Type.DIRECT)) {
            config.setProxy(DEFAULT_PROXY);
        }
       
        // Transfer any extra state we have to config
        if (this.timeout > 0) config.setReadTimeout(this.timeout);
    }

    /**
     * Returns a Force.com API {@code MetadataConnection}.
     * <p>
     * This connection type can be use to make Force.com Metadata API calls.
     * The {@code MetadataConnection} will be lazily constructed and
     * stored in this {@code ForceServiceConnector}'s state.  This state
     * can be cleared with a call to {@code close}
     *
     * @return a Force.com API {@code MetadataConnection} from the {@code ForceConnectorConfig}
     *         state found in this {@code ForceServiceConnector}
     * @throws ConnectionException if the {@code ForceConnectorConfig} state cannot be found
     *                             or otherwise constructed
     * @throws ConnectionException if this {@code ForceServiceConnector} cannot get a connection
     *                             to the Force.com service with its {@code ForceConnectorConfig} state
     * @see ForceServiceConnector#renewSession(ConnectorConfig)
     * @see ForceServiceConnector#close
     */
    public MetadataConnection getMetadataConnection() throws ConnectionException {
        if (this.metadataConnection == null) {
            initMetadataConnection();
        }
        return this.metadataConnection;
    }

    private void initMetadataConnection() throws ConnectionException {
        if (this.connection == null) {
            initConnection();
        }
       
        ConnectorConfig configNew = new ConnectorConfig();
        configNew.setSessionId(config.getSessionId());
        configNew.setServiceEndpoint(METADATA_URI_PATTERN.matcher(config.getServiceEndpoint()).replaceFirst("$1/m/$2"));

        this.metadataConnection = new MetadataConnection(configNew);

        // Give the metadata connection a client id if we have one
        if (this.clientId != null) {
            this.metadataConnection.setCallOptions(this.clientId);
        } else if (this.externalClientId != null) {
            // If we've constructed config from ForceServiceConnectionInfo state
            // then we've saved any client id for use here (see getConfig)
            this.metadataConnection.setCallOptions(this.externalClientId);
        } else {
            this.metadataConnection.setCallOptions(API_USER_AGENT); //just default to sdk version
        }
        this.metadataConnection.getConfig().setRequestHeader("User-Agent", API_USER_AGENT);
    }

    /**
     * Returns a Force.com Bulk API {@code BulkConnection}.
     * <p>
     * This connection type can be use to make Force.com Bulk API calls.
     * The {@code BulkConnection} will be lazily constructed and
     * stored in this {@code ForceServiceConnector}'s state.  This state
     * can be cleared with a call to {@code close}
     *
     * @return a Force.com API {@code BulkConnection} from the {@code ForceConnectorConfig}
     *         state found in this {@code ForceServiceConnector}
     * @throws ConnectionException if the {@code ForceConnectorConfig} state cannot be found
     *                             or otherwise constructed
     * @throws ConnectionException if this {@code ForceServiceConnector} cannot get a connection
     *                             to the Force.com service with its {@code ForceConnectorConfig} state
     * @throws AsyncApiException if this {@code ForceServiceConnector} cannot load a {@code BulkConnection}
     *                           to the Force.com service with its {@code ForceConnectorConfig} state
     * @see ForceServiceConnector#renewSession(ConnectorConfig)
     * @see ForceServiceConnector#close
     */
    public BulkConnection getBulkConnection() throws ConnectionException, AsyncApiException {
        if (this.bulkConnection == null) {
            initBulkConnection();
        }
        return this.bulkConnection;
    }

    private void initBulkConnection() throws ConnectionException, AsyncApiException {
        if (this.connection == null) {
            initConnection();
        }
       
        ConnectorConfig configNew = new ConnectorConfig();
        configNew.setSessionId(config.getSessionId());
        configNew.setServiceEndpoint(config.getServiceEndpoint());
        configNew.setRestEndpoint(RESTAPI_URI_PATTERN.matcher(config.getServiceEndpoint()).replaceFirst("$1/async/$2/"));
        this.bulkConnection = new BulkConnection(configNew);
    }

    /**
     * Returns the namespace of the Force.com store to which this {@code ForceServiceConnector}
     * is getting a connection.
     * <p>
     * A namespace uniquely identifies a Force.com store on the Force.com service.  This {@code ForceServiceConnector}
     * will retrieve the namespace by getting a Force.com connection with its {@code ForceConnectorConfig} state.
     *
     * @return the unique Force.com store namespace; {@code null} is no such namespace exists
     * @throws ConnectionException if the {@code ForceConnectorConfig} state cannot be found
     *                             or otherwise constructed
     * @throws ConnectionException if this {@code ForceServiceConnector} cannot get a connection
     *                             to the Force.com service with its {@code ForceConnectorConfig} state
     * @throws ConnectionException if the namespace cannot be retrieved over the Force.com connection
     */
    public String getNamespace() throws ConnectionException {
        if (metadataConnection == null) {
            initMetadataConnection();
        }
        if (!config.isNamespaceInitialized()) {
            DescribeMetadataResult result = metadataConnection.describeMetadata(DESCRIBE_METADATA_VERSION);
            String organizationNamespace = result.getOrganizationNamespace();
            config.setNamespace(organizationNamespace != null && organizationNamespace.length() > 0
                    ? organizationNamespace : null);
        }
        return config.getNamespace();
    }

    /**
     * Clears this {@code ForceServiceConnector}'s local state.
     * <p>
     * The connections from a {@code ForceServiceConnector} are lazily
     * constructed and stored in the {@code ForceServiceConnector}'s local state.  Thus
     * multiple calls to get a connection will return the same connection object without
     * re-establishing a connection to the Force.com service.  The {@code close} method
     * forces this {@code ForceServiceConnector} to re-establish a connection with the
     * Force.com service by clearing its local state.
     *
     * @see ForceServiceConnector#getConnection()
     * @see ForceServiceConnector#getMetadataConnection()
     * @see ForceServiceConnector#getBulkConnection()
     * @see ForceServiceConnector#renewSession(ConnectorConfig)
     */
    public void close() {
        this.config = null;
       
        this.connectionName = null;
       
        this.externalConfig = null;

        this.clientId = null;
        this.externalClientId = null;

        this.timeout = 0;
       
        this.connection = null;
        this.metadataConnection = null;
        this.bulkConnection = null;
    }
   
    static void clearCache() {
        CACHED_CONFIGS.clear();
        CONN_NAME_TO_CACHED_CONFIGS.clear();
    }

    static Map<String, ForceConnectorConfig> getCachedConfigs() {
        return CACHED_CONFIGS;
    }
   
    static ForceConnectorConfig getCachedConfig(String cacheId) {
        if (cacheId == null) return null;
        return CACHED_CONFIGS.get(cacheId);
    }

    /**
     * Automatically renews Force.com timed out sessions.
     * <p>
     * The connections from a {@code ForceServiceConnector} are lazily
     * constructed and stored in the {@code ForceServiceConnector}'s local state.  Thus
     * multiple calls to get a connection will return the same connection object without
     * re-establishing a connection to the Force.com service.  However, this presents
     * a problem should the Force.com session expire.  In that case, stored connections
     * will have their session automatically renewed by the {@code renewSession}.
     *
     * @param connectorConfig the {@code ForceConnectorConfig} to be used to re-establish a
     *               Force.com connection
     * @return a session renewal SOAP header
     * @throws ConnectionException if the Force.com connection cannot be re-established
     * @see ForceServiceConnector#getConnection()
     * @see ForceServiceConnector#getMetadataConnection()
     * @see ForceServiceConnector#getBulkConnection()
     * @see ForceServiceConnector#close()
     */
    @Override
    public SessionRenewalHeader renewSession(ConnectorConfig connectorConfig) throws ConnectionException {
        if (connectorConfig.getPassword() != null) {
            connectorConfig.setSessionId(null);
           
            close();
            setConnectorConfig((ForceConnectorConfig) connectorConfig);
            getConnection();

            SessionRenewalHeader ret = new SessionRenewalHeader();
            ret.name = SESSION_HEADER_QNAME;
            SessionHeader_element se = new SessionHeader_element();
            se.setSessionId(connectorConfig.getSessionId());
            ret.headerElement = se;
            return ret;
        }
        return null;
    }


    /**
     * Sets the Force.com connection client id.
     * <p>
     * The client id is a {@code String} identifier that is set on the Force.com
     * connection in this {@code ForceServiceConnector}.  Note that the client
     * id set here will override the client id in this {@code ForceServiceConnector}'s
     * {@code ForceConnectorConfig} state.
     *
     * @param clientId any non {@code null}, non empty {@code String} that is
     *                 to be used as a Force.com connection identifier
     */

    public void setClientId(String clientId) {

        this.clientId = clientId;

    }

    /**
     * Returns the named {@code ForceConnectorConfig} source in
     * this {@code ForceServiceConnector}.
     * <p>
     * A named {@code ForceConnectorConfig} source specifies connection
     * properties in a named location.  These properties can be used to construct
     * a {@code ForceConnectorConfig}.
     *
     * @return a named {@code ForceConnectorConfig} source
     * @see ForceConnectorUtils#loadConnectorPropsFromName(String)
     */
    public String getConnectionName() {
        return connectionName;
    }
   
    /**
     * Sets the named {@code ForceConnectorConfig} source in
     * this {@code ForceServiceConnector}.
     * <p>
     * A named {@code ForceConnectorConfig} source specifies connection
     * properties in a named location.  These properties can be used to construct
     * a {@code ForceConnectorConfig}.  Note that a named connection {@code ForceConnectorConfig}
     * source can be overridden by directly injecting the {@code ForceConnectorConfig} state.
     *
     * @param connectionName the name of a {@code ForceConnectorConfig} source
     * @see ForceConnectorUtils#loadConnectorPropsFromName(String)
     * @see ForceServiceConnector#setConnectorConfig(ForceConnectorConfig)
     */
    public void setConnectionName(String connectionName) {
        this.connectionName = connectionName;
    }

    /**
     * Sets the {@code ForceConnectorConfig} state in this {@code ForceServiceConnector}.
     * <p>
     * The {@code ForceConnectorConfig} state is used by a {@code ForceServiceConnector}
     * to get connections to the Force.com service.  Note that setting this state
     * will override any named {@code ForceConnectorConfig} source set
     * in this {@code ForceServiceConnector}.
     *
     * @param connectorConfig the {@code ForceConnectorConfig} be to used to get Force.com connection
     *               within this {@code ForceServiceConnector}
     * @see ForceConnectorUtils#loadConnectorPropsFromName(String)
     * @see ForceServiceConnector#setConnectionName(String)
     */
    public void setConnectorConfig(ForceConnectorConfig connectorConfig) {
        this.externalConfig = connectorConfig;
    }
   
    /**
     * Indicates whether or not this {@code ForceServiceConnector} should skip
     * in-memory {@code ForceConnectorConfig} cache reads and writes.
     * <p>
     * By default, a {@code ForceServiceConnector} will cache {@code ForceConnectorConfig}
     * objects when getting a connection to the Force.com service.   This state allows
     * the caller to control whether that cache is used or not.
     *
     * @param skipCache boolean to indicate whether this {@code ForceServiceConnector} should
     *                  ignore the {@code ForceConnectorConfig} in memory cache
     */
    public void setSkipCache(boolean skipCache) {
        this.skipCache = skipCache;
    }
   
    /**
     * Sets the read timeout for all Force.com connections using this {@code ForceServiceConnector}.
     * <p>
     * Note that this timeout value will override any read timeout value set in
     * a {@code ForceConnectorConfig}.
     *
     * @param timeout the Force.com connection read timeout in milliseconds
     */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
}
TOP

Related Classes of com.force.sdk.connector.ForceServiceConnector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.