Partilhar via


Exemplo de Código de Anúncios de Hotel

Este exemplo demonstra como configurar o Hotel Ads.

Sugestão

Utilize o seletor de idiomas no cabeçalho da documentação para escolher C#, Java, Php ou Python.

Para obter tokens de acesso e atualização para o seu utilizador do Microsoft Advertising e fazer a sua primeira chamada de serviço com a API de Anúncios do Bing, veja o Guia de Introdução . Vai querer rever o guia de Introdução e instruções para o seu idioma preferido, por exemplo, C#, Java, Php e Python.

Os ficheiros de suporte para exemplos de C#, Java, Php e Python estão disponíveis no GitHub. Pode clonar cada repositório ou reutilizar fragmentos conforme necessário.

Importante

Os exemplos de código do Hotel Ads estão atualmente disponíveis em C# e Java.

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V13.CampaignManagement;
using Microsoft.BingAds;
using System.Reflection;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to apply hotel group for Microsoft Hotel Campaigns.
    /// </summary>
    public class HotelAds : ExampleBase
    {
        public override string Description
        {
            get { return "Microsoft Hotel Campaigns | Campaign Management V13"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                    authorizationData: authorizationData,
                    environment: environment);

               // Create a hotel campaign.

                var campaigns = new[] {
                    new Campaign
                    {
                        CampaignType = CampaignType.Hotel, // set campaign type to Hotel
                        Languages = new string[] { "All" }, // for hotel campaign, language should be set to "All"
                        BiddingScheme = new CommissionBiddingScheme // hotel campaign supports commission, percent cpc and manual cpc bidding scheme
                        {
                            CommissionRate = 3.14,
                        },
                        Name = "Everyone's Hotel " + DateTime.UtcNow,
                        DailyBudget = 50,
                        BudgetType = BudgetLimitType.DailyBudgetStandard,
                        TimeZone = "PacificTimeUSCanadaTijuana",
                    }
                };

                OutputStatusMessage("-----\nAddCampaigns:");
                AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(
                    accountId: authorizationData.AccountId,
                    campaigns: campaigns);
                long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                OutputStatusMessage("CampaignIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors);
                long campaignId = (long)campaignIds[0];

                // Create the hotel ad group that will have the hotel groups. This is needed.

                var adGroups = new[] {
                    new AdGroup
                    {
                        Name = "Everyone's Hotel",
                        AdGroupType = "HotelAds",
                        Settings = new []
                        {
                            new HotelSetting
                            {
                                HotelAdGroupType = HotelAdGroupType.HotelAd, // set ad group type, should be HotelAd or PropertyAd or specify both
                            }
                        },
                        StartDate = null,
                        EndDate = new Date {
                            Month = 12,
                            Day = 31,
                            Year = DateTime.UtcNow.Year + 1
                        },
                        // set ad group level bid value
                        // Here the campaign we created is using Commission bidding scheme, so we set CommissionRate
                        // if the campaign bidding scheme is PercentCpc, please set PercentCpcBid
                        // if the campaign bidding scheme is ManualCpc, please set CpcBid
                        CommissionRate = new RateBid
                        {
                            RateAmount = new RateAmount { Amount = 5.6 },
                        }
                    }
                };

                OutputStatusMessage("-----\nAddAdGroups:");
                
                AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync(
                    campaignId: (long)campaignIds[0],
                    adGroups: adGroups,
                    returnInheritedBidStrategyTypes: false);
                long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray();
                BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray();
                OutputStatusMessage("AdGroupIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors);
                long adGroupId = (long)adGroupIds[0];

                // What about hotel ad entity?
                // When we call addAdGroups method, an ad will be automatically created for hotel ad group
                // So it's not needed to add an ad for hotel ad group manually

                // Bid all hotels
                // Create a hotel group tree with one single node (root node), then update bid of the node

                var hotelGrouphelper = new HotelGroupActionHelper(adGroupId);

                var root = hotelGrouphelper.AddUnit(
                    parent: null,
                    listing: new HotelListing { Operand = "All", Attribute = null },
                    bidAmount: 0.35,
                    isNegative: false);

                OutputStatusMessage("-----\nApplyHotelGroupActions:");
                OutputStatusMessage("Applying only the root as a Unit with a bid...");
                var applytHotelGroupActionsResponse = await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
                    criterionActions: hotelGrouphelper.HotelGroupActions);

                // HotelGroup is a kind of AdGroupCriterion, so we can use GetAdGroupCriterionsByIds to get HotelGroup.
                // Also in this example code, "AdGroupCriterion", "HotelGroup" or "HotelGroupCriterion" are equivalent.

                OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
                var hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    adGroupCriterionIds: null,
                    adGroupId: adGroupId,
                    criterionType: AdGroupCriterionType.HotelGroup,
                    null);

                OutputStatusMessage("The ad group's hotel group tree only has a root node: \n");
                OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);

                // Let's update the bid of the root unit we just added.

                BiddableAdGroupCriterion updatedRoot = new BiddableAdGroupCriterion
                {
                    Id = applytHotelGroupActionsResponse.AdGroupCriterionIds[0],
                    CriterionBid = new RateBid
                    {
                        RateAmount = new RateAmount { Amount = 0.45 }
                    }
                };

                hotelGrouphelper = new HotelGroupActionHelper(adGroupId);
                hotelGrouphelper.UpdateHotelGroup(updatedRoot);

                OutputStatusMessage("-----\nApplyHotelGroupActions:");
                OutputStatusMessage("Updating the bid for the tree root node...");
                await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
                    criterionActions: hotelGrouphelper.HotelGroupActions);

                OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
                hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    adGroupCriterionIds: null,
                    adGroupId: adGroupId,
                    criterionType: AdGroupCriterionType.HotelGroup,
                    null);

                OutputStatusMessage("Updated the bid for the tree root node: \n");
                OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);
                
                // Initialize and overwrite existing tree root, and build a hotel group tree structure. 
                // we will build it in steps to demonstrate how to use the results from ApplyHotelGroupActions to update the tree. 

                hotelGrouphelper = new HotelGroupActionHelper(adGroupId);

                // Get existing hotel groups and find the root node.

                OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
                hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    adGroupCriterionIds: null,
                    adGroupId: adGroupId,
                    criterionType: AdGroupCriterionType.HotelGroup,
                    null);

                var existingRoot = GetRootNode(hotelGroupCriterions?.AdGroupCriterions);
                if (existingRoot != null)
                {
                    hotelGrouphelper.DeleteHotelGroup(existingRoot);
                }

                var newRoot = hotelGrouphelper.AddSubdivision(
                    null,
                    new HotelListing { Operand = "All", Attribute = null }
                );
                
                // The direct children of any node must have the same Operand. 
                // For this example we will use StarRating nodes as children of the root. 

                var starRating5SubDivision = hotelGrouphelper.AddSubdivision(
                    parent: newRoot,
                    listing: new HotelListing { Operand = "StarRating", Attribute = "5" });

                var starRating4Unit = hotelGrouphelper.AddUnit(
                    parent: newRoot,
                    listing: new HotelListing { Operand = "StarRating", Attribute = "4" },
                    bidAmount: 0.35,
                    isNegative: false);

                // "Everything Else" node for StarRating condition. We should define everything else node for each condition/operand
                // For StarRating, besides 5 stars and 4 stars, all the other hotels below 4 stars are belong to the node below
                var otherStarRatingsUnit = hotelGrouphelper.AddUnit(
                    parent: newRoot,
                    listing: new HotelListing { Operand = "StarRating", Attribute = null },
                    bidAmount: 0.35,
                    isNegative: false);

                var brandAUnit = hotelGrouphelper.AddUnit(
                    parent: starRating5SubDivision,
                    listing: new HotelListing { Operand = "Brand", Attribute = "Brand A" },
                    bidAmount: 0.35,
                    isNegative: false);
                                
                // If you won't bid on Brand B, set the helper method's bidAmount to '0' and isNegative to true. 
                // The helper method will create a NegativeAdGroupCriterion and apply the condition.
                
                var brandBUnit = hotelGrouphelper.AddUnit(
                    parent: starRating5SubDivision,
                    listing: new HotelListing { Operand = "Brand", Attribute = "Brand B" },
                    bidAmount: 0,
                    isNegative: true);

                var otherBrandsUnit = hotelGrouphelper.AddUnit(
                    parent: starRating5SubDivision,
                    listing: new HotelListing { Operand = "Brand", Attribute = null },
                    bidAmount: 0.35,
                    isNegative: false);
                
                OutputStatusMessage("-----\nApplyHotelGroupActions:");
                OutputStatusMessage("Applying hotel groups to the ad group...");
                applytHotelGroupActionsResponse = await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
                    criterionActions: hotelGrouphelper.HotelGroupActions);

                // To retrieve hotel groups after they have been applied, call GetAdGroupCriterionsByIds. 
                // The hotel group with ParentCriterionId set to null is the root node.

                OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
                hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    adGroupCriterionIds: null,
                    adGroupId: adGroupId,
                    criterionType: AdGroupCriterionType.HotelGroup,
                    null);

                // The hotel group tree now has 7 nodes. 

                //All hotels (Root Node)
                // |
                // +-- Star Rating 5 (StarRating)
                // |    |
                // |    +-- Brand A (Brand)
                // |    |    
                // |    +-- Brand B (Brand)
                // |    |        
                // |    +-- All other (Brand)    
                // |        
                // +-- Star Rating 4 (StarRating)
                // |   
                // +-- All other (StarRating)

                OutputStatusMessage("The hotel group tree now has 7 nodes: \n");
                OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);

                // Let's replace the Star Rating 4 (StarRating) node created above with an Star Rating 4 (StarRating) node that 
                // has children i.e. Brand C (Brand), Brand D (Brand) and All other (Brand) as follows: 

                //Star Rating 4 (StarRating)
                //|
                //+-- Brand C (Brand)
                //|
                //+-- Brand D (Brand)
                //|
                //+-- All other (Brand)

                hotelGrouphelper = new HotelGroupActionHelper(adGroupId);

                // To replace a node we must know its Id and its ParentCriterionId. In this case the parent of the node 
                // we are replacing is All hotels (Root Node), and was created at Index 1 of the previous ApplyHotelGroupActions call. 
                // The node that we are replacing is Star Rating 4 (StarRating), and was created at Index 3. 

                var rootId = applytHotelGroupActionsResponse.AdGroupCriterionIds[1];
                starRating4Unit.Id = applytHotelGroupActionsResponse.AdGroupCriterionIds[3];
                hotelGrouphelper.DeleteHotelGroup(starRating4Unit);

                var parent = new BiddableAdGroupCriterion() { Id = rootId };

                var newStarRating4Subdivision = hotelGrouphelper.AddSubdivision(
                    parent: parent,
                    listing: new HotelListing { Operand = "StarRating", Attribute = "4" }
                );

                var brandCUnit = hotelGrouphelper.AddUnit(
                    parent: newStarRating4Subdivision,
                    listing: new HotelListing { Operand = "Brand", Attribute = "Brand C" },
                    bidAmount: 0.35,
                    isNegative: false);

                var brandDUnit = hotelGrouphelper.AddUnit(
                    parent: newStarRating4Subdivision,
                    listing: new HotelListing { Operand = "Brand", Attribute = "Brand D" },
                    bidAmount: 0.35,
                    isNegative: false);

                var otherBrands = hotelGrouphelper.AddUnit(
                    parent: newStarRating4Subdivision,
                    listing: new HotelListing { Operand = "Brand", Attribute = null },
                    bidAmount: 0.35,
                    isNegative: false);

                OutputStatusMessage("-----\nApplyHotelGroupActions:");
                OutputStatusMessage(
                    "Updating the hotel group to refine Star Rating 4 (StarRating) with 3 child nodes..."
                );
                applytHotelGroupActionsResponse = await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
                    criterionActions: hotelGrouphelper.HotelGroupActions);

                OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
                hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    adGroupCriterionIds: null,
                    adGroupId: adGroupId,
                    criterionType: AdGroupCriterionType.HotelGroup,
                    null);

                // The hotel group tree now has 10 nodes, including the children of Star Rating 4 (StarRating):

                //All hotels (Root Node)
                // |
                // +-- Star Rating 5 (StarRating)
                // |    |
                // |    +-- Brand A (Brand)
                // |    |    
                // |    +-- Brand B (Brand)
                // |    |        
                // |    +-- All other (Brand)    
                // |        
                // +-- Star Rating 4 (StarRating)
                // |    |
                // |    +-- Brand C (Brand)
                // |    |    
                // |    +-- Brand D (Brand)
                // |    |        
                // |    +-- All other (Brand) 
                // |   
                // +-- All other (StarRating)

                OutputStatusMessage(
                    "The hotel group tree now has 10 nodes, including the children of Star Rating 4 (StarRating): \n"
                );
                OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);
               

                // Delete the campaign and everything it contains e.g., ad groups and ads.

                OutputStatusMessage("-----\nDeleteCampaigns:");
                await CampaignManagementExampleHelper.DeleteCampaignsAsync(
                    accountId: authorizationData.AccountId,
                    campaignIds: new[] { (long)campaignIds[0] });
                OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0]));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }

        /// <summary>
        /// Returns the root node of a tree. This operation assumes that a complete 
        /// hotel group tree is provided for one ad group. The node that has
        /// null ParentCriterionId is the root node.
        /// </summary>
        /// <param name="adGroupCriterions">The ad group criterions that contain 
        /// the hotel group tree.</param>
        /// <returns>The ad group criterion that represents the tree root node.</returns>
        private AdGroupCriterion GetRootNode(IList<AdGroupCriterion> adGroupCriterions)
        {
            AdGroupCriterion rootNode = null;
            foreach (AdGroupCriterion adGroupCriterion in adGroupCriterions)
            {
                if (((HotelGroup)(adGroupCriterion.Criterion)).ParentCriterionId == null)
                {
                    rootNode = adGroupCriterion;
                    break;
                }
            }
            return rootNode;
        }

        /// <summary>
        /// Helper class used to maintain a list of hotel group actions for an ad group.
        /// The list of hotel group actions can be passed to the ApplyHotelGroupActions service operation.
        /// </summary>
        private class HotelGroupActionHelper
        {
            /// <summary>
            /// Each criterion is associated with the same ad group.
            /// </summary>
            private long adGroupId;

            /// <summary>
            /// Each new hotel gorup will be assigned a temporary negative identifier, since it does not exist 
            /// and does not yet have a Microsoft Advertising system identifier. This identifier will be used as the ParentCriterionId 
            /// for any child node of the subdivision. 
            /// </summary>
            private long referenceId = -1;

            /// <summary>
            /// The list of hotel group actions that can be passed to the ApplyHotelGroupActions service operation.
            /// </summary>
            private List<AdGroupCriterionAction> hotelGroupActions = new List<AdGroupCriterionAction>();

            /// <summary>
            /// Initializes an instance of the HotelGroupActionHelper class.
            /// </summary>
            /// <param name="adGroupId">The ad group identifier associated with each criterion.</param>
            public HotelGroupActionHelper(long adGroupId)
            {
                this.adGroupId = adGroupId;
            }

            /// <summary>
            /// Returns the list of hotel group actions that can be passed to the ApplyHotelGroupActions service operation.
            /// </summary>
            public IList<AdGroupCriterionAction> HotelGroupActions
            {
                get
                {
                    return hotelGroupActions;
                }
            }

            /// <summary>
            /// Sets the Add action for a new BiddableAdGroupCriterion corresponding to the specified HotelGroup, 
            /// and adds it to the helper's list of HotelGroupActions. 
            /// </summary>
            /// <param name="parent">The parent of the hotel group subdivision that you want to add.</param>
            /// <param name="listing">The hotel listing for the new hotel group.</param>
            /// <returns>The ad group criterion that was added to the list of HotelGroupActions.</returns>
            public AdGroupCriterion AddSubdivision(
                AdGroupCriterion parent,
                HotelListing listing
                )
            {
                var biddableAdGroupCriterion = new BiddableAdGroupCriterion()
                {
                    Id = this.referenceId--,
                    Criterion = new HotelGroup()
                    {
                        ParentCriterionId = parent?.Id,
                        Listing = listing,
                        ListingType = HotelListingType.Subdivision
                    },
                    CriterionBid = null,
                    AdGroupId = this.adGroupId
                };

                var hotelGroupCriterionAction = new AdGroupCriterionAction()
                {
                    Action = ItemAction.Add,
                    AdGroupCriterion = biddableAdGroupCriterion
                };

                this.hotelGroupActions.Add(hotelGroupCriterionAction);

                return biddableAdGroupCriterion;
            }

            /// <summary>
            /// Sets the Add action for a new AdGroupCriterion corresponding to the specified HotelListing, 
            /// and adds it to the helper's list of HotelGroupAction. 
            /// </summary>
            /// <param name="parent">The parent of the hotel group unit that you want to add.</param>
            /// <param name="listing">The hotel listing filter for the new hotel group.</param>
            /// <param name="bidAmount">The bid amount for the new hotel group.</param>
            /// <param name="isNegative">Indicates whether or not to add a NegativeAdGroupCriterion. 
            /// The default value is false, in which case a BiddableAdGroupCriterion will be added.</param>
            /// <returns>The ad group criterion that was added to the list of HotelGroupActions.</returns>
            public AdGroupCriterion AddUnit(
                AdGroupCriterion parent,
                HotelListing listing,
                double bidAmount,
                bool isNegative
                )
            {
                AdGroupCriterion hotelGroupCriterion;

                if (isNegative)
                {
                    hotelGroupCriterion = new NegativeAdGroupCriterion();
                }
                else
                {
                    hotelGroupCriterion = new BiddableAdGroupCriterion()
                    {
                        CriterionBid = new RateBid()
                        {
                            RateAmount = new RateAmount { Amount = bidAmount } 
                        }
                    };
                }

                hotelGroupCriterion.AdGroupId = this.adGroupId;
                hotelGroupCriterion.Criterion = new HotelGroup
                {
                    Listing = listing,
                    ParentCriterionId = parent != null ? parent.Id : null,
                    ListingType = HotelListingType.Unit
                };
                var hotelGroupCriterionAction = new AdGroupCriterionAction()
                {
                    Action = ItemAction.Add,
                    AdGroupCriterion = hotelGroupCriterion
                };

                this.hotelGroupActions.Add(hotelGroupCriterionAction);

                return hotelGroupCriterion;
            }

            /// <summary>
            /// Sets the Delete action for the specified AdGroupCriterion, 
            /// and adds it to the helper's list of HotelGroupAction. 
            /// </summary>
            /// <param name="adGroupCriterion">The ad group criterion whose hotel group you want to delete.</param>
            public void DeleteHotelGroup(AdGroupCriterion adGroupCriterion)
            {
                adGroupCriterion.AdGroupId = this.adGroupId;

                var hotelGroupCriterionAction = new AdGroupCriterionAction()
                {
                    Action = ItemAction.Delete,
                    AdGroupCriterion = adGroupCriterion
                };

                this.hotelGroupActions.Add(hotelGroupCriterionAction);

                return;
            }

            /// <summary>
            /// Sets the Update action for the specified BiddableAdGroupCriterion, 
            /// and adds it to the helper's list of HotelGroupAction.  
            /// When working with hotel groups, you cannot update the Criterion (HotelListing). 
            /// To update a HotelListing, you must delete the existing node (DeleteHotelGroup) and 
            /// add a new one (AddUnit or AddSubdivision) during the same call to ApplyHotelGroupActions. 
            /// </summary>
            /// <param name="biddableAdGroupCriterion">The biddable ad group criterion (hotel group criterion) to update.</param>
            public void UpdateHotelGroup(BiddableAdGroupCriterion biddableAdGroupCriterion)
            {
                biddableAdGroupCriterion.AdGroupId = this.adGroupId;

                var hotelGroupCriterionAction = new AdGroupCriterionAction()
                {
                    Action = ItemAction.Update,
                    AdGroupCriterion = biddableAdGroupCriterion
                };

                this.hotelGroupActions.Add(hotelGroupCriterionAction);

                return;
            }
        }

        /// <summary>
        /// Outputs the list of hotel groups, formatted as a tree. 
        /// To ensure the complete tree is represented, you should first call GetAdGroupCriterionsByIds 
        /// where CriterionTypeFilter is HotelGroup, and pass the returned list of AdGroupCriterion to this method. 
        /// </summary>
        /// <param name="hotelGroupCriterions">The list of hotel group criterions (of type AdGroupCriterion) to output formatted as a tree.</param>
        private void OutputHotelGroupCriterions(IList<AdGroupCriterion> hotelGroupCriterions)
        {
            // Set up the tree for output

            Dictionary<long, List<AdGroupCriterion>> childBranches = new Dictionary<long, List<AdGroupCriterion>>();
            AdGroupCriterion treeRoot = null;

            foreach (var hotelGroupCriterion in hotelGroupCriterions)
            {
                HotelGroup hotelGroup = (HotelGroup)hotelGroupCriterion.Criterion;
                long? parentHotelGroupId = hotelGroup.ParentCriterionId;

                if (parentHotelGroupId != null)
                {
                    if (!childBranches.ContainsKey(parentHotelGroupId.Value))
                    {
                        childBranches[parentHotelGroupId.Value] = new List<AdGroupCriterion>();
                    }
                    childBranches[parentHotelGroupId.Value].Add(hotelGroupCriterion);
                }
                else
                {
                    treeRoot = hotelGroupCriterion;
                }
            }

            // Outputs the tree root node and any children recursively
            OutputHotelGroupTree(treeRoot, childBranches, 0);
        }

        /// <summary>
        /// Outputs the details of the specified hotel group node, 
        /// and passes any children to itself recursively.
        /// </summary>
        /// <param name="node">The node to output, whether a Subdivision or Unit.</param>
        /// <param name="childBranches">The child branches or nodes if any exist.</param>
        /// <param name="treeLevel">
        /// The number of descendents from the tree root node. 
        /// Used by this operation to format the tree structure output.
        /// </param>
        private void OutputHotelGroupTree(
            AdGroupCriterion node,
            Dictionary<long, List<AdGroupCriterion>> childBranches,
            int treeLevel)
        {
            OutputStatusMessage(string.Format("{0}{1}",
                "".PadLeft(treeLevel, '\t'),
                ((HotelGroup)(node.Criterion)).ListingType)
            );

            OutputStatusMessage(string.Format("{0}ParentCriterionId: {1}",
                "".PadLeft(treeLevel, '\t'),
                ((HotelGroup)(node.Criterion)).ParentCriterionId)
            );

            OutputStatusMessage(string.Format("{0}Id: {1}",
                "".PadLeft(treeLevel, '\t'),
                node.Id)
            );

            if (((HotelGroup)(node.Criterion)).ListingType == HotelListingType.Unit)
            {
                var biddableAdGroupCriterion = node as BiddableAdGroupCriterion;
                if (biddableAdGroupCriterion != null)
                {
                    OutputStatusMessage(string.Format("{0}Bid Amount: {1}",
                        "".PadLeft(treeLevel, '\t'),
                        ((RateBid)(biddableAdGroupCriterion.CriterionBid)).RateAmount.Amount)
                    );
                }
                else
                {
                    var negativeAdGroupCriterion = node as NegativeAdGroupCriterion;
                    if (negativeAdGroupCriterion != null)
                    {
                        OutputStatusMessage(string.Format("{0}Not Bidding on this Listing",
                            "".PadLeft(treeLevel, '\t'))
                        );
                    }
                }
            }

            string nullAttribute = ((HotelGroup)(node.Criterion)).ParentCriterionId != null ? "(All other)" : "(Tree Root)";
            OutputStatusMessage(string.Format("{0}Attribute: {1}",
                "".PadLeft(treeLevel, '\t'),
                ((HotelGroup)(node.Criterion)).Listing.Attribute ?? nullAttribute)
            );

            OutputStatusMessage(string.Format("{0}Operand: {1}\n",
                "".PadLeft(treeLevel, '\t'),
                ((HotelGroup)(node.Criterion)).Listing.Operand)
            );

            if (childBranches.ContainsKey((long)(node.Id)))
            {
                foreach (AdGroupCriterion childNode in childBranches[(long)(node.Id)])
                {
                    OutputHotelGroupTree(childNode, childBranches, treeLevel + 1);
                }
            }
        }

    }
}
package com.microsoft.bingads.examples.v13;

