package com.microsoft.bingads; import com.microsoft.bingads.internal.HeaderHandler; import com.microsoft.bingads.internal.OAuthWithAuthorizationCode; import com.microsoft.bingads.internal.ServiceFactory; import com.microsoft.bingads.internal.ServiceFactoryFactory; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.Map; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import javax.jws.WebService; import javax.xml.ws.Service; import javax.xml.ws.handler.Handler; import javax.xml.ws.handler.HandlerResolver; import javax.xml.ws.handler.PortInfo; /** * Provides an interface for calling the methods of the specified Bing Ads service. * <p> * Note: Valid value of {@link T} are: * <ul> * <li>{@link IBulkService}</li> * <li>{@link ICampaignManagementService}</li> * <li>{@link ICustomerBillingService}</li> * <li>{@link ICustomerManagementService}</li> * <li>{@link IReportingService}</li> * </ul> * * </p> * * @param <T> The Bing Ads service interface that should be called. For example, {@link ICampaignManagementService}. * */ public class ServiceClient<T> { private final AuthorizationData authorizationData; private final Class<T> serviceInterface; private final Service service; private final ServiceFactory serviceFactory; private ApiEnvironment environment; /** * Gets the Bing Ads API environment. */ public ApiEnvironment getEnvironment() { return environment; } /** * Gets the data representing a user who intends to call the API. */ public AuthorizationData getAuthorizationData() { return authorizationData; } /** * Initializes a new instance of this class with the specified authorization data. * * @param authorizationData Represents a user who intends to access the corresponding customer and account. * @param serviceInterface the Bing Ads service interface that should be called */ public ServiceClient(AuthorizationData authorizationData, Class<T> serviceInterface) { this(authorizationData, null, serviceInterface); } /** * Initializes a new instance of this class with the specified authorization data and Bing Ads API environment. * * @param authorizationData Represents a user who intends to access the corresponding customer and account. * @param environment Bing Ads API environment * @param serviceInterface the Bing Ads service interface that should be called */ public ServiceClient(AuthorizationData authorizationData, ApiEnvironment environment, Class<T> serviceInterface) { this.authorizationData = authorizationData; this.serviceInterface = serviceInterface; if (environment == null) { environment = getEnvironmentFromConfig(); } if (environment == null) { environment = ApiEnvironment.PRODUCTION; } this.environment = environment; serviceFactory = ServiceFactoryFactory.createServiceFactory(); service = serviceFactory.createService(serviceInterface, environment); } /** * Creates an object implementing the service interface that needs to be called. * * @return the service object implementing the service interface */ public T getService() { authorizationData.validate(); WebService webServiceAnnotation = serviceInterface.getAnnotation(WebService.class); final String ns = webServiceAnnotation.targetNamespace(); final Map<String, String> headers = new HashMap<String, String>(); headers.put("CustomerAccountId", Long.toString(authorizationData.getAccountId())); headers.put("CustomerId", Long.toString(authorizationData.getCustomerId())); headers.put("DeveloperToken", authorizationData.getDeveloperToken()); refreshOAuthTokensIfNeeded(); this.authorizationData.getAuthentication().addHeaders(new HeadersImpl() { @Override public void addHeader(String name, String value) { headers.put(name, value); } }); service.setHandlerResolver(new HandlerResolver() { @Override public List<Handler> getHandlerChain(PortInfo portInfo) { List<Handler> handlerList = new ArrayList<Handler>(); handlerList.add(new HeaderHandler(ns, headers)); return handlerList; } }); T port = serviceFactory.createProxyFromService(service, environment, serviceInterface); return port; } private void refreshOAuthTokensIfNeeded() { if (authorizationData.getAuthentication() instanceof OAuthWithAuthorizationCode) { OAuthWithAuthorizationCode auth = (OAuthWithAuthorizationCode) authorizationData.getAuthentication(); auth.refreshTokensIfNeeded(false); } } private ApiEnvironment getEnvironmentFromConfig() { InputStream input = null; try { input = this.getClass().getClassLoader().getResourceAsStream("bingads.properties"); if (input == null) { return null; } Properties props = new Properties(); props.load(input); String envString = props.getProperty("environment"); if (envString == null) { return null; } return ApiEnvironment.fromValue(envString); } catch (IOException ex) { return null; } finally { try { if (input != null) { input.close(); } } catch (IOException ex) { throw new InternalException(ex); } } } }