The code samples below provide examples of common account management functions using the AdWords API. Client Library.
Accept an invitation for linking to a manager account
// Copyright 2017 Google Inc. All Rights Reserved. // // 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 adwords.axis.v201809.accountmanagement; import static com.google.api.ads.common.lib.utils.Builder.DEFAULT_CONFIGURATION_FILENAME; import com.beust.jcommander.Parameter; import com.google.api.ads.adwords.axis.factory.AdWordsServices; import com.google.api.ads.adwords.axis.v201809.cm.ApiError; import com.google.api.ads.adwords.axis.v201809.cm.ApiException; import com.google.api.ads.adwords.axis.v201809.cm.Operator; import com.google.api.ads.adwords.axis.v201809.mcm.CustomerServiceInterface; import com.google.api.ads.adwords.axis.v201809.mcm.ServiceLink; import com.google.api.ads.adwords.axis.v201809.mcm.ServiceLinkLinkStatus; import com.google.api.ads.adwords.axis.v201809.mcm.ServiceLinkOperation; import com.google.api.ads.adwords.axis.v201809.mcm.ServiceType; import com.google.api.ads.adwords.lib.client.AdWordsSession; import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface; import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames; import com.google.api.ads.common.lib.auth.OfflineCredentials; import com.google.api.ads.common.lib.auth.OfflineCredentials.Api; import com.google.api.ads.common.lib.conf.ConfigurationLoadException; import com.google.api.ads.common.lib.exception.OAuthException; import com.google.api.ads.common.lib.exception.ValidationException; import com.google.api.ads.common.lib.utils.examples.CodeSampleParams; import com.google.api.client.auth.oauth2.Credential; import java.rmi.RemoteException; /** * This example accepts a pending invitation to link your AdWords account to a Google Merchant * Center account. * * <p>Credentials and properties in {@code fromFile()} are pulled from the "ads.properties" file. * See README for more info. */ public class AcceptServiceLink { private static class AcceptServiceLinkParams extends CodeSampleParams { @Parameter(names = ArgumentNames.SERVICE_LINK_ID, required = true) private Long serviceLinkId; } public static void main(String[] args) { AdWordsSession session; try { // Generate a refreshable OAuth2 credential. Credential oAuth2Credential = new OfflineCredentials.Builder() .forApi(Api.ADWORDS) .fromFile() .build() .generateCredential(); // Construct an AdWordsSession. session = new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build(); } catch (ConfigurationLoadException cle) { System.err.printf( "Failed to load configuration from the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, cle); return; } catch (ValidationException ve) { System.err.printf( "Invalid configuration in the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, ve); return; } catch (OAuthException oe) { System.err.printf( "Failed to create OAuth credentials. Check OAuth settings in the %s file. " + "Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, oe); return; } AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance(); AcceptServiceLinkParams params = new AcceptServiceLinkParams(); if (!params.parseArguments(args)) { // Either pass the required parameters for this example on the command line, or insert them // into the code here. See the parameter class definition above for descriptions. params.serviceLinkId = Long.parseLong("INSERT_SERVICE_LINK_ID_HERE"); } try { runExample(adWordsServices, session, params.serviceLinkId); } catch (ApiException apiException) { // ApiException is the base class for most exceptions thrown by an API request. Instances // of this exception have a message and a collection of ApiErrors that indicate the // type and underlying cause of the exception. Every exception object in the adwords.axis // packages will return a meaningful value from toString // // ApiException extends RemoteException, so this catch block must appear before the // catch block for RemoteException. System.err.println("Request failed due to ApiException. Underlying ApiErrors:"); if (apiException.getErrors() != null) { int i = 0; for (ApiError apiError : apiException.getErrors()) { System.err.printf(" Error %d: %s%n", i++, apiError); } } } catch (RemoteException re) { System.err.printf( "Request failed unexpectedly due to RemoteException: %s%n", re); } } /** * Runs the example. * * @param adWordsServices the services factory. * @param session the session. * @param serviceLinkId the ID of the service link to accept. * @throws ApiException if the API request failed with one or more service errors. * @throws RemoteException if the API request failed due to other errors. */ public static void runExample( AdWordsServicesInterface adWordsServices, AdWordsSession session, long serviceLinkId) throws RemoteException { // Get the CustomerService. CustomerServiceInterface customerService = adWordsServices.get(session, CustomerServiceInterface.class); // Create the operation to set the status to ACTIVE. ServiceLinkOperation op = new ServiceLinkOperation(); op.setOperator(Operator.SET); ServiceLink serviceLink = new ServiceLink(); serviceLink.setServiceLinkId(serviceLinkId); serviceLink.setServiceType(ServiceType.MERCHANT_CENTER); serviceLink.setLinkStatus(ServiceLinkLinkStatus.ACTIVE); op.setOperand(serviceLink); // Update the service link. ServiceLink[] mutatedServiceLinks = customerService.mutateServiceLinks(new ServiceLinkOperation[] {op}); // Display the results. for (ServiceLink mutatedServiceLink : mutatedServiceLinks) { System.out.printf( "Service link with service link ID %d, type '%s' updated to status: %s.%n", mutatedServiceLink.getServiceLinkId(), mutatedServiceLink.getServiceType(), mutatedServiceLink.getLinkStatus()); } } }
Create a new account under an AdWords manager
// Copyright 2017 Google Inc. All Rights Reserved. // // 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 adwords.axis.v201809.accountmanagement; import static com.google.api.ads.common.lib.utils.Builder.DEFAULT_CONFIGURATION_FILENAME; import com.google.api.ads.adwords.axis.factory.AdWordsServices; import com.google.api.ads.adwords.axis.v201809.cm.ApiError; import com.google.api.ads.adwords.axis.v201809.cm.ApiException; import com.google.api.ads.adwords.axis.v201809.cm.Operator; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomer; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomerOperation; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomerReturnValue; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomerServiceInterface; import com.google.api.ads.adwords.lib.client.AdWordsSession; import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface; import com.google.api.ads.common.lib.auth.OfflineCredentials; import com.google.api.ads.common.lib.auth.OfflineCredentials.Api; import com.google.api.ads.common.lib.conf.ConfigurationLoadException; import com.google.api.ads.common.lib.exception.OAuthException; import com.google.api.ads.common.lib.exception.ValidationException; import com.google.api.client.auth.oauth2.Credential; import java.rmi.RemoteException; import org.joda.time.DateTime; /** * This example creates a new account under an AdWords manager account. * * <p>Note: this example must be run using the credentials of an AdWords manager account, and * by default the new account will only be accessible via the parent AdWords manager * account. * * <p>Credentials and properties in {@code fromFile()} are pulled from the * "ads.properties" file. See README for more info. */ public class CreateAccount { public static void main(String[] args) { AdWordsSession session; try { // Generate a refreshable OAuth2 credential. Credential oAuth2Credential = new OfflineCredentials.Builder() .forApi(Api.ADWORDS) .fromFile() .build() .generateCredential(); // Construct an AdWordsSession. session = new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build(); } catch (ConfigurationLoadException cle) { System.err.printf( "Failed to load configuration from the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, cle); return; } catch (ValidationException ve) { System.err.printf( "Invalid configuration in the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, ve); return; } catch (OAuthException oe) { System.err.printf( "Failed to create OAuth credentials. Check OAuth settings in the %s file. " + "Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, oe); return; } AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance(); try { runExample(adWordsServices, session); } catch (ApiException apiException) { // ApiException is the base class for most exceptions thrown by an API request. Instances // of this exception have a message and a collection of ApiErrors that indicate the // type and underlying cause of the exception. Every exception object in the adwords.axis // packages will return a meaningful value from toString // // ApiException extends RemoteException, so this catch block must appear before the // catch block for RemoteException. System.err.println("Request failed due to ApiException. Underlying ApiErrors:"); if (apiException.getErrors() != null) { int i = 0; for (ApiError apiError : apiException.getErrors()) { System.err.printf(" Error %d: %s%n", i++, apiError); } } } catch (RemoteException re) { System.err.printf( "Request failed unexpectedly due to RemoteException: %s%n", re); } } /** * Runs the example. * * @param adWordsServices the services factory. * @param session the session. * @throws ApiException if the API request failed with one or more service errors. * @throws RemoteException if the API request failed due to other errors. */ public static void runExample( AdWordsServicesInterface adWordsServices, AdWordsSession session) throws RemoteException { // Get the CampaignService. ManagedCustomerServiceInterface managedCustomerService = adWordsServices.get(session, ManagedCustomerServiceInterface.class); // Create account. ManagedCustomer customer = new ManagedCustomer(); customer.setName("Customer created with ManagedCustomerService on " + DateTime.now()); customer.setCurrencyCode("EUR"); customer.setDateTimeZone("Europe/London"); // Create operations. ManagedCustomerOperation operation = new ManagedCustomerOperation(); operation.setOperand(customer); operation.setOperator(Operator.ADD); ManagedCustomerOperation[] operations = new ManagedCustomerOperation[] {operation}; // Add account. ManagedCustomerReturnValue result = managedCustomerService.mutate(operations); // Display accounts. for (ManagedCustomer customerResult : result.getValue()) { System.out.printf("Account with customer ID %d was created.%n", customerResult.getCustomerId()); } } }
Get all account changes during the past 24 hours
// Copyright 2017 Google Inc. All Rights Reserved. // // 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 adwords.axis.v201809.accountmanagement; import static com.google.api.ads.common.lib.utils.Builder.DEFAULT_CONFIGURATION_FILENAME; import com.google.api.ads.adwords.axis.factory.AdWordsServices; import com.google.api.ads.adwords.axis.utils.v201809.SelectorBuilder; import com.google.api.ads.adwords.axis.v201809.ch.AdGroupChangeData; import com.google.api.ads.adwords.axis.v201809.ch.CampaignChangeData; import com.google.api.ads.adwords.axis.v201809.ch.ChangeStatus; import com.google.api.ads.adwords.axis.v201809.ch.CustomerChangeData; import com.google.api.ads.adwords.axis.v201809.ch.CustomerSyncSelector; import com.google.api.ads.adwords.axis.v201809.ch.CustomerSyncServiceInterface; import com.google.api.ads.adwords.axis.v201809.cm.ApiError; import com.google.api.ads.adwords.axis.v201809.cm.ApiException; import com.google.api.ads.adwords.axis.v201809.cm.CampaignPage; import com.google.api.ads.adwords.axis.v201809.cm.CampaignServiceInterface; import com.google.api.ads.adwords.axis.v201809.cm.DateTimeRange; import com.google.api.ads.adwords.axis.v201809.cm.Selector; import com.google.api.ads.adwords.lib.client.AdWordsSession; import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface; import com.google.api.ads.adwords.lib.selectorfields.v201809.cm.CampaignField; import com.google.api.ads.common.lib.auth.OfflineCredentials; import com.google.api.ads.common.lib.auth.OfflineCredentials.Api; import com.google.api.ads.common.lib.conf.ConfigurationLoadException; import com.google.api.ads.common.lib.exception.OAuthException; import com.google.api.ads.common.lib.exception.ValidationException; import com.google.api.client.auth.oauth2.Credential; import java.rmi.RemoteException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; /** * This example gets the changes in the account during the last 24 hours. */ public class GetAccountChanges { public static void main(String[] args) { AdWordsSession session; try { // Generate a refreshable OAuth2 credential. Credential oAuth2Credential = new OfflineCredentials.Builder() .forApi(Api.ADWORDS) .fromFile() .build() .generateCredential(); // Construct an AdWordsSession. session = new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build(); } catch (ConfigurationLoadException cle) { System.err.printf( "Failed to load configuration from the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, cle); return; } catch (ValidationException ve) { System.err.printf( "Invalid configuration in the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, ve); return; } catch (OAuthException oe) { System.err.printf( "Failed to create OAuth credentials. Check OAuth settings in the %s file. " + "Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, oe); return; } AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance(); try { runExample(adWordsServices, session); } catch (ApiException apiException) { // ApiException is the base class for most exceptions thrown by an API request. Instances // of this exception have a message and a collection of ApiErrors that indicate the // type and underlying cause of the exception. Every exception object in the adwords.axis // packages will return a meaningful value from toString // // ApiException extends RemoteException, so this catch block must appear before the // catch block for RemoteException. System.err.println("Request failed due to ApiException. Underlying ApiErrors:"); if (apiException.getErrors() != null) { int i = 0; for (ApiError apiError : apiException.getErrors()) { System.err.printf(" Error %d: %s%n", i++, apiError); } } } catch (RemoteException re) { System.err.printf( "Request failed unexpectedly due to RemoteException: %s%n", re); } } /** * Runs the example. * * @param adWordsServices the services factory. * @param session the session. * @throws ApiException if the API request failed with one or more service errors. * @throws RemoteException if the API request failed due to other errors. */ public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session) throws RemoteException { // Get the CampaignService. CampaignServiceInterface campaignService = adWordsServices.get(session, CampaignServiceInterface.class); // Get the CustomerSyncService. CustomerSyncServiceInterface customerSyncService = adWordsServices.get(session, CustomerSyncServiceInterface.class); // Get a list of all campaign IDs. List<Long> campaignIds = new ArrayList<>(); Selector selector = new SelectorBuilder() .fields(CampaignField.Id) .build(); CampaignPage campaigns = campaignService.get(selector); if (campaigns.getEntries() != null) { Arrays.stream(campaigns.getEntries()).forEach(campaign -> campaignIds.add(campaign.getId())); } // Create date time range for the past 24 hours. DateTimeRange dateTimeRange = new DateTimeRange(); dateTimeRange.setMin(new SimpleDateFormat("yyyyMMdd HHmmss").format(new Date(System .currentTimeMillis() - 1000L * 60 * 60 * 24))); dateTimeRange.setMax(new SimpleDateFormat("yyyyMMdd HHmmss").format(new Date())); // Create selector. CustomerSyncSelector customerSyncSelector = new CustomerSyncSelector(); customerSyncSelector.setDateTimeRange(dateTimeRange); customerSyncSelector .setCampaignIds(ArrayUtils.toPrimitive(campaignIds.toArray(new Long[] {}))); // Get all account changes for campaign. CustomerChangeData accountChanges = customerSyncService.get(customerSyncSelector); // Display changes. if (accountChanges != null && accountChanges.getChangedCampaigns() != null) { System.out.printf("Most recent change: %s%n", accountChanges.getLastChangeTimestamp()); for (CampaignChangeData campaignChanges : accountChanges.getChangedCampaigns()) { System.out.printf("Campaign with ID %d was changed:%n", campaignChanges.getCampaignId()); System.out.printf("\tCampaign changed status: '%s'%n", campaignChanges.getCampaignChangeStatus()); if (!ChangeStatus.NEW.equals(campaignChanges.getCampaignChangeStatus())) { System.out.printf("\tAdded campaign criteria: %s%n", getFormattedList(campaignChanges.getAddedCampaignCriteria())); System.out.printf("\tRemoved campaign criteria: %s%n", getFormattedList(campaignChanges.getRemovedCampaignCriteria())); if (campaignChanges.getChangedAdGroups() != null) { for (AdGroupChangeData adGroupChanges : campaignChanges.getChangedAdGroups()) { System.out.printf("\tAd group with ID %d was changed:%n", adGroupChanges.getAdGroupId()); System.out.printf("\t\tAd group changed status: %s%n", adGroupChanges.getAdGroupChangeStatus()); if (!ChangeStatus.NEW.equals(adGroupChanges.getAdGroupChangeStatus())) { System.out.printf("\t\tAds changed: %s%n", getFormattedList(adGroupChanges.getChangedAds())); System.out.printf("\t\tCriteria changed: %s%n", getFormattedList(adGroupChanges.getChangedCriteria())); System.out.printf("\t\tCriteria removed: %s%n", getFormattedList(adGroupChanges.getRemovedCriteria())); } } } } System.out.println(""); } } else { System.out.println("No account changes were found."); } } /** * Gets a formatted list of a long array in the form {1,2,3}. * @param idList the long array * @return the formatted list */ private static String getFormattedList(long[] idList) { if (idList == null) { idList = new long[]{}; } return new StringBuilder().append("{") .append(StringUtils.join(ArrayUtils.toObject(idList), ',')) .append("}").toString(); } }
Get the account hierarchy under the current account
// Copyright 2017 Google Inc. All Rights Reserved. // // 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 adwords.axis.v201809.accountmanagement; import static com.google.api.ads.common.lib.utils.Builder.DEFAULT_CONFIGURATION_FILENAME; import com.google.api.ads.adwords.axis.factory.AdWordsServices; import com.google.api.ads.adwords.axis.utils.v201809.SelectorBuilder; import com.google.api.ads.adwords.axis.v201809.cm.ApiError; import com.google.api.ads.adwords.axis.v201809.cm.ApiException; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomer; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomerLink; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomerPage; import com.google.api.ads.adwords.axis.v201809.mcm.ManagedCustomerServiceInterface; import com.google.api.ads.adwords.lib.client.AdWordsSession; import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface; import com.google.api.ads.adwords.lib.selectorfields.v201809.cm.ManagedCustomerField; import com.google.api.ads.common.lib.auth.OfflineCredentials; import com.google.api.ads.common.lib.auth.OfflineCredentials.Api; import com.google.api.ads.common.lib.conf.ConfigurationLoadException; import com.google.api.ads.common.lib.exception.OAuthException; import com.google.api.ads.common.lib.exception.ValidationException; import com.google.api.client.auth.oauth2.Credential; import com.google.common.collect.Maps; import com.google.common.collect.SortedSetMultimap; import com.google.common.collect.TreeMultimap; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; /** * This example gets the account hierarchy under the current account. * * <p>Credentials and properties in {@code fromFile()} are pulled from the * "ads.properties" file. See README for more info. */ public class GetAccountHierarchy { private static final int PAGE_SIZE = 500; public static void main(String[] args) { AdWordsSession session; try { // Generate a refreshable OAuth2 credential. Credential oAuth2Credential = new OfflineCredentials.Builder() .forApi(Api.ADWORDS) .fromFile() .build() .generateCredential(); // Construct an AdWordsSession. session = new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build(); } catch (ConfigurationLoadException cle) { System.err.printf( "Failed to load configuration from the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, cle); return; } catch (ValidationException ve) { System.err.printf( "Invalid configuration in the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, ve); return; } catch (OAuthException oe) { System.err.printf( "Failed to create OAuth credentials. Check OAuth settings in the %s file. " + "Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, oe); return; } AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance(); try { runExample(adWordsServices, session); } catch (ApiException apiException) { // ApiException is the base class for most exceptions thrown by an API request. Instances // of this exception have a message and a collection of ApiErrors that indicate the // type and underlying cause of the exception. Every exception object in the adwords.axis // packages will return a meaningful value from toString // // ApiException extends RemoteException, so this catch block must appear before the // catch block for RemoteException. System.err.println("Request failed due to ApiException. Underlying ApiErrors:"); if (apiException.getErrors() != null) { int i = 0; for (ApiError apiError : apiException.getErrors()) { System.err.printf(" Error %d: %s%n", i++, apiError); } } } catch (RemoteException re) { System.err.printf( "Request failed unexpectedly due to RemoteException: %s%n", re); } } /** * Runs the example. * * @param adWordsServices the services factory. * @param session the session. * @throws ApiException if the API request failed with one or more service errors. * @throws RemoteException if the API request failed due to other errors. */ public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session) throws RemoteException { // Get the ServicedAccountService. ManagedCustomerServiceInterface managedCustomerService = adWordsServices.get(session, ManagedCustomerServiceInterface.class); // Create selector builder. int offset = 0; SelectorBuilder selectorBuilder = new SelectorBuilder() .fields(ManagedCustomerField.CustomerId, ManagedCustomerField.Name) .offset(offset) .limit(PAGE_SIZE); // Get results. ManagedCustomerPage page; // Map from customerId to customer node. Map<Long, ManagedCustomerTreeNode> customerIdToCustomerNode = Maps.newHashMap(); // Map from each parent customer ID to its set of linked child customer IDs. SortedSetMultimap<Long, Long> parentIdToChildIds = TreeMultimap.create(); do { page = managedCustomerService.get(selectorBuilder.build()); if (page.getEntries() != null) { // Create account tree nodes for each customer. for (ManagedCustomer customer : page.getEntries()) { ManagedCustomerTreeNode node = new ManagedCustomerTreeNode(); node.account = customer; customerIdToCustomerNode.put(customer.getCustomerId(), node); } // Update the map of parent customer ID to child customer IDs. if (page.getLinks() != null) { for (ManagedCustomerLink link : page.getLinks()) { parentIdToChildIds.put(link.getManagerCustomerId(), link.getClientCustomerId()); } } } offset += PAGE_SIZE; selectorBuilder.increaseOffsetBy(PAGE_SIZE); } while (offset < page.getTotalNumEntries()); // Update the parentNode of each child node, and add each child to the childAccounts // of its parentNode. for (Entry<Long, Long> parentIdEntry : parentIdToChildIds.entries()) { ManagedCustomerTreeNode parentNode = customerIdToCustomerNode.get(parentIdEntry.getKey()); ManagedCustomerTreeNode childNode = customerIdToCustomerNode.get(parentIdEntry.getValue()); childNode.parentNode = parentNode; parentNode.childAccounts.add(childNode); } // Find the root account node in the tree. ManagedCustomerTreeNode rootNode = customerIdToCustomerNode.values().stream() .filter(node -> node.parentNode == null) .findFirst() .orElse(null); // Display serviced account graph. if (rootNode != null) { // Display account tree. System.out.println("CustomerId, Name"); System.out.println(rootNode.toTreeString(0, new StringBuffer())); } else { System.out.println("No serviced accounts were found."); } } /** * Example implementation of a node that would exist in an account tree. */ private static class ManagedCustomerTreeNode { protected ManagedCustomerTreeNode parentNode; protected ManagedCustomer account; protected List<ManagedCustomerTreeNode> childAccounts = new ArrayList<ManagedCustomerTreeNode>(); /** * Default constructor. */ public ManagedCustomerTreeNode() {} @Override public String toString() { return String.format("%s, %s", account.getCustomerId(), account.getName()); } /** * Returns a string representation of the current level of the tree and * recursively returns the string representation of the levels below it. * * @param depth the depth of the node * @param sb the string buffer containing the tree representation * @return the tree string representation */ public StringBuffer toTreeString(int depth, StringBuffer sb) { sb.append(StringUtils.repeat("-", depth * 2)).append(this).append(SystemUtils.LINE_SEPARATOR); childAccounts.forEach(childAccount -> childAccount.toTreeString(depth + 1, sb)); return sb; } } }