import com.microsoft.bingads.ServiceClient;
import com.microsoft.bingads.v13.campaignmanagement.*;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

// How to apply hotel group for Microsoft Hotel Campaigns.

public class HotelAds extends ExampleBase {

    private static ArrayOfAdGroupCriterionAction _hotelGroupActions = new ArrayOfAdGroupCriterionAction();
    private static long _referenceId = -1;

    public static void main(java.lang.String[] args) {

        // To set up hotel ads, we need to create at least a Campaign, an AdGroup under this campaign, and some Hotel Groups

        try
        {
            authorizationData = getAuthorizationData();

            CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                    authorizationData,
                    API_ENVIRONMENT,
                    ICampaignManagementService.class);

            // Create the hotel campaign. This is needed.

            ArrayOfNullableOflong campaignIds = createHotelCampaign();

            // Create the hotel ad group that will have the hotel groups. This is needed.

            ArrayOfNullableOflong adGroupIds = createHotelAdGroup(campaignIds);

            // Hotel groups are also needed.
            // Create and update the hotel groups.

            addAndUpdateSingleHotelCriterion(adGroupIds.getLongs().get(0));
            ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = addBranchAndLeafHotelCriterionsToRoot(adGroupIds.getLongs().get(0));

            long rootId = applyHotelGroupActionsResponse.getAdGroupCriterionIds().getLongs().get(1);
            long starRating4HotelGroupId = applyHotelGroupActionsResponse.getAdGroupCriterionIds().getLongs().get(3);
            updateBranchAndLeafHotelCriterionsForStarRating4(adGroupIds.getLongs().get(0), rootId, starRating4HotelGroupId);

            // Delete the campaign and everything it contains e.g., ad groups and ads.

            outputStatusMessage("-----\nDeleteCampaigns:");
            ArrayOflong deleteCampaignIds = new ArrayOflong();
            deleteCampaignIds.getLongs().add(campaignIds.getLongs().get(0));
            CampaignManagementExampleHelper.deleteCampaigns(
                    authorizationData.getAccountId(),
                    deleteCampaignIds);
            outputStatusMessage(String.format("Deleted CampaignId %d", deleteCampaignIds.getLongs().get(0)));
        }
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        }
    }

    // create hotel campaign

    static ArrayOfNullableOflong createHotelCampaign() throws Exception {
        Campaign campaign = new Campaign();

        // set campaign type to Hotel
        ArrayList<CampaignType> campaignTypes = new ArrayList<CampaignType>();
        campaignTypes.add(CampaignType.HOTEL);
        campaign.setCampaignType(campaignTypes);

        // Hotel campaign supports commission, percent cpc and manual cpc bidding scheme
        CommissionBiddingScheme biddingScheme = new CommissionBiddingScheme();
        biddingScheme.setCommissionRate(3.14);
        campaign.setBiddingScheme(biddingScheme);

        // for hotel campaign, language should be set to "All"
        ArrayOfstring languages = new ArrayOfstring();
        languages.getStrings().add("All");
        campaign.setLanguages(languages);

        // set other fields
        campaign.setBudgetType(BudgetLimitType.DAILY_BUDGET_STANDARD);
        campaign.setDailyBudget(50.00);
        campaign.setName("Everyone's Hotel " + System.currentTimeMillis());
        campaign.setTimeZone("PacificTimeUSCanadaTijuana");
        ArrayOfCampaign campaigns = new ArrayOfCampaign();
        campaigns.getCampaigns().add(campaign);

        outputStatusMessage("-----\nAddCampaigns:");
        AddCampaignsResponse addCampaignsResponse = CampaignManagementExampleHelper.addCampaigns(
                authorizationData.getAccountId(),
                campaigns);
        ArrayOfNullableOflong campaignIds = addCampaignsResponse.getCampaignIds();
        ArrayOfBatchError campaignErrors = addCampaignsResponse.getPartialErrors();
        outputStatusMessage("CampaignIds:");
        CampaignManagementExampleHelper.outputArrayOfNullableOflong(campaignIds);
        outputStatusMessage("PartialErrors:");
        CampaignManagementExampleHelper.outputArrayOfBatchError(campaignErrors);

        return campaignIds;
    }

    // create hotel ad group

    static ArrayOfNullableOflong createHotelAdGroup(ArrayOfNullableOflong campaignIds) throws Exception {
        AdGroup adGroup = new AdGroup();

        // ad group type should be set to "HotelAds"
        adGroup.setAdGroupType("HotelAds");

        // set ad group type, should be HotelAd or PropertyAd or specify both
        ArrayList<HotelAdGroupType> hotelAdGroupTypes = new ArrayList<HotelAdGroupType>();
        hotelAdGroupTypes.add(HotelAdGroupType.HOTEL_AD);
        HotelSetting hotelSetting = new HotelSetting();
        hotelSetting.setHotelAdGroupType(hotelAdGroupTypes);
        ArrayOfSetting adGroupSettings = new ArrayOfSetting();
        adGroupSettings.getSettings().add(hotelSetting);
        adGroup.setSettings(adGroupSettings);

        // set ad group level bid value
        // Here the campaign we created is using Commission bidding scheme, so we set CommissionRate
        // if the campaign bidding scheme is PercentCpc, please set PercentCpcBid
        // if the campaign bidding scheme is ManualCpc, please set CpcBid
        RateBid rateBid = getRateBid(5.6);
        adGroup.setCommissionRate(rateBid);

        // Hotel AdGroups will inherit Hotel Campaign setting, which enforces the “All” language.
        adGroup.setLanguage(null);

        adGroup.setName("Everyone's Hotel");
        adGroup.setStartDate(null);
        Calendar calendar = Calendar.getInstance();
        adGroup.setEndDate(new com.microsoft.bingads.v13.campaignmanagement.Date());
        adGroup.getEndDate().setDay(31);
        adGroup.getEndDate().setMonth(12);
        adGroup.getEndDate().setYear(calendar.get(Calendar.YEAR));

        ArrayOfAdGroup adGroups = new ArrayOfAdGroup();
        adGroups.getAdGroups().add(adGroup);

        outputStatusMessage("-----\nAddAdGroups:");
        // when we call addAdGroups method, an ad will be automatically created for hotel ad group
        AddAdGroupsResponse addAdGroupsResponse = CampaignManagementExampleHelper.addAdGroups(
                campaignIds.getLongs().get(0),
                adGroups,
                false);
        ArrayOfNullableOflong adGroupIds = addAdGroupsResponse.getAdGroupIds();
        ArrayOfBatchError adGroupErrors = addAdGroupsResponse.getPartialErrors();
        outputStatusMessage("AdGroupIds:");
        CampaignManagementExampleHelper.outputArrayOfNullableOflong(adGroupIds);
        outputStatusMessage("PartialErrors:");
        CampaignManagementExampleHelper.outputArrayOfBatchError(adGroupErrors);

        return adGroupIds;
    }

    // Create a hotel group tree with one single node (root node), then update bid of the node.

    static void addAndUpdateSingleHotelCriterion(long adGroupId) throws Exception
    {
        // Add a biddable criterion as the root.

        HotelListing rootHotelListing = new HotelListing();
        rootHotelListing.setAttribute(null);
        rootHotelListing.setOperand("All");

        AdGroupCriterion root = addHotelCriterion(
                adGroupId,
                null,
                rootHotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        outputStatusMessage("-----\nApplyHotelGroupActions:");
        outputStatusMessage("Applying a biddable criterion as the root...");
        ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
                _hotelGroupActions);
        CampaignManagementExampleHelper.outputArrayOfNullableOflong(applyHotelGroupActionsResponse.getAdGroupCriterionIds());
        CampaignManagementExampleHelper.outputArrayOfBatchError(applyHotelGroupActionsResponse.getPartialErrors());

        ArrayList<AdGroupCriterionType> criterionType = new ArrayList<AdGroupCriterionType>();
        criterionType.add(AdGroupCriterionType.HOTEL_GROUP);

        outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
        ArrayOfAdGroupCriterion adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
                null,
                adGroupId,
                criterionType,
                null).getAdGroupCriterions();

        outputStatusMessage("Printing the ad group's hotel group; contains only the tree root node");
        printHotelGroups(adGroupCriterions);

        // Update the bid from 0.35 to 0.40, of the root node that we just added.

        BiddableAdGroupCriterion updatedRoot = new BiddableAdGroupCriterion();
        updatedRoot.setId(applyHotelGroupActionsResponse.getAdGroupCriterionIds().getLongs().get(0));
        updatedRoot.setAdGroupId(adGroupId);
        updatedRoot.setCriterionBid(getRateBid(0.40));

        _hotelGroupActions.getAdGroupCriterionActions().clear();

        addAdGroupCriterionAction(updatedRoot, ItemAction.UPDATE);

        outputStatusMessage("-----\nApplyHotelGroupActions:");
        outputStatusMessage("Updating the bid for the tree root node...");
        applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
                _hotelGroupActions);

        outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
        adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
                null,
                adGroupId,
                criterionType,
                null).getAdGroupCriterions();

        outputStatusMessage("Updated the bid for the tree root node");
        printHotelGroups(adGroupCriterions);
    }

    // Add branch and leaf nodes to the hotel group tree and then update it.

    static ApplyHotelGroupActionsResponse addBranchAndLeafHotelCriterionsToRoot(long adGroupId) throws Exception
    {
        _hotelGroupActions.getAdGroupCriterionActions().clear();

        ArrayList<AdGroupCriterionType> criterionType = new ArrayList<AdGroupCriterionType>();
        criterionType.add(AdGroupCriterionType.HOTEL_GROUP);
        outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
        ArrayOfAdGroupCriterion adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
                null,
                adGroupId,
                criterionType,
                null).getAdGroupCriterions();

        // If we want to update the tree structure at a node, we must delete existing node and then add a new equivalent node,
        // Here we modify the root node and add some new branches and leafs, so we delete it first.
        AdGroupCriterion existingRoot = getRootHotelCriterion(adGroupCriterions);
        if (existingRoot != null)
        {
            addAdGroupCriterionAction(existingRoot, ItemAction.DELETE);
        }

        // Add the equivalent new root node
        HotelListing newRootHotelListing = new HotelListing();
        newRootHotelListing.setAttribute(null);
        newRootHotelListing.setOperand("All");
        AdGroupCriterion newRoot = addHotelCriterion(
                adGroupId,
                null,
                newRootHotelListing,
                HotelListingType.SUBDIVISION,
                null,
                false);

        HotelListing starRating5HotelListing = new HotelListing();
        starRating5HotelListing.setAttribute("5");
        starRating5HotelListing.setOperand("StarRating");
        AdGroupCriterion starRating5SubDivision = addHotelCriterion(
                adGroupId,
                newRoot,
                starRating5HotelListing,
                HotelListingType.SUBDIVISION,
                null,
                false);

        HotelListing starRating4HotelListing = new HotelListing();
        starRating4HotelListing.setAttribute("4");
        starRating4HotelListing.setOperand("StarRating");
        AdGroupCriterion starRating4Unit = addHotelCriterion(
                adGroupId,
                newRoot,
                starRating4HotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        // "Everything Else" node for StarRating condition. We should define everything else node for each condition/operand
        // For StarRating, besides 5 stars and 4 stars, all the other hotels below 4 stars are belong to the node below
        HotelListing otherStarRatingsHotelListing = new HotelListing();
        otherStarRatingsHotelListing.setAttribute(null);
        otherStarRatingsHotelListing.setOperand("StarRating");
        AdGroupCriterion otherStarRatingsUnit = addHotelCriterion(
                adGroupId,
                newRoot,
                otherStarRatingsHotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        HotelListing brandAHotelListing = new HotelListing();
        brandAHotelListing.setAttribute("Brand A");
        brandAHotelListing.setOperand("Brand");
        AdGroupCriterion brandAUnit = addHotelCriterion(
                adGroupId,
                starRating5SubDivision,
                brandAHotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        HotelListing brandBHotelListing = new HotelListing();
        brandBHotelListing.setAttribute("Brand B");
        brandBHotelListing.setOperand("Brand");
        AdGroupCriterion brandBUnit = addHotelCriterion(
                adGroupId,
                starRating5SubDivision,
                brandBHotelListing,
                HotelListingType.UNIT,
                null,
                true);

        // everything else node for Brand condition
        HotelListing otherBrandsHotelListing = new HotelListing();
        otherBrandsHotelListing.setAttribute(null);
        otherBrandsHotelListing.setOperand("Brand");
        AdGroupCriterion otherBrandsUnit = addHotelCriterion(
                adGroupId,
                starRating5SubDivision,
                otherBrandsHotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        outputStatusMessage("-----\nApplyHotelGroupActions:");
        outputStatusMessage("Applying hotel groups to the ad group...");
        ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
                _hotelGroupActions);

        outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
        adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
                null,
                adGroupId,
                criterionType,
                null).getAdGroupCriterions();

        outputStatusMessage("The hotel group tree now has 7 nodes");
        printHotelGroups(adGroupCriterions);

        return applyHotelGroupActionsResponse;
    }

    // update starRating 4 node to have more leaf hotel groups

    static void updateBranchAndLeafHotelCriterionsForStarRating4(long adGroupId, long rootId, long existingStarRating4CriterionId) throws Exception
    {
        _hotelGroupActions.getAdGroupCriterionActions().clear();

        AdGroupCriterion starRating4Criterion = new BiddableAdGroupCriterion();
        starRating4Criterion.setId(existingStarRating4CriterionId);
        starRating4Criterion.setAdGroupId(adGroupId);
        addAdGroupCriterionAction(starRating4Criterion, ItemAction.DELETE);

        BiddableAdGroupCriterion parent = new BiddableAdGroupCriterion();
        parent.setId(rootId);

        HotelListing newStarRating4HotelListing = new HotelListing();
        newStarRating4HotelListing.setAttribute("4");
        newStarRating4HotelListing.setOperand("StarRating");

        AdGroupCriterion newStarRating4Subdivision = addHotelCriterion(
                adGroupId,
                parent,
                newStarRating4HotelListing,
                HotelListingType.SUBDIVISION, // it's not leave node anymore, the type should set to SUBDIVISION
                null,
                false);

        // Add leafs of "Brand C", "Brand D" and other brands, to the star rating 4 branch.

        HotelListing brandCHotelListing = new HotelListing();
        brandCHotelListing.setAttribute("Brand C");
        brandCHotelListing.setOperand("Brand");
        AdGroupCriterion brandCUnit = addHotelCriterion(
                adGroupId,
                newStarRating4Subdivision,
                brandCHotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        HotelListing brandDHotelListing = new HotelListing();
        brandDHotelListing.setAttribute("Brand D");
        brandDHotelListing.setOperand("Brand");
        AdGroupCriterion brandDUnit = addHotelCriterion(
                adGroupId,
                newStarRating4Subdivision,
                brandDHotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        HotelListing otherBrandsHotelListing = new HotelListing();
        otherBrandsHotelListing.setAttribute(null);
        otherBrandsHotelListing.setOperand("Brand");
        AdGroupCriterion otherBrandsUnit = addHotelCriterion(
                adGroupId,
                newStarRating4Subdivision,
                otherBrandsHotelListing,
                HotelListingType.UNIT,
                getRateBid(0.35),
                false);

        outputStatusMessage("-----\nApplyHotelGroupActions:");
        outputStatusMessage("Updating the star rating 4 hotel group...");
        ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
                _hotelGroupActions);

        ArrayList<AdGroupCriterionType> criterionType = new ArrayList<AdGroupCriterionType>();
        criterionType.add(AdGroupCriterionType.HOTEL_GROUP);
        outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
        ArrayOfAdGroupCriterion adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
                null,
                adGroupId,
                criterionType,
                null).getAdGroupCriterions();

        outputStatusMessage("The hotel group tree now has 10 nodes");
        printHotelGroups(adGroupCriterions);
    }

    // Get the root hotel group node.

    static AdGroupCriterion getRootHotelCriterion(ArrayOfAdGroupCriterion adGroupCriterions)
    {
        AdGroupCriterion rootNode = null;

        for (AdGroupCriterion adGroupCriterion : adGroupCriterions.getAdGroupCriterions())
        {
            if (((HotelGroup)adGroupCriterion.getCriterion()).getParentCriterionId() == null)
            {
                rootNode = adGroupCriterion;
                break;
            }
        }

        return rootNode;
    }

    // Get a Rate bid object with the specified bid amount.

    static RateBid getRateBid(final double bidAmount)
    {
        RateAmount rateAmount = new RateAmount();
        rateAmount.setAmount(bidAmount);
        RateBid rateBid = new RateBid();
        rateBid.setRateAmount(rateAmount);

        return rateBid;
    }

    // Add a criterion action to the list of actions.

    static void addAdGroupCriterionAction(final AdGroupCriterion CRITERION, final ItemAction ITEM_ACTION)
    {
        AdGroupCriterionAction hotelGroupAction = new AdGroupCriterionAction();
        hotelGroupAction.setAction(ITEM_ACTION);
        hotelGroupAction.setAdGroupCriterion(CRITERION);

        _hotelGroupActions.getAdGroupCriterionActions().add(hotelGroupAction);
    }

    // Add either a negative or biddable hotel group criterion.
    // To call Microsoft Ads API, we need to wrap hotel group to AdGroupCriterion

    static AdGroupCriterion addHotelCriterion(
            long adGroupId,
            AdGroupCriterion parent,
            HotelListing hotelListing,
            HotelListingType hotelListingType,
            RateBid bid,
            Boolean isNegative)
    {
        AdGroupCriterion adGroupCriterion = null;

        if (isNegative)
        {
            adGroupCriterion = new NegativeAdGroupCriterion();
        }
        else
        {
            adGroupCriterion = new BiddableAdGroupCriterion();
            ((BiddableAdGroupCriterion)adGroupCriterion).setCriterionBid(bid);
        }

        adGroupCriterion.setAdGroupId(adGroupId);

        HotelGroup hotelGroup = new HotelGroup();
        hotelGroup.setListing(hotelListing);
        hotelGroup.setParentCriterionId((parent != null) ? parent.getId() : null);

        if (hotelListingType == HotelListingType.SUBDIVISION)
        {
            hotelGroup.setListingType(HotelListingType.SUBDIVISION);  // Branch
            adGroupCriterion.setId(_referenceId--);
        }
        else
        {
            hotelGroup.setListingType(HotelListingType.UNIT);;  // Leaf
        }

        adGroupCriterion.setCriterion(hotelGroup);

        addAdGroupCriterionAction(adGroupCriterion, ItemAction.ADD);

        return adGroupCriterion;
    }

    // Print the hotel group

    static void printHotelGroups(ArrayOfAdGroupCriterion adGroupCriterions)
    {
        Map<Long, ArrayList<AdGroupCriterion>> childBranches = new HashMap<Long, ArrayList<AdGroupCriterion>>();
        AdGroupCriterion treeRoot = null;

        for (AdGroupCriterion adGroupCriterion : adGroupCriterions.getAdGroupCriterions())
        {
            HotelGroup hotelGroup = (HotelGroup)adGroupCriterion.getCriterion();
            childBranches.put(adGroupCriterion.getId(), new ArrayList<AdGroupCriterion>());

            if (hotelGroup.getParentCriterionId() != null)
            {
                childBranches.get(hotelGroup.getParentCriterionId()).add(adGroupCriterion);
            }
            else
            {
                treeRoot = adGroupCriterion;
            }
        }

        printHotelGroupTree(treeRoot, childBranches, 0);
    }

    // Print the hotel group tree.

    static void printHotelGroupTree(
            AdGroupCriterion node,
            Map<Long, ArrayList<AdGroupCriterion>> childBranches,
            int treeLevel)
    {
        HotelGroup criterion = (HotelGroup) node.getCriterion();

        outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s\n",
                "",
                criterion.getListingType()));

        outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%d\n",
                "",
                "ParentCriterionId: ",
                criterion.getParentCriterionId()));

        outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%d\n",
                "",
                "Id: ",
                node.getId()));

        if (criterion.getListingType() == HotelListingType.UNIT)
        {
            if (node instanceof BiddableAdGroupCriterion)
            {
                outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%.2f\n",
                        "",
                        "Bid amount: ",
                        ((RateBid)((BiddableAdGroupCriterion)node).getCriterionBid()).getRateAmount().getAmount()));

            }
            else
            {
                if (node instanceof NegativeAdGroupCriterion)
                {
                    outputStatusMessage(String.format("%" + treeLevel * 4 + "s%s\n",
                            "",
                            "Not bidding on this listing"));
                }
            }
        }

        String nullAttribute = (criterion.getParentCriterionId() != null) ? "(All Others)" : "(Tree Root)";

        outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%s\n",
                "",
                "Attribute: ",
                (criterion.getListing().getAttribute() == null) ? nullAttribute : criterion.getListing().getAttribute()));

        outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%s\n",
                "",
                "Listing: ",
                criterion.getListing().getOperand()));

        for (AdGroupCriterion childNode : childBranches.get(node.getId()))
        {
            printHotelGroupTree(childNode, childBranches, treeLevel + 1);
        }
    }
}

See Also

Introdução à API de Anúncios do Bing