package com.paypal.core.rest; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties; import com.paypal.core.APICallPreHandler; import com.paypal.core.ConfigManager; import com.paypal.core.ConnectionManager; import com.paypal.core.Constants; import com.paypal.core.HttpConfiguration; import com.paypal.core.HttpConnection; import com.paypal.core.LoggingManager; import com.paypal.core.SDKUtil; import com.paypal.core.SDKVersion; /** * PayPalResource acts as a base class for REST enabled resources. */ public abstract class PayPalResource { /* * The class relies on an implementation of APICallPreHandler (here * RESTAPICallPreHandler)to get access to endpoint, HTTP headers, and * payload. */ /** * Map used in dynamic configuration */ private static Map<String, String> configurationMap; /** * Configuration enabled flag */ private static boolean configInitialized = false; /** * Last request sent to Service */ private static final ThreadLocal<String> LASTREQUEST = new ThreadLocal<String>(); /** * Last response returned form Service */ private static final ThreadLocal<String> LASTRESPONSE = new ThreadLocal<String>(); /** * Initialize the system using a File(Properties file). The system is * initialized using the given file and if the initialization succeeds the * default 'sdk_config.properties' can only be loaded by calling the method * initializeToDefault() * * @param file * File object of a properties entity * @throws PayPalRESTException * @return OAuthTokenCredential instance with client ID and client secret stored in configuration file. */ public static OAuthTokenCredential initConfig(File file) throws PayPalRESTException { try { if (!file.exists()) { throw new FileNotFoundException("File doesn't exist: " + file.getAbsolutePath()); } FileInputStream fis = new FileInputStream(file); return initConfig(fis); } catch (IOException ioe) { LoggingManager.severe(PayPalResource.class, ioe.getMessage(), ioe); throw new PayPalRESTException(ioe.getMessage(), ioe); } } /** * Initialize using Properties. The system is initialized using the given * properties object and if the initialization succeeds the default * 'sdk_config.properties' can only be loaded by calling the method * initializeToDefault() * * @param properties * Properties object * @return OAuthTokenCredential instance with client ID and client secret in given properties. */ public static OAuthTokenCredential initConfig(Properties properties) { configurationMap = SDKUtil.constructMap(properties); configInitialized = true; return getOAuthTokenCredential(); } /** * Initialize using {@link InputStream}(of a Properties file).. The system * is initialized using the given {@link InputStream} and if the * initialization succeeds the default 'sdk_config.properties' can only be * loaded by calling the method initializeToDefault(). The system is * initialized with the information after loading defaults for the * parameters that are not passed as part of the configuration. For defaults * see {@link ConfigManager} * * @param inputStream * InputStream * @throws PayPalRESTException * @return OAuthTokenCredential instance with client ID and client secret stored in given inputStream. */ public static OAuthTokenCredential initConfig(InputStream inputStream) throws PayPalRESTException { try { Properties properties = new Properties(); properties.load(inputStream); /* * Create a Map instance and combine it with default values */ configurationMap = SDKUtil.constructMap(properties); configInitialized = true; return getOAuthTokenCredential(); } catch (IOException ioe) { LoggingManager.severe(PayPalResource.class, ioe.getMessage(), ioe); throw new PayPalRESTException(ioe.getMessage(), ioe); } } /** * Return Client ID from configuration Map */ public static String getClientID() { return configurationMap.get(Constants.CLIENT_ID); } /** * Returns Client Secret from configuration Map */ public static String getClientSecret() { return configurationMap.get(Constants.CLIENT_SECRET); } /** * Returns OAuthTokenCredential instance using client ID and client secret loaded from configuration. * @return OAuthTokenCredential instance. */ public static OAuthTokenCredential getOAuthTokenCredential() { if(configInitialized){ return new OAuthTokenCredential(getClientID(), getClientSecret(), configurationMap); }else{ return new OAuthTokenCredential(getClientID(), getClientSecret()); } } /** * Initialize to default properties * * @throws PayPalRESTException */ public static void initializeToDefault() throws PayPalRESTException { configurationMap = SDKUtil.combineDefaultMap(ConfigManager .getInstance().getConfigurationMap()); } /** * Returns the last request sent to the Service * * @return Last request sent to the server */ public static String getLastRequest() { return LASTREQUEST.get(); } /** * Returns the last response returned by the Service * * @return Last response got from the Service */ public static String getLastResponse() { return LASTRESPONSE.get(); } /** * Configures and executes REST call: Supports JSON * * @deprecated * @param <T> * Response Type for de-serialization * @param accessToken * OAuth AccessToken to be used for the call. * @param httpMethod * Http Method verb * @param resourcePath * Resource URI path * @param payLoad * Payload to Service * @param clazz * {@link Class} object used in De-serialization * @return T * @throws PayPalRESTException */ public static <T> T configureAndExecute(String accessToken, HttpMethod httpMethod, String resourcePath, String payLoad, Class<T> clazz) throws PayPalRESTException { return configureAndExecute(null, accessToken, httpMethod, resourcePath, null, payLoad, null, clazz); } /** * Configures and executes REST call: Supports JSON * * @param <T> * Response Type for de-serialization * @param apiContext * {@link APIContext} to be used for the call. * @param httpMethod * Http Method verb * @param resource * Resource URI path * @param payLoad * Payload to Service * @param clazz * {@link Class} object used in De-serialization * @return T * @throws PayPalRESTException */ public static <T> T configureAndExecute(APIContext apiContext, HttpMethod httpMethod, String resourcePath, String payLoad, Class<T> clazz) throws PayPalRESTException { T t = null; Map<String, String> cMap; String accessToken; String requestId; Map<String, String> headersMap; if (apiContext != null) { if (apiContext.getConfigurationMap() != null) { cMap = SDKUtil.combineDefaultMap(apiContext .getConfigurationMap()); } else { if (!configInitialized) { initializeToDefault(); } /* * The Map returned here is already combined with default values */ cMap = new HashMap<String, String>( PayPalResource.configurationMap); } headersMap = apiContext.getHTTPHeaders(); accessToken = apiContext.getAccessToken(); requestId = apiContext.getRequestId(); APICallPreHandler apiCallPreHandler = createAPICallPreHandler(cMap, payLoad, resourcePath, headersMap, accessToken, requestId, apiContext.getSdkVersion()); HttpConfiguration httpConfiguration = createHttpConfiguration(cMap, httpMethod, apiCallPreHandler); t = execute(apiCallPreHandler, httpConfiguration, clazz); } return t; } /** * Configures and executes REST call: Supports JSON * * @deprecated * @param <T> * @param apiContext * {@link APIContext} to be used for the call. * @param httpMethod * Http Method verb * @param resourcePath * Resource URI path * @param headersMap * Optional headers Map * @param payLoad * Payload to Service * @param clazz * {@link Class} object used in De-serialization * @return T * @throws PayPalRESTException */ public static <T> T configureAndExecute(APIContext apiContext, HttpMethod httpMethod, String resourcePath, Map<String, String> headersMap, String payLoad, Class<T> clazz) throws PayPalRESTException { Map<String, String> cMap = null; String accessToken = null; String requestId = null; if (apiContext != null) { cMap = apiContext.getConfigurationMap(); accessToken = apiContext.getAccessToken(); requestId = apiContext.getRequestId(); } return configureAndExecute(cMap, accessToken, httpMethod, resourcePath, headersMap, payLoad, requestId, clazz); } private static <T> T configureAndExecute( Map<String, String> configurationMap, String accessToken, HttpMethod httpMethod, String resourcePath, Map<String, String> headersMap, String payLoad, String requestId, Class<T> clazz) throws PayPalRESTException { T t; Map<String, String> cMap; /* * Check for null before combining with default */ if (configurationMap != null) { cMap = SDKUtil.combineDefaultMap(configurationMap); } else { if (!configInitialized) { initializeToDefault(); } /* * The Map returned here is already combined with default values */ cMap = new HashMap<String, String>(PayPalResource.configurationMap); } APICallPreHandler apiCallPreHandler = createAPICallPreHandler(cMap, payLoad, resourcePath, headersMap, accessToken, requestId, null); HttpConfiguration httpConfiguration = createHttpConfiguration(cMap, httpMethod, apiCallPreHandler); t = execute(apiCallPreHandler, httpConfiguration, clazz); return t; } /** * Returns a implementation of {@link APICallPreHandler} for the underlying * layer. * * @param configurationMap * configuration Map * @param payLoad * Raw payload * @param resourcePath * URI part of the resource operated on * @param headersMap * Custom HTTP headers map * @param accessToken * OAuth Token * @param requestId * PayPal Request Id * @param sdkVersion * {@link SDKVersion} instance * @return */ public static APICallPreHandler createAPICallPreHandler( Map<String, String> configurationMap, String payLoad, String resourcePath, Map<String, String> headersMap, String accessToken, String requestId, SDKVersion sdkVersion) { APICallPreHandler apiCallPreHandler; RESTAPICallPreHandler restAPICallPreHandler = new RESTAPICallPreHandler( configurationMap, headersMap); restAPICallPreHandler.setResourcePath(resourcePath); restAPICallPreHandler.setRequestId(requestId); restAPICallPreHandler.setAuthorizationToken(accessToken); restAPICallPreHandler.setPayLoad(payLoad); restAPICallPreHandler.setSdkVersion(sdkVersion); apiCallPreHandler = restAPICallPreHandler; return apiCallPreHandler; } /** * Execute the API call and return response * * @param <T> * Generic Type for response object construction * @param apiCallPreHandler * Implementation of {@link APICallPreHandler} * @param httpConfiguration * {@link HttpConfiguration} * @param clazz * Response Object class * @return Response Type * @throws PayPalRESTException */ private static <T> T execute(APICallPreHandler apiCallPreHandler, HttpConfiguration httpConfiguration, Class<T> clazz) throws PayPalRESTException { T t = null; ConnectionManager connectionManager; HttpConnection httpConnection; Map<String, String> headers; String responseString; try { // REST Headers headers = apiCallPreHandler.getHeaderMap(); // HttpConnection Initialization connectionManager = ConnectionManager.getInstance(); httpConnection = connectionManager.getConnection(httpConfiguration); httpConnection.createAndconfigureHttpConnection(httpConfiguration); LASTREQUEST.set(apiCallPreHandler.getPayLoad()); responseString = httpConnection.execute(null, apiCallPreHandler.getPayLoad(), headers); LASTRESPONSE.set(responseString); if (clazz != null) { t = JSONFormatter.fromJSON(responseString, clazz); } } catch (Exception e) { throw new PayPalRESTException(e.getMessage(), e); } return t; } /** * Utility method that creates a {@link HttpConfiguration} object from the * passed information * * @param configurationMap * Configuration to base the construction upon. * @param httpMethod * HTTP Method * @param contentType * Content-Type header * @param apiCallPreHandler * {@link APICallPreHandler} for retrieving EndPoint * @return */ private static HttpConfiguration createHttpConfiguration( Map<String, String> configurationMap, HttpMethod httpMethod, APICallPreHandler apiCallPreHandler) { HttpConfiguration httpConfiguration = new HttpConfiguration(); httpConfiguration.setHttpMethod(httpMethod.toString()); httpConfiguration.setEndPointUrl(apiCallPreHandler.getEndPoint()); httpConfiguration .setGoogleAppEngine(Boolean.parseBoolean(configurationMap .get(Constants.GOOGLE_APP_ENGINE))); if (Boolean.parseBoolean(configurationMap .get((Constants.USE_HTTP_PROXY)))) { httpConfiguration.setProxyPort(Integer.parseInt(configurationMap .get((Constants.HTTP_PROXY_PORT)))); httpConfiguration.setProxyHost(configurationMap .get((Constants.HTTP_PROXY_HOST))); httpConfiguration.setProxyUserName(configurationMap .get((Constants.HTTP_PROXY_USERNAME))); httpConfiguration.setProxyPassword(configurationMap .get((Constants.HTTP_PROXY_PASSWORD))); } httpConfiguration.setConnectionTimeout(Integer .parseInt(configurationMap .get(Constants.HTTP_CONNECTION_TIMEOUT))); httpConfiguration.setMaxRetry(Integer.parseInt(configurationMap .get(Constants.HTTP_CONNECTION_RETRY))); httpConfiguration.setReadTimeout(Integer.parseInt(configurationMap .get(Constants.HTTP_CONNECTION_READ_TIMEOUT))); httpConfiguration.setMaxHttpConnection(Integer .parseInt(configurationMap .get(Constants.HTTP_CONNECTION_MAX_CONNECTION))); httpConfiguration.setIpAddress(configurationMap .get(Constants.DEVICE_IP_ADDRESS)); return httpConfiguration; } }