From 553b32ad2dbe8c2749274d998e79268ddb27ea28 Mon Sep 17 00:00:00 2001 From: mohnoor94 Date: Wed, 14 May 2025 17:53:15 +0300 Subject: [PATCH 1/2] refactor: format code for consistency and readability across scenario classes Signed-off-by: mohnoor94 --- examples/pom.xml | 19 +- .../sdk/xap/examples/XapSdkDemoTestRun.java | 71 +-- .../xap/examples/scenarios/XapScenario.java | 29 +- .../ActivityDetailsQuickStartScenario.java | 497 ++++++++-------- .../ActivityListingsQuickStartScenario.java | 230 ++++---- .../car/CarDetailsQuickStartScenario.java | 441 +++++++------- .../car/CarListingsQuickStartScenario.java | 267 ++++----- .../flight/FlightListingExample.java | 483 ++++++--------- ...ailabilityCalendarsQuickStartScenario.java | 119 ++-- .../HotelIdsSearchEndToEndScenario.java | 413 ++++++------- .../lodging/ListingsQuickStartScenario.java | 276 ++++----- .../lodging/QuotesQuickStartScenario.java | 201 +++---- .../VrboPropertySearchEndToEndScenario.java | 553 ++++++++---------- .../scenarios/lodging/VrboScenario.java | 26 +- 14 files changed, 1680 insertions(+), 1945 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 306203c62..3d2108626 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -31,7 +31,7 @@ 1.8 1.8 UTF-8 - 1.2.0 + 1.2.9-SNAPSHOT 5.0.0 @@ -76,23 +76,6 @@ - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.6.0 - - google_checks.xml - true - warning - - - - - check - - - - com.mycila license-maven-plugin diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/XapSdkDemoTestRun.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/XapSdkDemoTestRun.java index bf97539ef..b3f1bd251 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/XapSdkDemoTestRun.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/XapSdkDemoTestRun.java @@ -32,60 +32,47 @@ * For reference, see the individual scenarios in the scenarios package. */ public class XapSdkDemoTestRun { - private static final Logger logger = LoggerFactory.getLogger(XapSdkDemoTestRun.class); + private static final Logger logger = LoggerFactory.getLogger(XapSdkDemoTestRun.class); - /** - * Main method. - */ - public static void main(String[] args) { + /** + * Main method. + */ + public static void main(String[] args) { - logger.info( - "============================== Running Lodging Scenarios ============================="); + logger.info("============================== Running Lodging Scenarios ============================="); - AvailabilityCalendarsQuickStartScenario availabilityCalendarsQuickStartScenario = - new AvailabilityCalendarsQuickStartScenario(); - availabilityCalendarsQuickStartScenario.run(); + AvailabilityCalendarsQuickStartScenario availabilityCalendarsQuickStartScenario = new AvailabilityCalendarsQuickStartScenario(); + availabilityCalendarsQuickStartScenario.run(); - ListingsQuickStartScenario listingsQuickStartScenario = new ListingsQuickStartScenario(); - listingsQuickStartScenario.run(); + ListingsQuickStartScenario listingsQuickStartScenario = new ListingsQuickStartScenario(); + listingsQuickStartScenario.run(); - HotelIdsSearchEndToEndScenario hotelIdsSearchEndToEndScenario = - new HotelIdsSearchEndToEndScenario(); - hotelIdsSearchEndToEndScenario.run(); + HotelIdsSearchEndToEndScenario hotelIdsSearchEndToEndScenario = new HotelIdsSearchEndToEndScenario(); + hotelIdsSearchEndToEndScenario.run(); - VrboPropertySearchEndToEndScenario vrboPropertySearchEndToEndScenario = - new VrboPropertySearchEndToEndScenario(); - vrboPropertySearchEndToEndScenario.run(); + VrboPropertySearchEndToEndScenario vrboPropertySearchEndToEndScenario = new VrboPropertySearchEndToEndScenario(); + vrboPropertySearchEndToEndScenario.run(); - logger.info( - "=============================== End of Lodging Scenarios =============================="); + logger.info("=============================== End of Lodging Scenarios =============================="); + logger.info("============================== Running Car Scenarios ============================="); - logger.info( - "============================== Running Car Scenarios ============================="); - CarListingsQuickStartScenario carListingsQuickStartScenario = - new CarListingsQuickStartScenario(); + CarListingsQuickStartScenario carListingsQuickStartScenario = new CarListingsQuickStartScenario(); + carListingsQuickStartScenario.run(); - carListingsQuickStartScenario.run(); + CarDetailsQuickStartScenario carDetailsQuickStartScenario = new CarDetailsQuickStartScenario(); + carDetailsQuickStartScenario.run(); - CarDetailsQuickStartScenario carDetailsQuickStartScenario = new CarDetailsQuickStartScenario(); - carDetailsQuickStartScenario.run(); - logger.info( - "=============================== End of Car Scenarios =============================="); + logger.info("=============================== End of Car Scenarios =============================="); + logger.info("============================== Running Activity Scenarios ============================="); - logger.info( - "============================== Running Activity Scenarios ============================="); - ActivityListingsQuickStartScenario activityListingsQuickStartScenario = - new ActivityListingsQuickStartScenario(); + ActivityListingsQuickStartScenario activityListingsQuickStartScenario = new ActivityListingsQuickStartScenario(); + activityListingsQuickStartScenario.run(); - activityListingsQuickStartScenario.run(); + ActivityDetailsQuickStartScenario activityDetailsQuickStartScenario = new ActivityDetailsQuickStartScenario(); + activityDetailsQuickStartScenario.run(); - ActivityDetailsQuickStartScenario activityDetailsQuickStartScenario = - new ActivityDetailsQuickStartScenario(); - activityDetailsQuickStartScenario.run(); - logger.info( - "=============================== End of Activity Scenarios =============================="); + logger.info("=============================== End of Activity Scenarios =============================="); - - System.exit(0); - } + System.exit(0); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/XapScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/XapScenario.java index 3856f5f7f..9dd6976f0 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/XapScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/XapScenario.java @@ -22,23 +22,18 @@ * Interface for scenarios. */ public interface XapScenario { + String PARTNER_TRANSACTION_ID = "xap-java-sdk-examples"; - String PARTNER_TRANSACTION_ID = "xap-java-sdk-examples"; + void run(); - void run(); - - /** - * Create a client. - * - * @return XapClient - */ - default XapClient createClient() { - String key = System.getProperty("com.expediagroup.xapjavasdk.apikey"); - String secret = System.getProperty("com.expediagroup.xapjavasdk.apisecret"); - return XapClient - .builder() - .key(key) - .secret(secret) - .build(); - } + /** + * Create a client. + * + * @return XapClient + */ + default XapClient createClient() { + String key = System.getProperty("com.expediagroup.xapjavasdk.apikey"); + String secret = System.getProperty("com.expediagroup.xapjavasdk.apisecret"); + return XapClient.builder().key(key).secret(secret).build(); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityDetailsQuickStartScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityDetailsQuickStartScenario.java index a526f2909..a20840fa3 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityDetailsQuickStartScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityDetailsQuickStartScenario.java @@ -30,8 +30,10 @@ import com.expediagroup.sdk.xap.operations.GetActivityDetailsOperationParams; import com.expediagroup.sdk.xap.operations.GetActivityListingsOperation; import com.expediagroup.sdk.xap.operations.GetActivityListingsOperationParams; + import java.time.LocalDate; import java.util.Arrays; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,303 +42,302 @@ * This example demonstrates how to get Activity details. */ public class ActivityDetailsQuickStartScenario implements XapScenario { + private static final Logger LOGGER = + LoggerFactory.getLogger(ActivityDetailsQuickStartScenario.class); - private static final Logger LOGGER = - LoggerFactory.getLogger(ActivityDetailsQuickStartScenario.class); - - public static void main(String[] args) { - new ActivityDetailsQuickStartScenario().run(); - System.exit(0); - } - - @Override - public void run() { - // This example demonstrates how to obtain the Activity Details Deep Link from the Activity - // Listings. - // For information on using activity search, refer to Activity ListingsQuickStartExample. - LOGGER.info( - "========================== Running DetailsQuickStartScenario ========================="); - - // Execute the operation and get the ActivityListingsRespons - XapClient xapClient = createClient(); - - GetActivityListingsOperationParams getActivityListingsOperationParams = - GetActivityListingsOperationParams.builder() - .partnerTransactionId(XapScenario.PARTNER_TRANSACTION_ID).location("seattle") - .links(Arrays.asList(GetActivityListingsOperationParams.Links.AD)) - .startDate(LocalDate.now().plusDays(5)).endDate(LocalDate.now().plusDays(8)) - .locale("en_US").build(); - - Response listingsResponse = - xapClient.execute(new GetActivityListingsOperation(getActivityListingsOperationParams)); - - if (listingsResponse == null || listingsResponse.getData() == null - || listingsResponse.getData().getActivities() == null) { - throw new IllegalStateException("No activity details found."); + public static void main(String[] args) { + new ActivityDetailsQuickStartScenario().run(); + System.exit(0); } + @Override + public void run() { + // This example demonstrates how to obtain the Activity Details Deep Link from the Activity + // Listings. + // For information on using activity search, refer to Activity ListingsQuickStartExample. + LOGGER.info( + "========================== Running DetailsQuickStartScenario ========================="); + + // Execute the operation and get the ActivityListingsRespons + XapClient xapClient = createClient(); + + GetActivityListingsOperationParams getActivityListingsOperationParams = + GetActivityListingsOperationParams.builder() + .partnerTransactionId(XapScenario.PARTNER_TRANSACTION_ID).location("seattle") + .links(Arrays.asList(GetActivityListingsOperationParams.Links.AD)) + .startDate(LocalDate.now().plusDays(5)).endDate(LocalDate.now().plusDays(8)) + .locale("en_US").build(); + + Response listingsResponse = + xapClient.execute(new GetActivityListingsOperation(getActivityListingsOperationParams)); + + if (listingsResponse == null || listingsResponse.getData() == null + || listingsResponse.getData().getActivities() == null) { + throw new IllegalStateException("No activity details found."); + } - Activity listingsActivity = listingsResponse.getData().getActivities().get(0); - - // Get offerToken from APIDetails link url - String adLink = listingsActivity.getLinks().get("ApiDetails").getHref(); - String offerToken = adLink.substring(adLink.lastIndexOf("/") + 1); - - // Execute the operation and get the ActivityDetailsResponse - GetActivityDetailsOperationParams getActivityDetailsOperationParams = - GetActivityDetailsOperationParams.builder() - .partnerTransactionId(XapScenario.PARTNER_TRANSACTION_ID).offerToken(offerToken) - .build(); - Response detalisResponse = - xapClient.execute(new GetActivityDetailsOperation(getActivityDetailsOperationParams)); + Activity listingsActivity = listingsResponse.getData().getActivities().get(0); + // Get offerToken from APIDetails link url + String adLink = listingsActivity.getLinks().get("ApiDetails").getHref(); + String offerToken = adLink.substring(adLink.lastIndexOf("/") + 1); - LOGGER.info( - "======================== GetActivityDetailsOperation Executed ========================"); + // Execute the operation and get the ActivityDetailsResponse + GetActivityDetailsOperationParams getActivityDetailsOperationParams = + GetActivityDetailsOperationParams.builder() + .partnerTransactionId(XapScenario.PARTNER_TRANSACTION_ID).offerToken(offerToken) + .build(); - if (detalisResponse == null || detalisResponse.getData() == null - || detalisResponse.getData().getActivityDetails() == null - || detalisResponse.getData().getActivityDetails() == null) { - throw new IllegalStateException("No activity details found."); - } + Response detalisResponse = + xapClient.execute(new GetActivityDetailsOperation(getActivityDetailsOperationParams)); - // The ActivityListingsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", detalisResponse.getData().getTransactionId()); + LOGGER.info( + "======================== GetActivityDetailsOperation Executed ========================"); - LOGGER.info( - "============================ Activity details Start ============================"); - Activity activity = detalisResponse.getData().getActivityDetails(); - // To get the activity title - if (StringUtils.isNotEmpty(activity.getTitle())) { - LOGGER.info("Activity title: {}", activity.getTitle()); - } - // To get the activity description - if (StringUtils.isNotEmpty(activity.getDescription())) { - LOGGER.info("Activity description: {}", activity.getDescription()); - } + if (detalisResponse == null || detalisResponse.getData() == null + || detalisResponse.getData().getActivityDetails() == null + || detalisResponse.getData().getActivityDetails() == null) { + throw new IllegalStateException("No activity details found."); + } - // To get the activity duration - if (StringUtils.isNotEmpty(activity.getDuration())) { - LOGGER.info("Activity duration: {}", activity.getDuration()); - } + // The ActivityListingsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", detalisResponse.getData().getTransactionId()); - // To get the activity image - if (activity.getMedia() != null) { - LOGGER.info( - "============================ Activity Images ============================ "); - activity.getMedia().forEach(image -> { - LOGGER.info("Image title: {}", image.getTitle()); - LOGGER.info("Image url: {}", image.getUrl()); - }); - LOGGER.info( - "============================ Activity Images ============================ "); - } + LOGGER.info( + "============================ Activity details Start ============================"); + Activity activity = detalisResponse.getData().getActivityDetails(); + // To get the activity title + if (StringUtils.isNotEmpty(activity.getTitle())) { + LOGGER.info("Activity title: {}", activity.getTitle()); + } + // To get the activity description + if (StringUtils.isNotEmpty(activity.getDescription())) { + LOGGER.info("Activity description: {}", activity.getDescription()); + } - // To get the activity free cancellation available - LOGGER.info("Activity free cancellation available: {}", activity.getFreeCancellation()); + // To get the activity duration + if (StringUtils.isNotEmpty(activity.getDuration())) { + LOGGER.info("Activity duration: {}", activity.getDuration()); + } - // To get the activity price - if (activity.getPrice() != null) { - LOGGER.info("Activity price currency: {}", activity.getPrice().getTotalRate().getCurrency()); - LOGGER.info("Activity price value: {}", activity.getPrice().getTotalRate().getValue()); - } + // To get the activity image + if (activity.getMedia() != null) { + LOGGER.info( + "============================ Activity Images ============================ "); + activity.getMedia().forEach(image -> { + LOGGER.info("Image title: {}", image.getTitle()); + LOGGER.info("Image url: {}", image.getUrl()); + }); + LOGGER.info( + "============================ Activity Images ============================ "); + } - // To get the activity redemption - if (activity.getRedemption() != null) { - LOGGER.info( - "============================ Activity Redemption ============================ "); - if (StringUtils.isNotEmpty(activity.getDuration())) { - LOGGER.info("Activity Redemption type: {}", activity.getRedemption().getType()); - } - - if (activity.getRedemption().getRedemptionLocations() != null) { - activity.getRedemption().getRedemptionLocations().forEach(location -> { - printLocation(location); - }); - } - LOGGER.info( - "============================ Activity Redemption ============================ "); - } + // To get the activity free cancellation available + LOGGER.info("Activity free cancellation available: {}", activity.getFreeCancellation()); - // To get the activity location - if (activity.getActivityLocations() != null) { - activity.getActivityLocations().forEach(location -> { - printLocation(location); - }); - } + // To get the activity price + if (activity.getPrice() != null) { + LOGGER.info("Activity price currency: {}", activity.getPrice().getTotalRate().getCurrency()); + LOGGER.info("Activity price value: {}", activity.getPrice().getTotalRate().getValue()); + } - // To get the activity cancellation policy - printCancellationPolicy(activity.getCancellationPolicy()); + // To get the activity redemption + if (activity.getRedemption() != null) { + LOGGER.info( + "============================ Activity Redemption ============================ "); + if (StringUtils.isNotEmpty(activity.getDuration())) { + LOGGER.info("Activity Redemption type: {}", activity.getRedemption().getType()); + } - // To get activity highlight - if (activity.getHighlights() != null) { - LOGGER.info( - "============================ Activity Highlight ============================ "); - activity.getHighlights().forEach(highlight -> { - LOGGER.info(highlight); - }); - LOGGER.info( - "============================ Activity Highlight ============================ "); - } + if (activity.getRedemption().getRedemptionLocations() != null) { + activity.getRedemption().getRedemptionLocations().forEach(location -> { + printLocation(location); + }); + } + LOGGER.info( + "============================ Activity Redemption ============================ "); + } - // To get activity inclusions - if (activity.getInclusions() != null) { - LOGGER.info( - "============================ Activity Inclusions ============================ "); - activity.getInclusions().forEach(inclusion -> { - LOGGER.info(inclusion); - }); - LOGGER.info( - "============================ Activity Inclusions ============================ "); - } + // To get the activity location + if (activity.getActivityLocations() != null) { + activity.getActivityLocations().forEach(location -> { + printLocation(location); + }); + } - // To get activity exclusion - if (activity.getExclusions() != null) { - LOGGER.info( - "============================ Activity Exclusions ============================ "); - activity.getExclusions().forEach(exclusion -> { - LOGGER.info(exclusion); - }); - LOGGER.info( - "============================ Activity Exclusions ============================ "); - } - // To get activity knowBeforeYouBook - if (activity.getKnowBeforeYouBook() != null) { - LOGGER.info( - "============================ Activity KnowBeforeYouBook ============================ "); - activity.getKnowBeforeYouBook().forEach(knowBeforeYouBook -> { - LOGGER.info(knowBeforeYouBook); - }); - LOGGER.info( - "============================ Activity KnowBeforeYouBook ============================ "); - } + // To get the activity cancellation policy + printCancellationPolicy(activity.getCancellationPolicy()); - // To get activity offers - if (activity.getOffers() != null) { - LOGGER.info( - "============================ Activity Offers ============================ "); - activity.getOffers().forEach(offer -> { - // To get the Offer title - if (StringUtils.isNotEmpty(offer.getTitle())) { - LOGGER.info("Offer title: {}", offer.getTitle()); + // To get activity highlight + if (activity.getHighlights() != null) { + LOGGER.info( + "============================ Activity Highlight ============================ "); + activity.getHighlights().forEach(highlight -> { + LOGGER.info(highlight); + }); + LOGGER.info( + "============================ Activity Highlight ============================ "); } - // To get the Offer description - if (StringUtils.isNotEmpty(offer.getDescription())) { - LOGGER.info("Offer description: {}", offer.getDescription()); + + // To get activity inclusions + if (activity.getInclusions() != null) { + LOGGER.info( + "============================ Activity Inclusions ============================ "); + activity.getInclusions().forEach(inclusion -> { + LOGGER.info(inclusion); + }); + LOGGER.info( + "============================ Activity Inclusions ============================ "); } - // To get the Offer duration - if (StringUtils.isNotEmpty(offer.getDuration())) { - LOGGER.info("Offer duration: {}", offer.getDuration()); + // To get activity exclusion + if (activity.getExclusions() != null) { + LOGGER.info( + "============================ Activity Exclusions ============================ "); + activity.getExclusions().forEach(exclusion -> { + LOGGER.info(exclusion); + }); + LOGGER.info( + "============================ Activity Exclusions ============================ "); } - // To get the offer price - if (offer.getOfferPrice() != null) { - LOGGER.info("Offer price currency: {}", - offer.getOfferPrice().getTotalRate().getCurrency()); - LOGGER.info("Offer price value: {}", offer.getOfferPrice().getTotalRate().getValue()); + // To get activity knowBeforeYouBook + if (activity.getKnowBeforeYouBook() != null) { + LOGGER.info( + "============================ Activity KnowBeforeYouBook ============================ "); + activity.getKnowBeforeYouBook().forEach(knowBeforeYouBook -> { + LOGGER.info(knowBeforeYouBook); + }); + LOGGER.info( + "============================ Activity KnowBeforeYouBook ============================ "); } - // To get the Offer availableTimeSlots - if (offer.getAvailableTimeSlots() != null) { - LOGGER.info( - "========================= Activity AvailableTimeSlots ========================="); - - offer.getAvailableTimeSlots().forEach(availableTimeSlot -> { - LOGGER.info("DateTime: {}", availableTimeSlot.getDateTime()); - LOGGER.info("AllDayActivity: {}", availableTimeSlot.getAllDayActivity()); - printCancellationPolicy(availableTimeSlot.getCancellationPolicy()); - - // To get ticket info - if (availableTimeSlot.getTickets() != null) { - LOGGER.info( - "============================ Activity ticket ============================= "); - availableTimeSlot.getTickets().forEach(ticket -> { - LOGGER.info("Code: {}", ticket.getCode()); - LOGGER.info("Ticket price currency: {}", - ticket.getTicketPrice().getTotalRate().getCurrency()); - LOGGER.info("Ticket price value: {}", - ticket.getTicketPrice().getTotalRate().getValue()); - - }); - LOGGER.info( - "============================ Activity ticket ============================ "); - } + // To get activity offers + if (activity.getOffers() != null) { + LOGGER.info( + "============================ Activity Offers ============================ "); + activity.getOffers().forEach(offer -> { + // To get the Offer title + if (StringUtils.isNotEmpty(offer.getTitle())) { + LOGGER.info("Offer title: {}", offer.getTitle()); + } + // To get the Offer description + if (StringUtils.isNotEmpty(offer.getDescription())) { + LOGGER.info("Offer description: {}", offer.getDescription()); + } + + // To get the Offer duration + if (StringUtils.isNotEmpty(offer.getDuration())) { + LOGGER.info("Offer duration: {}", offer.getDuration()); + } + + // To get the offer price + if (offer.getOfferPrice() != null) { + LOGGER.info("Offer price currency: {}", + offer.getOfferPrice().getTotalRate().getCurrency()); + LOGGER.info("Offer price value: {}", offer.getOfferPrice().getTotalRate().getValue()); + } + + // To get the Offer availableTimeSlots + if (offer.getAvailableTimeSlots() != null) { + LOGGER.info( + "========================= Activity AvailableTimeSlots ========================="); + + offer.getAvailableTimeSlots().forEach(availableTimeSlot -> { + LOGGER.info("DateTime: {}", availableTimeSlot.getDateTime()); + LOGGER.info("AllDayActivity: {}", availableTimeSlot.getAllDayActivity()); + printCancellationPolicy(availableTimeSlot.getCancellationPolicy()); + + // To get ticket info + if (availableTimeSlot.getTickets() != null) { + LOGGER.info( + "============================ Activity ticket ============================= "); + availableTimeSlot.getTickets().forEach(ticket -> { + LOGGER.info("Code: {}", ticket.getCode()); + LOGGER.info("Ticket price currency: {}", + ticket.getTicketPrice().getTotalRate().getCurrency()); + LOGGER.info("Ticket price value: {}", + ticket.getTicketPrice().getTotalRate().getValue()); + + }); + LOGGER.info( + "============================ Activity ticket ============================ "); + } + + }); + + LOGGER.info( + "======================== Activity AvailableTimeSlots ==========================="); + } + }); + LOGGER.info( + "============================ Activity Offers ============================ "); + } - }); + LOGGER.info( + "============================= Activity End ============================="); - LOGGER.info( - "======================== Activity AvailableTimeSlots ==========================="); - } - }); - LOGGER.info( - "============================ Activity Offers ============================ "); + LOGGER.info( + "============================ End ListingsQuickStartScenario ==========================="); } - LOGGER.info( - "============================= Activity End ============================="); + private void printCancellationPolicy(ActivitiesCancellationPolicy cancellationPolicy) { + if (cancellationPolicy != null) { + LOGGER.info("Activity free cancellation available: {}", + cancellationPolicy.getFreeCancellation()); - LOGGER.info( - "============================ End ListingsQuickStartScenario ==========================="); - } + LOGGER.info("FreeCancellationMinHours: {}", cancellationPolicy.getFreeCancellationMinHours()); + LOGGER.info("FreeCancellationEndDateTime: {}", + cancellationPolicy.getFreeCancellationEndDateTime()); + LOGGER.info("CancelPolicyDescription: {}", cancellationPolicy.getCancelPolicyDescription()); - private void printCancellationPolicy(ActivitiesCancellationPolicy cancellationPolicy) { - if (cancellationPolicy != null) { - LOGGER.info("Activity free cancellation available: {}", - cancellationPolicy.getFreeCancellation()); + } + } - LOGGER.info("FreeCancellationMinHours: {}", cancellationPolicy.getFreeCancellationMinHours()); - LOGGER.info("FreeCancellationEndDateTime: {}", - cancellationPolicy.getFreeCancellationEndDateTime()); - LOGGER.info("CancelPolicyDescription: {}", cancellationPolicy.getCancelPolicyDescription()); + private void printLocation(ActivitiesLocation location) { + if (location != null) { + if (location.getAddress() != null) { + ActivitiesAddress address = location.getAddress(); + if (StringUtils.isNotEmpty(address.getCountry())) { + LOGGER.info("Country: {}", address.getCountry()); + } - } - } - - private void printLocation(ActivitiesLocation location) { - if (location != null) { - if (location.getAddress() != null) { - ActivitiesAddress address = location.getAddress(); - if (StringUtils.isNotEmpty(address.getCountry())) { - LOGGER.info("Country: {}", address.getCountry()); - } + if (StringUtils.isNotEmpty(address.getProvince())) { + LOGGER.info("Province: {}", address.getProvince()); + } - if (StringUtils.isNotEmpty(address.getProvince())) { - LOGGER.info("Province: {}", address.getProvince()); - } + if (StringUtils.isNotEmpty(address.getCity())) { + LOGGER.info("City: {}", address.getCity()); + } - if (StringUtils.isNotEmpty(address.getCity())) { - LOGGER.info("City: {}", address.getCity()); - } + if (StringUtils.isNotEmpty(address.getAddress1())) { + LOGGER.info("Address1: {}", address.getAddress1()); + } - if (StringUtils.isNotEmpty(address.getAddress1())) { - LOGGER.info("Address1: {}", address.getAddress1()); - } + if (StringUtils.isNotEmpty(address.getAddress2())) { + LOGGER.info("Address2: {}", address.getAddress2()); + } - if (StringUtils.isNotEmpty(address.getAddress2())) { - LOGGER.info("Address2: {}", address.getAddress2()); - } + } - } + if (location.getGeoLocation() != null) { + ActivitiesGeoLocation geoLocation = location.getGeoLocation(); + if (StringUtils.isNotEmpty(geoLocation.getLatitude())) { + LOGGER.info("Latitude: {}", geoLocation.getLatitude()); + } - if (location.getGeoLocation() != null) { - ActivitiesGeoLocation geoLocation = location.getGeoLocation(); - if (StringUtils.isNotEmpty(geoLocation.getLatitude())) { - LOGGER.info("Latitude: {}", geoLocation.getLatitude()); - } + if (StringUtils.isNotEmpty(geoLocation.getLongitude())) { + LOGGER.info("Longitude: {}", geoLocation.getLongitude()); + } + } - if (StringUtils.isNotEmpty(geoLocation.getLongitude())) { - LOGGER.info("Longitude: {}", geoLocation.getLongitude()); } - } } - - } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityListingsQuickStartScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityListingsQuickStartScenario.java index c6f668730..143426269 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityListingsQuickStartScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/activity/ActivityListingsQuickStartScenario.java @@ -21,8 +21,10 @@ import com.expediagroup.sdk.xap.models.ActivityListingsResponse; import com.expediagroup.sdk.xap.operations.GetActivityListingsOperation; import com.expediagroup.sdk.xap.operations.GetActivityListingsOperationParams; + import java.time.LocalDate; import java.util.Arrays; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,124 +33,122 @@ * This example demonstrates how to search for properties with a location applied. */ public class ActivityListingsQuickStartScenario implements XapScenario { + private static final Logger LOGGER = + LoggerFactory.getLogger(ActivityListingsQuickStartScenario.class); - private static final Logger LOGGER = - LoggerFactory.getLogger(ActivityListingsQuickStartScenario.class); - - public static void main(String[] args) { - new ActivityListingsQuickStartScenario().run(); - System.exit(0); - } - - @Override - public void run() { - // This example will search for activities with the following criteria: - // 1. Activities located in Seattle; - // 2. Start date 5 days from now, end date 8 days from now; - // 3. Return Expedia Web details and api details links. - LOGGER.info( - "========================== Running ListingsQuickStartScenario ========================="); - - LOGGER.info( - "======================== Executing GetActivityListingsOperation ======================="); - - - - // Build the query parameters with GetActivityListingsOperationParams - GetActivityListingsOperationParams getActivityListingsOperationParams = - GetActivityListingsOperationParams.builder() - .partnerTransactionId(XapScenario.PARTNER_TRANSACTION_ID).location("seattle") - .links(Arrays.asList(GetActivityListingsOperationParams.Links.WD, - GetActivityListingsOperationParams.Links.AD)) - .startDate(LocalDate.now().plusDays(5)).endDate(LocalDate.now().plusDays(8)).build(); - - XapClient xapClient = createClient(); - - // Execute the operation and get the HotelListingsResponse - ActivityListingsResponse activityListingsResponse = xapClient - .execute(new GetActivityListingsOperation(getActivityListingsOperationParams)).getData(); - - // If you want to use the async method, you can use the following code: - // --------------------------------------------------------------- - // CompletableFuture> completableFuture = - // xapClient.executeAsync( - // new GetActivityListingsOperation(getActivityListingsOperationParams)); - // completableFuture.thenAccept(activityListingsResponse -> { - // // Your code here - // }); - // --------------------------------------------------------------- - - LOGGER.info( - "======================== GetActivityListingsOperation Executed ========================"); - - if (activityListingsResponse == null || activityListingsResponse.getActivities() == null - || activityListingsResponse.getActivities().isEmpty()) { - throw new IllegalStateException("No activities found."); + public static void main(String[] args) { + new ActivityListingsQuickStartScenario().run(); + System.exit(0); } - // The ActivityListingsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", activityListingsResponse.getTransactionId()); - - // To access the activities, iterate through the list of activity properties - activityListingsResponse.getActivities().forEach(activity -> { - LOGGER.info( - "=================================== Activity Start ==================================="); - // To get the activity title - if (StringUtils.isNotEmpty(activity.getTitle())) { - LOGGER.info("Activity title: {}", activity.getTitle()); - } - // To get the activity description - if (StringUtils.isNotEmpty(activity.getDescription())) { - LOGGER.info("Activity description: {}", activity.getDescription()); - } - - // To get the activity duration - if (StringUtils.isNotEmpty(activity.getDuration())) { - LOGGER.info("Activity duration: {}", activity.getDuration()); - } - - - // To get the activity image - if (activity.getMedia() != null) { - LOGGER.info("Activity image: {}", activity.getMedia().get(0).getUrl()); - } - - // To get the activity review count - if (activity.getReviewCount() != null) { - LOGGER.info("Activity review count: {}", activity.getReviewCount()); - } - - // To get the activity review score - if (activity.getReviewScore() != null) { - LOGGER.info("Activity review score: {}", activity.getReviewScore()); - } - - // To get the activity free cancellation available - LOGGER.info("Activity free cancellation available: {}", activity.getFreeCancellation()); - - // To get the activity price - if (activity.getPrice() != null) { - LOGGER.info("Activity price currency: {}", - activity.getPrice().getTotalRate().getCurrency()); - LOGGER.info("Activity price value: {}", activity.getPrice().getTotalRate().getValue()); - } - - // Get the API details link and web details link from the links collection. - if (!activity.getLinks().isEmpty()) { - if (activity.getLinks().get("ApiDetails") != null) { - LOGGER.info("ApiDetails Link: {}", activity.getLinks().get("ApiDetails")); - } - - if (activity.getLinks().get("WebDetails") != null) { - LOGGER.info("WebDetails Link: {}", activity.getLinks().get("WebDetails")); + @Override + public void run() { + // This example will search for activities with the following criteria: + // 1. Activities located in Seattle; + // 2. Start date 5 days from now, end date 8 days from now; + // 3. Return Expedia Web details and api details links. + LOGGER.info( + "========================== Running ListingsQuickStartScenario ========================="); + + LOGGER.info( + "======================== Executing GetActivityListingsOperation ======================="); + + + // Build the query parameters with GetActivityListingsOperationParams + GetActivityListingsOperationParams getActivityListingsOperationParams = + GetActivityListingsOperationParams.builder() + .partnerTransactionId(XapScenario.PARTNER_TRANSACTION_ID).location("seattle") + .links(Arrays.asList(GetActivityListingsOperationParams.Links.WD, + GetActivityListingsOperationParams.Links.AD)) + .startDate(LocalDate.now().plusDays(5)).endDate(LocalDate.now().plusDays(8)).build(); + + XapClient xapClient = createClient(); + + // Execute the operation and get the HotelListingsResponse + ActivityListingsResponse activityListingsResponse = xapClient + .execute(new GetActivityListingsOperation(getActivityListingsOperationParams)).getData(); + + // If you want to use the async method, you can use the following code: + // --------------------------------------------------------------- + // CompletableFuture> completableFuture = + // xapClient.executeAsync( + // new GetActivityListingsOperation(getActivityListingsOperationParams)); + // completableFuture.thenAccept(activityListingsResponse -> { + // // Your code here + // }); + // --------------------------------------------------------------- + + LOGGER.info( + "======================== GetActivityListingsOperation Executed ========================"); + + if (activityListingsResponse == null || activityListingsResponse.getActivities() == null + || activityListingsResponse.getActivities().isEmpty()) { + throw new IllegalStateException("No activities found."); } - } - - LOGGER.info( - "==================================== Activity End ===================================="); - }); - LOGGER.info( - "============================ End ListingsQuickStartScenario ==========================="); - } + // The ActivityListingsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", activityListingsResponse.getTransactionId()); + + // To access the activities, iterate through the list of activity properties + activityListingsResponse.getActivities().forEach(activity -> { + LOGGER.info( + "=================================== Activity Start ==================================="); + // To get the activity title + if (StringUtils.isNotEmpty(activity.getTitle())) { + LOGGER.info("Activity title: {}", activity.getTitle()); + } + // To get the activity description + if (StringUtils.isNotEmpty(activity.getDescription())) { + LOGGER.info("Activity description: {}", activity.getDescription()); + } + + // To get the activity duration + if (StringUtils.isNotEmpty(activity.getDuration())) { + LOGGER.info("Activity duration: {}", activity.getDuration()); + } + + + // To get the activity image + if (activity.getMedia() != null) { + LOGGER.info("Activity image: {}", activity.getMedia().get(0).getUrl()); + } + + // To get the activity review count + if (activity.getReviewCount() != null) { + LOGGER.info("Activity review count: {}", activity.getReviewCount()); + } + + // To get the activity review score + if (activity.getReviewScore() != null) { + LOGGER.info("Activity review score: {}", activity.getReviewScore()); + } + + // To get the activity free cancellation available + LOGGER.info("Activity free cancellation available: {}", activity.getFreeCancellation()); + + // To get the activity price + if (activity.getPrice() != null) { + LOGGER.info("Activity price currency: {}", + activity.getPrice().getTotalRate().getCurrency()); + LOGGER.info("Activity price value: {}", activity.getPrice().getTotalRate().getValue()); + } + + // Get the API details link and web details link from the links collection. + if (!activity.getLinks().isEmpty()) { + if (activity.getLinks().get("ApiDetails") != null) { + LOGGER.info("ApiDetails Link: {}", activity.getLinks().get("ApiDetails")); + } + + if (activity.getLinks().get("WebDetails") != null) { + LOGGER.info("WebDetails Link: {}", activity.getLinks().get("WebDetails")); + } + } + + LOGGER.info( + "==================================== Activity End ===================================="); + }); + + LOGGER.info( + "============================ End ListingsQuickStartScenario ==========================="); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarDetailsQuickStartScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarDetailsQuickStartScenario.java index e96ceda05..967abff75 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarDetailsQuickStartScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarDetailsQuickStartScenario.java @@ -27,10 +27,12 @@ import com.expediagroup.sdk.xap.operations.GetCarDetailsOperationParams; import com.expediagroup.sdk.xap.operations.GetCarsListingsOperation; import com.expediagroup.sdk.xap.operations.GetCarsListingsOperationParams; + import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,226 +41,225 @@ * obtained from the car listing. */ public class CarDetailsQuickStartScenario implements XapScenario { + private static final Logger LOGGER = LoggerFactory.getLogger(CarDetailsQuickStartScenario.class); + + /** + * Summary: main function. + */ + public static void main(String[] args) { + new CarListingsQuickStartScenario().run(); + new CarDetailsQuickStartScenario().run(); + System.exit(0); + } + + /** + * Summary: split URL into components. + */ + public static String[] splitUrl(String url) { + String[] parts = url.split("\\?"); + String base = parts[0]; + String query = parts[1]; + + String offerToken = base.substring(base.lastIndexOf("/") + 1); + String[] queryParams = query.split("&"); + String price = queryParams[0].split("=")[1]; + String currency = queryParams[1].split("=")[1]; + + return new String[]{offerToken, price, currency}; + } + + @Override + public void run() { + LOGGER.info("========== Start QuickStartScenario =========="); + + LOGGER.info("========== Car Listing Start =========="); + + // This example demonstrates how to obtain the Car Details Deep Link from the CarListing. + // For information on using car search, refer to + // car/shopping/listings/ListingsQuickStartExample. + List linksList = new ArrayList<>(); + linksList.add(GetCarsListingsOperationParams.Links.AD); + linksList.add(GetCarsListingsOperationParams.Links.WS); + linksList.add(GetCarsListingsOperationParams.Links.WD); + GetCarsListingsOperationParams getCarsListingsOperationParams = + GetCarsListingsOperationParams.builder() + .partnerTransactionId("EWSCar_Automation") + .dropOffAirport("MCO") + .pickupAirport("MCO") + .pickupTime(LocalDateTime.now().plusDays(5)) + .dropOffTime(LocalDateTime.now().plusDays(8)) + .limit(1) + .links(linksList) + .build(); + + XapClient xapClient = createClient(); + GetCarsListingsOperation getCarsListingsOperation = + new GetCarsListingsOperation(getCarsListingsOperationParams); + Response carListingsResponse = xapClient.execute(getCarsListingsOperation); + + LOGGER.info("========== Car Listing Property End =========="); + + // Iterate through the car listings and retrieve the Car Details Deep Link. + LOGGER.info("========== Car Details Start =========="); + Objects.requireNonNull(carListingsResponse.getData().getCars()).forEach(car -> { + if (!car.getLinks().get("ApiDetails").getHref().isEmpty()) { + // Retrieve the Car Details Deep Link from the car listing. + LOGGER.info("Car Details Deep Link: " + car.getLinks().get("ApiDetails").getHref()); + String[] strings = splitUrl(car.getLinks().get("ApiDetails").getHref()); + + // Retrieve the Car Details information using the Car Details Deep Link, which + // includes (offerToken, price, currency) + GetCarDetailsOperationParams getCarDetailsOperationParams = + GetCarDetailsOperationParams.builder().partnerTransactionId("EWSCar_Automation") + .offerToken(strings[0]).price(strings[1]).currency(strings[2]).build(); + + // Execute the operation and get the CarDetailsResponse + LOGGER.info("========== Executing GetCarDetailsOperation =========="); + CarDetailsResponse carDetailsResponse = xapClient.execute( + new GetCarDetailsOperation(getCarDetailsOperationParams)).getData(); + LOGGER.info("========== GetCarDetailsOperation Executed =========="); + + if (carDetailsResponse == null || carDetailsResponse.getLinks() == null) { + throw new IllegalStateException("No car found."); + } + + LOGGER.info("========== Car Properties Start =========="); + + // The CarDetailsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", carDetailsResponse.getTransactionId()); + + // List Container for warning messages + if (carDetailsResponse.getWarnings() != null) { + LOGGER.info("Warnings: {}", carDetailsResponse.getWarnings()); + } + + // Details of requested car. + // Details refer to the CarDetails Section table below. + if (carDetailsResponse.getValidFormsOfPayment() != null) { + LOGGER.info("Valid Forms Of Payment: {}", carDetailsResponse.getValidFormsOfPayment()); + } + + // A map of links to other Car APIs. + if (carDetailsResponse.getLinks() != null) { + LOGGER.info("Links: {}", carDetailsResponse.getLinks()); + } + + // Specific information for a car. + CarDetails carDetails = carDetailsResponse.getCarDetails(); + VehicleDetails vehicleDetails = carDetails.getVehicleDetails(); + if (vehicleDetails.getMake() != null) { + //Car manufacturer and model. + LOGGER.info("Make: {}", vehicleDetails.getMake()); + } + + // Car category and type. + LOGGER.info("Car Class: {}", vehicleDetails.getCarClass()); + + // Minimal car door count. + if (vehicleDetails.getMinDoors() != null) { + LOGGER.info("Min Doors: {}", vehicleDetails.getMinDoors()); + } + + // Maximum car door count. + if (vehicleDetails.getMaxDoors() != null) { + LOGGER.info("Max Doors: {}", vehicleDetails.getMaxDoors()); + } + + // Car fuel information. + if (vehicleDetails.getFuelLevel() != null) { + // Fuel level of the car. + LOGGER.info("Fuel Level: {}", vehicleDetails.getFuelLevel()); + } + + // Car category. + LOGGER.info("Car Category: {}", vehicleDetails.getCarCategory()); + + // Car type. + LOGGER.info("Car Type: {}", vehicleDetails.getCarType()); + + // Car transmission and drive. + LOGGER.info("Transmission Drive: {}", vehicleDetails.getTransmissionDrive()); + + // Car fuel type and whether Air Conditioning is included. + LOGGER.info("Fuel AC: {}", vehicleDetails.getFuelAC()); + + // Capacity for car's properties, which include AdultCount, ChildCount, SmallLuggageCount + // and LargeLuggageCount. + if (vehicleDetails.getCapacity() != null) { + LOGGER.info("Capacity: {}", vehicleDetails.getCapacity()); + } + + // Car rental supplier. + LOGGER.info(" : {}", carDetails.getSupplier()); + + // Pickup information + LOGGER.info("Pickup Details: {}", carDetails.getPickupDetails()); + + // Drop off information, include drop off date time and drop off location information. + LOGGER.info("Drop Off Details: {}", carDetails.getDropOffDetails()); + + // The rate information for a car product. + LOGGER.info("Rate Details: {}", carDetails.getRateDetails()); + + // Base price per rate period. + LOGGER.info("Price: {}", carDetails.getPrice()); + + // List of TaxesAndFees Details. + if (carDetails.getTaxesAndFeesDetails() != null) { + LOGGER.info("Taxes And Fees Details: {}", carDetails.getTaxesAndFeesDetails()); + } + + // List of ExtraFeesDetails + if (carDetails.getExtraFeesDetails() != null) { + LOGGER.info("Extra Fees Details: {}", carDetails.getExtraFeesDetails()); + } + + // ReferencePrice is the totalPrice for the comparable standalone car, when there is + // a discounted car or need to show strike through pricing. + if (carDetails.getReferencePrice() != null) { + LOGGER.info("Reference Price: {}", carDetails.getReferencePrice()); + } + + // List of additional fees including both mandatory and optional fees such as young driver + // fee/drop off fee /CollisionDamageWaiver. + if (carDetails.getAdditionalFees() != null) { + LOGGER.info("Additional Fees: {}", carDetails.getAdditionalFees()); + } + + // Description and costs of any optional special equipment that may be rented with the car. + if (carDetails.getSpecialEquipments() != null) { + LOGGER.info("Special Equipments: {}", carDetails.getSpecialEquipments()); + } + + // Limitations that are part of this rental agreement. + if (carDetails.getRentalLimits() != null) { + LOGGER.info("Rental Limits: {}", carDetails.getRentalLimits()); + } + + // Cancellation Policy Container. + LOGGER.info("Cancellation Policy: {}", carDetails.getCancellationPolicy()); + + // Container for no show penalty + if (carDetails.getNoShowPenalty() != null) { + LOGGER.info("No Show Penalty: {}", carDetails.getNoShowPenalty()); + } + + // A list of policies that apply to this car rental. + if (carDetails.getCarPolicies() != null) { + LOGGER.info("Policies: {}", carDetails.getCarPolicies()); + } + + // List of image resources of the car product. + if (carDetails.getImages() != null) { + LOGGER.info("Images: {}", carDetails.getImages()); + } + + LOGGER.info("========== Property End =========="); + } + + }); - private static final Logger LOGGER = LoggerFactory.getLogger(CarDetailsQuickStartScenario.class); - - /** - * Summary: main function. - */ - public static void main(String[] args) { - new CarListingsQuickStartScenario().run(); - new CarDetailsQuickStartScenario().run(); - System.exit(0); - } - - /** - * Summary: split URL into components. - */ - public static String[] splitUrl(String url) { - String[] parts = url.split("\\?"); - String base = parts[0]; - String query = parts[1]; - - String offerToken = base.substring(base.lastIndexOf("/") + 1); - String[] queryParams = query.split("&"); - String price = queryParams[0].split("=")[1]; - String currency = queryParams[1].split("=")[1]; - - return new String[] {offerToken, price, currency}; - } - - @Override - public void run() { - LOGGER.info("========== Start QuickStartScenario =========="); - - LOGGER.info("========== Car Listing Start =========="); - - // This example demonstrates how to obtain the Car Details Deep Link from the CarListing. - // For information on using car search, refer to - // car/shopping/listings/ListingsQuickStartExample. - List linksList = new ArrayList<>(); - linksList.add(GetCarsListingsOperationParams.Links.AD); - linksList.add(GetCarsListingsOperationParams.Links.WS); - linksList.add(GetCarsListingsOperationParams.Links.WD); - GetCarsListingsOperationParams getCarsListingsOperationParams = - GetCarsListingsOperationParams.builder() - .partnerTransactionId("EWSCar_Automation") - .dropOffAirport("MCO") - .pickupAirport("MCO") - .pickupTime(LocalDateTime.now().plusDays(5)) - .dropOffTime(LocalDateTime.now().plusDays(8)) - .limit(1) - .links(linksList) - .build(); - - XapClient xapClient = createClient(); - GetCarsListingsOperation getCarsListingsOperation = - new GetCarsListingsOperation(getCarsListingsOperationParams); - Response carListingsResponse = xapClient.execute(getCarsListingsOperation); - - LOGGER.info("========== Car Listing Property End =========="); - - // Iterate through the car listings and retrieve the Car Details Deep Link. - LOGGER.info("========== Car Details Start =========="); - Objects.requireNonNull(carListingsResponse.getData().getCars()).forEach(car -> { - if (!car.getLinks().get("ApiDetails").getHref().isEmpty()) { - // Retrieve the Car Details Deep Link from the car listing. - LOGGER.info("Car Details Deep Link: " + car.getLinks().get("ApiDetails").getHref()); - String[] strings = splitUrl(car.getLinks().get("ApiDetails").getHref()); - - // Retrieve the Car Details information using the Car Details Deep Link, which - // includes (offerToken, price, currency) - GetCarDetailsOperationParams getCarDetailsOperationParams = - GetCarDetailsOperationParams.builder().partnerTransactionId("EWSCar_Automation") - .offerToken(strings[0]).price(strings[1]).currency(strings[2]).build(); - - // Execute the operation and get the CarDetailsResponse - LOGGER.info("========== Executing GetCarDetailsOperation =========="); - CarDetailsResponse carDetailsResponse = xapClient.execute( - new GetCarDetailsOperation(getCarDetailsOperationParams)).getData(); - LOGGER.info("========== GetCarDetailsOperation Executed =========="); - - if (carDetailsResponse == null || carDetailsResponse.getLinks() == null) { - throw new IllegalStateException("No car found."); - } - - LOGGER.info("========== Car Properties Start =========="); - - // The CarDetailsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", carDetailsResponse.getTransactionId()); - - // List Container for warning messages - if (carDetailsResponse.getWarnings() != null) { - LOGGER.info("Warnings: {}", carDetailsResponse.getWarnings()); - } - - // Details of requested car. - // Details refer to the CarDetails Section table below. - if (carDetailsResponse.getValidFormsOfPayment() != null) { - LOGGER.info("Valid Forms Of Payment: {}", carDetailsResponse.getValidFormsOfPayment()); - } - - // A map of links to other Car APIs. - if (carDetailsResponse.getLinks() != null) { - LOGGER.info("Links: {}", carDetailsResponse.getLinks()); - } - - // Specific information for a car. - CarDetails carDetails = carDetailsResponse.getCarDetails(); - VehicleDetails vehicleDetails = carDetails.getVehicleDetails(); - if (vehicleDetails.getMake() != null) { - //Car manufacturer and model. - LOGGER.info("Make: {}", vehicleDetails.getMake()); - } - - // Car category and type. - LOGGER.info("Car Class: {}", vehicleDetails.getCarClass()); - - // Minimal car door count. - if (vehicleDetails.getMinDoors() != null) { - LOGGER.info("Min Doors: {}", vehicleDetails.getMinDoors()); - } - - // Maximum car door count. - if (vehicleDetails.getMaxDoors() != null) { - LOGGER.info("Max Doors: {}", vehicleDetails.getMaxDoors()); - } - - // Car fuel information. - if (vehicleDetails.getFuelLevel() != null) { - // Fuel level of the car. - LOGGER.info("Fuel Level: {}", vehicleDetails.getFuelLevel()); - } - - // Car category. - LOGGER.info("Car Category: {}", vehicleDetails.getCarCategory()); - - // Car type. - LOGGER.info("Car Type: {}", vehicleDetails.getCarType()); - - // Car transmission and drive. - LOGGER.info("Transmission Drive: {}", vehicleDetails.getTransmissionDrive()); - - // Car fuel type and whether Air Conditioning is included. - LOGGER.info("Fuel AC: {}", vehicleDetails.getFuelAC()); - - // Capacity for car's properties, which include AdultCount, ChildCount, SmallLuggageCount - // and LargeLuggageCount. - if (vehicleDetails.getCapacity() != null) { - LOGGER.info("Capacity: {}", vehicleDetails.getCapacity()); - } - - // Car rental supplier. - LOGGER.info(" : {}", carDetails.getSupplier()); - - // Pickup information - LOGGER.info("Pickup Details: {}", carDetails.getPickupDetails()); - - // Drop off information, include drop off date time and drop off location information. - LOGGER.info("Drop Off Details: {}", carDetails.getDropOffDetails()); - - // The rate information for a car product. - LOGGER.info("Rate Details: {}", carDetails.getRateDetails()); - - // Base price per rate period. - LOGGER.info("Price: {}", carDetails.getPrice()); - - // List of TaxesAndFees Details. - if (carDetails.getTaxesAndFeesDetails() != null) { - LOGGER.info("Taxes And Fees Details: {}", carDetails.getTaxesAndFeesDetails()); - } - - // List of ExtraFeesDetails - if (carDetails.getExtraFeesDetails() != null) { - LOGGER.info("Extra Fees Details: {}", carDetails.getExtraFeesDetails()); - } - - // ReferencePrice is the totalPrice for the comparable standalone car, when there is - // a discounted car or need to show strike through pricing. - if (carDetails.getReferencePrice() != null) { - LOGGER.info("Reference Price: {}", carDetails.getReferencePrice()); - } - - // List of additional fees including both mandatory and optional fees such as young driver - // fee/drop off fee /CollisionDamageWaiver. - if (carDetails.getAdditionalFees() != null) { - LOGGER.info("Additional Fees: {}", carDetails.getAdditionalFees()); - } - - // Description and costs of any optional special equipment that may be rented with the car. - if (carDetails.getSpecialEquipments() != null) { - LOGGER.info("Special Equipments: {}", carDetails.getSpecialEquipments()); - } - - // Limitations that are part of this rental agreement. - if (carDetails.getRentalLimits() != null) { - LOGGER.info("Rental Limits: {}", carDetails.getRentalLimits()); - } - - // Cancellation Policy Container. - LOGGER.info("Cancellation Policy: {}", carDetails.getCancellationPolicy()); - - // Container for no show penalty - if (carDetails.getNoShowPenalty() != null) { - LOGGER.info("No Show Penalty: {}", carDetails.getNoShowPenalty()); - } - - // A list of policies that apply to this car rental. - if (carDetails.getCarPolicies() != null) { - LOGGER.info("Policies: {}", carDetails.getCarPolicies()); - } - - // List of image resources of the car product. - if (carDetails.getImages() != null) { - LOGGER.info("Images: {}", carDetails.getImages()); - } - - LOGGER.info("========== Property End =========="); - } - - }); - - LOGGER.info("========== End QuickStartExample =========="); - } + LOGGER.info("========== End QuickStartExample =========="); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarListingsQuickStartScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarListingsQuickStartScenario.java index 0d2d6406f..55a2aebad 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarListingsQuickStartScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/car/CarListingsQuickStartScenario.java @@ -21,9 +21,11 @@ import com.expediagroup.sdk.xap.models.CarListingsResponse; import com.expediagroup.sdk.xap.operations.GetCarsListingsOperation; import com.expediagroup.sdk.xap.operations.GetCarsListingsOperationParams; + import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,141 +34,140 @@ * applied. */ public class CarListingsQuickStartScenario implements XapScenario { - - private static final Logger LOGGER = LoggerFactory.getLogger(CarListingsQuickStartScenario.class); - - /** - * Summary: main function. - */ - public static void main(String[] args) { - new CarListingsQuickStartScenario().run(); - System.exit(0); - } - - @Override - public void run() { - LOGGER.info( - "========================= Running CarListingsQuickStartScenario ========================"); - - LOGGER.info( - "======================== Executing GetCarsListingsOperation ======================="); - // This example will search for properties based on the following criteria: - // 1. The pickup airport is MCO, and the drop-off airport is MCO; - // 2. The pickup time is "2025-01-15T11:00", and the drop-off time is "2025-01-19T11:00"; - // 3. The results should include API details, web search, and web details link; - // 4. Limit the results to 5; - - // Create a list to store the types of links to be returned. - // The added link types include(API details link, Web search link, and Web details link). - List linksList = new ArrayList<>(); - linksList.add(GetCarsListingsOperationParams.Links.AD); - linksList.add(GetCarsListingsOperationParams.Links.WS); - linksList.add(GetCarsListingsOperationParams.Links.WD); - - GetCarsListingsOperationParams getCarsListingsOperationParams = - GetCarsListingsOperationParams.builder().partnerTransactionId("EWSCar_Automation") - //Three letter code for the airport at which the customer would like to pick up the car. - //Supported values: standard 3 letter IATA Airport Code. - //Cannot coexist with other pickup parameters, only one pickup parameter is allowed per - //request. - .pickupAirport("MCO") - //Three letter code for the airport at which the customer would like to drop off the - //car. - //Supported values: standard 3 letter IATA Airport Code. - //Cannot coexist with other drop off parameters, only one drop off parameter is allowed - //per request. - //If no drop off location is specified, it is assumed that the customer will be dropping - //the car off at the same location at which they picked it up. - .dropOffAirport("MCO") - //Requested car pickup date and time. - //Date should be ISO8601 Date format.The supported search window is today to 330 days in - //the future. - //(Note that each rental counter has different hours of operation. If you select a time - //in the middle of the night there may be no inventory available as all locations may be - //closed.) - .pickupTime(LocalDateTime.now().plusDays(5)) - //Requested car drop off date and time. - //Date should be ISO8601 Date format.The supported search window is today to 330 days in - //the future. - //The drop-off datetime should occur at least 2 hours after the pickup datetime. - .dropOffTime(LocalDateTime.now().plusDays(8)) - //The maximum number of search results that will be returned by the query. - .limit(5).links(linksList).build(); - XapClient xapClient = createClient(); - - // Execute the operation and get the CarListingsResponse - CarListingsResponse carListingsResponse = - xapClient.execute(new GetCarsListingsOperation(getCarsListingsOperationParams)).getData(); - LOGGER.info( - "======================== GetCarsListingsOperation Executed ========================"); - - if (carListingsResponse == null || carListingsResponse.getCars() == null - || carListingsResponse.getCars().isEmpty()) { - throw new IllegalStateException("No cars found."); + private static final Logger LOGGER = LoggerFactory.getLogger(CarListingsQuickStartScenario.class); + + /** + * Summary: main function. + */ + public static void main(String[] args) { + new CarListingsQuickStartScenario().run(); + System.exit(0); } - // The CarListingsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", carListingsResponse.getTransactionId()); - // To get the total number of car found - LOGGER.info("Car Count: {}", carListingsResponse.getCarCount()); - - // To access the properties, iterate through the list of car properties - carListingsResponse.getCars().forEach(car -> { - LOGGER.info("======================== Car Properties Start ========================"); - - // Uniquely identifies a Car Offer. - LOGGER.info("Car Id: {}", car.getId()); - - // Specific information for a car. - LOGGER.info("Car VehicleDetails: {}", car.getVehicleDetails()); - - // The supplier of the car being offered. - LOGGER.info("Car Supplier: {}", car.getSupplier()); - - // Get Pickup information of the car. - LOGGER.info("Pick up Details: {}", car.getPickupDetails()); - - // Get Drop off information of the car. - LOGGER.info("Drop Off Details: {}", car.getDropOffDetails()); - - // Get the API details link, web search link, and web details link from the links collection. - if (!car.getLinks().isEmpty()) { - if (car.getLinks().get("ApiDetails") != null) { - LOGGER.info("ApiDetails Link: {}", car.getLinks().get("ApiDetails")); + @Override + public void run() { + LOGGER.info( + "========================= Running CarListingsQuickStartScenario ========================"); + + LOGGER.info( + "======================== Executing GetCarsListingsOperation ======================="); + // This example will search for properties based on the following criteria: + // 1. The pickup airport is MCO, and the drop-off airport is MCO; + // 2. The pickup time is "2025-01-15T11:00", and the drop-off time is "2025-01-19T11:00"; + // 3. The results should include API details, web search, and web details link; + // 4. Limit the results to 5; + + // Create a list to store the types of links to be returned. + // The added link types include(API details link, Web search link, and Web details link). + List linksList = new ArrayList<>(); + linksList.add(GetCarsListingsOperationParams.Links.AD); + linksList.add(GetCarsListingsOperationParams.Links.WS); + linksList.add(GetCarsListingsOperationParams.Links.WD); + + GetCarsListingsOperationParams getCarsListingsOperationParams = + GetCarsListingsOperationParams.builder().partnerTransactionId("EWSCar_Automation") + //Three letter code for the airport at which the customer would like to pick up the car. + //Supported values: standard 3 letter IATA Airport Code. + //Cannot coexist with other pickup parameters, only one pickup parameter is allowed per + //request. + .pickupAirport("MCO") + //Three letter code for the airport at which the customer would like to drop off the + //car. + //Supported values: standard 3 letter IATA Airport Code. + //Cannot coexist with other drop off parameters, only one drop off parameter is allowed + //per request. + //If no drop off location is specified, it is assumed that the customer will be dropping + //the car off at the same location at which they picked it up. + .dropOffAirport("MCO") + //Requested car pickup date and time. + //Date should be ISO8601 Date format.The supported search window is today to 330 days in + //the future. + //(Note that each rental counter has different hours of operation. If you select a time + //in the middle of the night there may be no inventory available as all locations may be + //closed.) + .pickupTime(LocalDateTime.now().plusDays(5)) + //Requested car drop off date and time. + //Date should be ISO8601 Date format.The supported search window is today to 330 days in + //the future. + //The drop-off datetime should occur at least 2 hours after the pickup datetime. + .dropOffTime(LocalDateTime.now().plusDays(8)) + //The maximum number of search results that will be returned by the query. + .limit(5).links(linksList).build(); + XapClient xapClient = createClient(); + + // Execute the operation and get the CarListingsResponse + CarListingsResponse carListingsResponse = + xapClient.execute(new GetCarsListingsOperation(getCarsListingsOperationParams)).getData(); + LOGGER.info( + "======================== GetCarsListingsOperation Executed ========================"); + + if (carListingsResponse == null || carListingsResponse.getCars() == null + || carListingsResponse.getCars().isEmpty()) { + throw new IllegalStateException("No cars found."); } - if (car.getLinks().get("WebSearch") != null) { - LOGGER.info("WebSearch Link: {}", car.getLinks().get("WebSearch")); - } - if (car.getLinks().get("WebDetails") != null) { - LOGGER.info("WebDetails Link: {}", car.getLinks().get("WebDetails")); - } - } - - // The rate detail information for a car offer. - if (car.getRateDetails() != null) { - LOGGER.info("Rate Details: {}", car.getRateDetails()); - } - - // Get the detailed pricing information for the rental of the car offer, - LOGGER.info("Car Price: {}", car.getPrice()); - - // Get a list of additional fees, including both mandatory and optional fees. - if (car.getAdditionalFees() != null) { - LOGGER.info("Additional Fees: {}", car.getAdditionalFees()); - } - - // Get the cancellation policy for the car offer, - LOGGER.info("Cancellation Policy: {}", car.getCancellationPolicy()); - - // Container for no show penalty element. - if (car.getNoShowPenalty() != null) { - LOGGER.info("No Show Penalty: {}", car.getNoShowPenalty()); - } - - LOGGER.info("======================== Property End ========================"); - }); - LOGGER.info( - "======================== End CarListingsQuickStartScenario ========================"); - } + // The CarListingsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", carListingsResponse.getTransactionId()); + // To get the total number of car found + LOGGER.info("Car Count: {}", carListingsResponse.getCarCount()); + + // To access the properties, iterate through the list of car properties + carListingsResponse.getCars().forEach(car -> { + LOGGER.info("======================== Car Properties Start ========================"); + + // Uniquely identifies a Car Offer. + LOGGER.info("Car Id: {}", car.getId()); + + // Specific information for a car. + LOGGER.info("Car VehicleDetails: {}", car.getVehicleDetails()); + + // The supplier of the car being offered. + LOGGER.info("Car Supplier: {}", car.getSupplier()); + + // Get Pickup information of the car. + LOGGER.info("Pick up Details: {}", car.getPickupDetails()); + + // Get Drop off information of the car. + LOGGER.info("Drop Off Details: {}", car.getDropOffDetails()); + + // Get the API details link, web search link, and web details link from the links collection. + if (!car.getLinks().isEmpty()) { + if (car.getLinks().get("ApiDetails") != null) { + LOGGER.info("ApiDetails Link: {}", car.getLinks().get("ApiDetails")); + } + if (car.getLinks().get("WebSearch") != null) { + LOGGER.info("WebSearch Link: {}", car.getLinks().get("WebSearch")); + } + if (car.getLinks().get("WebDetails") != null) { + LOGGER.info("WebDetails Link: {}", car.getLinks().get("WebDetails")); + } + } + + // The rate detail information for a car offer. + if (car.getRateDetails() != null) { + LOGGER.info("Rate Details: {}", car.getRateDetails()); + } + + // Get the detailed pricing information for the rental of the car offer, + LOGGER.info("Car Price: {}", car.getPrice()); + + + // Get a list of additional fees, including both mandatory and optional fees. + if (car.getAdditionalFees() != null) { + LOGGER.info("Additional Fees: {}", car.getAdditionalFees()); + } + + // Get the cancellation policy for the car offer, + LOGGER.info("Cancellation Policy: {}", car.getCancellationPolicy()); + + // Container for no show penalty element. + if (car.getNoShowPenalty() != null) { + LOGGER.info("No Show Penalty: {}", car.getNoShowPenalty()); + } + + LOGGER.info("======================== Property End ========================"); + }); + LOGGER.info( + "======================== End CarListingsQuickStartScenario ========================"); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/flight/FlightListingExample.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/flight/FlightListingExample.java index 32286d5fa..ee7c5ad4e 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/flight/FlightListingExample.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/flight/FlightListingExample.java @@ -19,333 +19,234 @@ import com.expediagroup.sdk.xap.client.XapClient; import com.expediagroup.sdk.xap.examples.scenarios.XapScenario; import com.expediagroup.sdk.xap.models.FlightSearchResponse; +import com.expediagroup.sdk.xap.models.GetFlightListingsOperationSegmentParam; import com.expediagroup.sdk.xap.operations.GetFlightListingsOperation; import com.expediagroup.sdk.xap.operations.GetFlightListingsOperationParams; + import java.time.LocalDate; import java.util.Arrays; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This example demonstrates how to search for flight listings for a one-way, - * round-trip & mutli-stop with adults, seniors, and childrens. + * round-trip & multi-stop with adults, seniors, and children. */ public class FlightListingExample implements XapScenario { + private static final Logger LOGGER = LoggerFactory.getLogger(FlightListingExample.class); - private static final Logger LOGGER = - LoggerFactory.getLogger(FlightListingExample.class); - - - public static void main(String[] args) { - new FlightListingExample().run(); - System.exit(0); - } + public static void main(String[] args) { + new FlightListingExample().run(); + System.exit(0); + } - @Override + @Override public void run() { - LOGGER.info( - "========= Running FlightListingsQuickStartScenario ============="); - - LOGGER.info( - "============= Executing GetFlightListingsOperation (One-Way) ========="); + LOGGER.info("========= Running FlightListingsQuickStartScenario ============="); + LOGGER.info("============= Executing GetFlightListingsOperation (One-Way) ========="); + LocalDate now = LocalDate.now(); - GetFlightListingsOperationParams getFlightListingsOperationParams = - GetFlightListingsOperationParams.builder() - .partnerTransactionID("txn-123-4") - .segment1Origin("LAS") - .segment1Destination("FLL") - .segment1DepartureDate(LocalDate.of(2025, 5, 1)) - .adult(1) - .senior(1) - .childrenAges(Arrays.asList(4, 5)) - .build(); + GetFlightListingsOperationParams getFlightListingsOperationParams = GetFlightListingsOperationParams.builder().partnerTransactionID("txn-123-4").segment1(GetFlightListingsOperationSegmentParam.builder().origin("LAS").destination("FLL").departureDate(now.plusDays(5)).build()).adult(1).senior(1).childrenAges(Arrays.asList(4, 5)).build(); - XapClient xapClient = createClient(); + XapClient xapClient = createClient(); - FlightSearchResponse flightListingsResponse = - xapClient.execute(new GetFlightListingsOperation(getFlightListingsOperationParams)) - .getData(); + FlightSearchResponse flightListingsResponse = xapClient.execute(new GetFlightListingsOperation(getFlightListingsOperationParams)).getData(); - LOGGER.info("========= GetFlightListingsOperation (One-Way) Executed ========"); - - if (flightListingsResponse == null || flightListingsResponse.getSegments() == null - || flightListingsResponse.getSegments().isEmpty()) { - throw new IllegalStateException("No flight found."); - } + LOGGER.info("========= GetFlightListingsOperation (One-Way) Executed ========"); + if (flightListingsResponse == null || flightListingsResponse.getSegments() == null || flightListingsResponse.getSegments().isEmpty()) { + throw new IllegalStateException("No flight found."); + } - LOGGER.info("Transaction ID: {}", flightListingsResponse.getTransactionId()); - - if (flightListingsResponse.getSegments() != null) { - flightListingsResponse.getSegments().forEach(segment -> { - LOGGER.info("======================== Flight Segment Start ========================"); - LOGGER.info("Segment ID: {}", segment.getSegmentId()); - LOGGER.info("Flight Duration: {}", segment.getFlightDuration()); - LOGGER.info("Total Stops: {}", segment.getTotalStops()); - LOGGER.info("Departure Arrival Day Difference: {}", - segment.getDepartureArrivalDayDifference()); - LOGGER.info("Seats Left: {}", segment.getSeatsLeft()); - LOGGER.info("Fare Type: {}", segment.getFareType()); - - if (segment.getLegs() != null) { - segment.getLegs().forEach(leg -> { - LOGGER.info("-------------------- Leg Start --------------------"); - - if (leg.getDepartureAirport() != null) { - LOGGER.info("Departure Airport Code: {}", - leg.getDepartureAirport().getCode()); - LOGGER.info("Departure Airport Name: {}", - leg.getDepartureAirport().getName()); - LOGGER.info("Departure City: {}", - leg.getDepartureAirport().getCity()); - LOGGER.info("Departure Province: {}", - leg.getDepartureAirport().getProvince()); - LOGGER.info("Departure Country: {}", - leg.getDepartureAirport().getCountry()); - LOGGER.info("Departure Latitude: {}", - leg.getDepartureAirport().getLatitude()); - LOGGER.info("Departure Longitude: {}", - leg.getDepartureAirport().getLongitude()); - } - - if (leg.getArrivalAirport() != null) { - LOGGER.info("Arrival Airport Code: {}", - leg.getArrivalAirport().getCode()); - LOGGER.info("Arrival Airport Name: {}", - leg.getArrivalAirport().getName()); - LOGGER.info("Arrival City: {}", - leg.getArrivalAirport().getCity()); - LOGGER.info("Arrival Province: {}", - leg.getArrivalAirport().getProvince()); - LOGGER.info("Arrival Country: {}", - leg.getArrivalAirport().getCountry()); - LOGGER.info("Arrival Latitude: {}", - leg.getArrivalAirport().getLatitude()); - LOGGER.info("Arrival Longitude: {}", - leg.getArrivalAirport().getLongitude()); - } - LOGGER.info("Departure Date Time: {}", - leg.getDepartureDateTime()); - LOGGER.info("Arrival Date Time: {}", - leg.getArrivalDateTime()); - LOGGER.info("Flight Number: {}", - leg.getFlightNumber()); - LOGGER.info("Marketing Airline Code: {}", - leg.getMarketingAirlineCode()); - LOGGER.info("Marketing Airline Name: {}", - leg.getMarketingAirlineName()); - LOGGER.info("Equipment Code: {}", - leg.getEquipmentCode()); - LOGGER.info("Flight On Time Percentage: {}", - leg.getFlightOnTimePercentage()); - LOGGER.info("Equipment Name: {}", - leg.getEquipmentName()); - LOGGER.info("Flight Duration (Leg): {}", - leg.getFlightDuration()); - - if (leg.getFlightDistance() != null) { - LOGGER.info("Flight Distance Value: {}", - leg.getFlightDistance().getValue()); - LOGGER.info("Flight Distance Unit: {}", - leg.getFlightDistance().getUnit()); - } - LOGGER.info("Booking Code: {}", - leg.getBookingCode()); - LOGGER.info("Cabin Class: {}", - leg.getCabinClass()); - LOGGER.info("Fare Basis Code: {}", - leg.getFareBasisCode()); - LOGGER.info("Meal Options: {}", - leg.getMealOptions()); - LOGGER.info("Amenities: {}", - leg.getAmenities()); - LOGGER.info("---------- Leg End ----------"); - }); + LOGGER.info("Transaction ID: {}", flightListingsResponse.getTransactionId()); + + if (flightListingsResponse.getSegments() != null) { + flightListingsResponse.getSegments().forEach(segment -> { + LOGGER.info("======================== Flight Segment Start ========================"); + LOGGER.info("Segment ID: {}", segment.getSegmentId()); + LOGGER.info("Flight Duration: {}", segment.getFlightDuration()); + LOGGER.info("Total Stops: {}", segment.getTotalStops()); + LOGGER.info("Departure Arrival Day Difference: {}", segment.getDepartureArrivalDayDifference()); + LOGGER.info("Seats Left: {}", segment.getSeatsLeft()); + LOGGER.info("Fare Type: {}", segment.getFareType()); + + if (segment.getLegs() != null) { + segment.getLegs().forEach(leg -> { + LOGGER.info("-------------------- Leg Start --------------------"); + + if (leg.getDepartureAirport() != null) { + LOGGER.info("Departure Airport Code: {}", leg.getDepartureAirport().getCode()); + LOGGER.info("Departure Airport Name: {}", leg.getDepartureAirport().getName()); + LOGGER.info("Departure City: {}", leg.getDepartureAirport().getCity()); + LOGGER.info("Departure Province: {}", leg.getDepartureAirport().getProvince()); + LOGGER.info("Departure Country: {}", leg.getDepartureAirport().getCountry()); + LOGGER.info("Departure Latitude: {}", leg.getDepartureAirport().getLatitude()); + LOGGER.info("Departure Longitude: {}", leg.getDepartureAirport().getLongitude()); + } + + if (leg.getArrivalAirport() != null) { + LOGGER.info("Arrival Airport Code: {}", leg.getArrivalAirport().getCode()); + LOGGER.info("Arrival Airport Name: {}", leg.getArrivalAirport().getName()); + LOGGER.info("Arrival City: {}", leg.getArrivalAirport().getCity()); + LOGGER.info("Arrival Province: {}", leg.getArrivalAirport().getProvince()); + LOGGER.info("Arrival Country: {}", leg.getArrivalAirport().getCountry()); + LOGGER.info("Arrival Latitude: {}", leg.getArrivalAirport().getLatitude()); + LOGGER.info("Arrival Longitude: {}", leg.getArrivalAirport().getLongitude()); + } + LOGGER.info("Departure Date Time: {}", leg.getDepartureDateTime()); + LOGGER.info("Arrival Date Time: {}", leg.getArrivalDateTime()); + LOGGER.info("Flight Number: {}", leg.getFlightNumber()); + LOGGER.info("Marketing Airline Code: {}", leg.getMarketingAirlineCode()); + LOGGER.info("Marketing Airline Name: {}", leg.getMarketingAirlineName()); + LOGGER.info("Equipment Code: {}", leg.getEquipmentCode()); + LOGGER.info("Flight On Time Percentage: {}", leg.getFlightOnTimePercentage()); + LOGGER.info("Equipment Name: {}", leg.getEquipmentName()); + LOGGER.info("Flight Duration (Leg): {}", leg.getFlightDuration()); + + if (leg.getFlightDistance() != null) { + LOGGER.info("Flight Distance Value: {}", leg.getFlightDistance().getValue()); + LOGGER.info("Flight Distance Unit: {}", leg.getFlightDistance().getUnit()); + } + + LOGGER.info("Booking Code: {}", leg.getBookingCode()); + LOGGER.info("Cabin Class: {}", leg.getCabinClass()); + LOGGER.info("Fare Basis Code: {}", leg.getFareBasisCode()); + LOGGER.info("Meal Options: {}", leg.getMealOptions()); + LOGGER.info("Amenities: {}", leg.getAmenities()); + LOGGER.info("---------- Leg End ----------"); + }); + } + LOGGER.info("=========== Flight Segment End ============"); + }); } - LOGGER.info("=========== Flight Segment End ============"); - }); - } - if (flightListingsResponse.getOffers() != null) { - flightListingsResponse.getOffers().forEach(offer -> { - LOGGER.info("======================== Flight Offer Start ========================"); + if (flightListingsResponse.getOffers() != null) { + flightListingsResponse.getOffers().forEach(offer -> { + LOGGER.info("======================== Flight Offer Start ========================"); + + if (offer.getLinks() != null) { + offer.getLinks().forEach((key, value) -> LOGGER.info("Link [{}]: {}", key, value)); + } + + LOGGER.info("Segment IDs: {}", offer.getSegmentIds()); + + if (offer.getOfferPrice() != null) { + + if (offer.getOfferPrice().getTotalPrice() != null) { + LOGGER.info("Total Price Value: {}", offer.getOfferPrice().getTotalPrice().getValue()); + LOGGER.info("Total Price Currency: {}", offer.getOfferPrice().getTotalPrice().getCurrency()); + } + + if (offer.getOfferPrice().getBasePrice() != null) { + LOGGER.info("Base Price Value: {}", offer.getOfferPrice().getBasePrice().getValue()); + LOGGER.info("Base Price Currency: {}", offer.getOfferPrice().getBasePrice().getCurrency()); + } + + if (offer.getOfferPrice().getTotalTaxes() != null) { + LOGGER.info("Total Taxes Value: {}", offer.getOfferPrice().getTotalTaxes().getValue()); + LOGGER.info("Total Taxes Currency: {}", offer.getOfferPrice().getTotalTaxes().getCurrency()); + } + + if (offer.getOfferPrice().getTotalTaxesAndFees() != null) { + LOGGER.info("Total Taxes and Fees Value: {}", offer.getOfferPrice().getTotalTaxesAndFees().getValue()); + LOGGER.info("Total Taxes and Fees Currency: {}", offer.getOfferPrice().getTotalTaxesAndFees().getCurrency()); + } + + if (offer.getOfferPrice().getAveragePricePerTicket() != null) { + LOGGER.info("Average Price Per Ticket Value: {}", offer.getOfferPrice().getAveragePricePerTicket().getValue()); + LOGGER.info("Average Price Per Ticket Currency: {}", offer.getOfferPrice().getAveragePricePerTicket().getCurrency()); + LOGGER.info("Average Price Per Ticket Count: {}", offer.getOfferPrice().getAveragePricePerTicket().getCount()); + } + + if (offer.getOfferPrice().getPricePerPassengerCategory() != null) { + offer.getOfferPrice().getPricePerPassengerCategory().forEach(categoryPrice -> { + LOGGER.info("---- Passenger Category Price Start ----"); + LOGGER.info("Category: {}", categoryPrice.getCategory()); + LOGGER.info("Count: {}", categoryPrice.getCount()); + + if (categoryPrice.getTotalPrice() != null) { + LOGGER.info("Total Price Value: {}", categoryPrice.getTotalPrice().getValue()); + LOGGER.info("Total Price Currency: {}", categoryPrice.getTotalPrice().getCurrency()); + } + + if (categoryPrice.getBasePrice() != null) { + LOGGER.info("Base Price Value: {}", categoryPrice.getBasePrice().getValue()); + LOGGER.info("Base Price Currency: {}", categoryPrice.getBasePrice().getCurrency()); + } + + if (categoryPrice.getTotalTaxes() != null) { + LOGGER.info("Total Taxes Value: {}", categoryPrice.getTotalTaxes().getValue()); + LOGGER.info("Total Taxes Currency: {}", categoryPrice.getTotalTaxes().getCurrency()); + } + LOGGER.info("---- Passenger Category Price End ----"); + }); + } + } + + + LOGGER.info("Ticket Type: {}", offer.getTicketType()); + LOGGER.info("======================== Flight Offer End ========================"); + }); + } - if (offer.getLinks() != null) { - offer.getLinks().forEach((key, value) -> - LOGGER.info("Link [{}]: {}", key, value)); + if (flightListingsResponse.getSearchCities() != null) { + flightListingsResponse.getSearchCities().forEach(city -> { + LOGGER.info("======================== Search City Start ========================"); + LOGGER.info("City Code: {}", city.getCode()); + LOGGER.info("City Name: {}", city.getCity()); + LOGGER.info("Province: {}", city.getProvince()); + LOGGER.info("Country: {}", city.getCountry()); + LOGGER.info("======================== Search City End ========================"); + }); } - LOGGER.info("Segment IDs: {}", offer.getSegmentIds()); - - if (offer.getOfferPrice() != null) { - - if (offer.getOfferPrice().getTotalPrice() != null) { - LOGGER.info("Total Price Value: {}", - offer.getOfferPrice().getTotalPrice().getValue()); - LOGGER.info("Total Price Currency: {}", - offer.getOfferPrice().getTotalPrice().getCurrency()); - } - - if (offer.getOfferPrice().getBasePrice() != null) { - LOGGER.info("Base Price Value: {}", - offer.getOfferPrice().getBasePrice().getValue()); - LOGGER.info("Base Price Currency: {}", - offer.getOfferPrice().getBasePrice().getCurrency()); - } - - if (offer.getOfferPrice().getTotalTaxes() != null) { - LOGGER.info("Total Taxes Value: {}", - offer.getOfferPrice().getTotalTaxes().getValue()); - LOGGER.info("Total Taxes Currency: {}", - offer.getOfferPrice().getTotalTaxes().getCurrency()); - } - - if (offer.getOfferPrice().getTotalTaxesAndFees() != null) { - LOGGER.info("Total Taxes and Fees Value: {}", - offer.getOfferPrice().getTotalTaxesAndFees().getValue()); - LOGGER.info("Total Taxes and Fees Currency: {}", - offer.getOfferPrice().getTotalTaxesAndFees().getCurrency()); - } - - if (offer.getOfferPrice().getAveragePricePerTicket() != null) { - LOGGER.info("Average Price Per Ticket Value: {}", - offer.getOfferPrice().getAveragePricePerTicket().getValue()); - LOGGER.info("Average Price Per Ticket Currency: {}", - offer.getOfferPrice().getAveragePricePerTicket().getCurrency()); - LOGGER.info("Average Price Per Ticket Count: {}", - offer.getOfferPrice().getAveragePricePerTicket().getCount()); - } - - if (offer.getOfferPrice().getPricePerPassengerCategory() != null) { - offer.getOfferPrice().getPricePerPassengerCategory() - .forEach(categoryPrice -> { - LOGGER.info("---- Passenger Category Price Start ----"); - LOGGER.info("Category: {}", categoryPrice.getCategory()); - LOGGER.info("Count: {}", categoryPrice.getCount()); - - if (categoryPrice.getTotalPrice() != null) { - LOGGER.info("Total Price Value: {}", - categoryPrice.getTotalPrice().getValue()); - LOGGER.info("Total Price Currency: {}", - categoryPrice.getTotalPrice().getCurrency()); - } - - if (categoryPrice.getBasePrice() != null) { - LOGGER.info("Base Price Value: {}", - categoryPrice.getBasePrice().getValue()); - LOGGER.info("Base Price Currency: {}", - categoryPrice.getBasePrice().getCurrency()); - } - - if (categoryPrice.getTotalTaxes() != null) { - LOGGER.info("Total Taxes Value: {}", - categoryPrice.getTotalTaxes().getValue()); - LOGGER.info("Total Taxes Currency: {}", - categoryPrice.getTotalTaxes().getCurrency()); - } - LOGGER.info("---- Passenger Category Price End ----"); - }); - } + if (flightListingsResponse.getValidFormsOfPayment() != null) { + flightListingsResponse.getValidFormsOfPayment().forEach((key, value) -> { + LOGGER.info("================= Valid Forms of Payment Start [{}] ============", key); + value.forEach(payment -> { + LOGGER.info("---- Payment Method Start ----"); + LOGGER.info("Payment Method: {}", payment.getPaymentMethod()); + LOGGER.info("Name: {}", payment.getName()); + LOGGER.info("Fee: {}", payment.getFee()); + LOGGER.info("Currency: {}", payment.getCurrency()); + LOGGER.info("---- Payment Method End ----"); + }); + LOGGER.info("========== Valid Forms of Payment End [{}] ============", key); + }); } + LOGGER.info("===================== End FlightListingsQuickStartScenario ===================="); - LOGGER.info("Ticket Type: {}", offer.getTicketType()); - LOGGER.info("======================== Flight Offer End ========================"); - }); - } + // --- Example for a Round Trip Search --- + LOGGER.info("\n======== Executing GetFlightListingsOperation (Round Trip) ========"); - if (flightListingsResponse.getSearchCities() != null) { - flightListingsResponse.getSearchCities().forEach(city -> { - LOGGER.info("======================== Search City Start ========================"); - LOGGER.info("City Code: {}", city.getCode()); - LOGGER.info("City Name: {}", city.getCity()); - LOGGER.info("Province: {}", city.getProvince()); - LOGGER.info("Country: {}", city.getCountry()); - LOGGER.info("======================== Search City End ========================"); - }); - } + GetFlightListingsOperationParams roundTripParams = GetFlightListingsOperationParams.builder().partnerTransactionID("txn-123-4").segment1(GetFlightListingsOperationSegmentParam.builder().origin("EWR").destination("LAX").departureDate(now.plusDays(10)).build()).segment2(GetFlightListingsOperationSegmentParam.builder().origin("LAX").destination("EWR").departureDate(now.plusDays(10)).build()).childrenAges(Arrays.asList(4, 5)).adult(1).senior(1).build(); - if (flightListingsResponse.getValidFormsOfPayment() != null) { - flightListingsResponse.getValidFormsOfPayment().forEach((key, value) -> { - LOGGER.info("================= Valid Forms of Payment Start [{}] ============", key); - value.forEach(payment -> { - LOGGER.info("---- Payment Method Start ----"); - LOGGER.info("Payment Method: {}", payment.getPaymentMethod()); - LOGGER.info("Name: {}", payment.getName()); - LOGGER.info("Fee: {}", payment.getFee()); - LOGGER.info("Currency: {}", payment.getCurrency()); - LOGGER.info("---- Payment Method End ----"); - }); - LOGGER.info("========== Valid Forms of Payment End [{}] ============", key); - }); - } + FlightSearchResponse roundTripResponse = xapClient.execute(new GetFlightListingsOperation(roundTripParams)).getData(); - LOGGER.info( - "===================== End FlightListingsQuickStartScenario ===================="); - - // --- Example for a Round Trip Search --- - LOGGER.info( - "\n======== Executing GetFlightListingsOperation (Round Trip) ========"); - - GetFlightListingsOperationParams roundTripParams = - GetFlightListingsOperationParams.builder() - .partnerTransactionID("txn-123-4") - .segment1Origin("EWR") - .segment1Destination("LAX") - .segment1DepartureDate(LocalDate.of(2025, 5, 1)) - .segment2Origin("LAX") - .segment2Destination("EWR") - .segment2DepartureDate(LocalDate.of(2025, 5, 5)) - .childrenAges(Arrays.asList(4, 5)) - .adult(1) - .senior(1) - .build(); - - FlightSearchResponse roundTripResponse = - xapClient.execute(new GetFlightListingsOperation(roundTripParams)).getData(); - - LOGGER.info( - "========= GetFlightListingsOperation (Round Trip) Executed =============="); - - if (roundTripResponse != null && roundTripResponse.getSegments() != null - && roundTripResponse.getSegments().size() == 2) { - LOGGER.info("Round trip search returned {} segments.", - roundTripResponse.getSegments().size()); - } + LOGGER.info("========= GetFlightListingsOperation (Round Trip) Executed =============="); + + if (roundTripResponse != null && roundTripResponse.getSegments() != null && roundTripResponse.getSegments().size() == 2) { + LOGGER.info("Round trip search returned {} segments.", roundTripResponse.getSegments().size()); + } + + // --- Example for a Multi-Stop Search --- + LOGGER.info("\n========= Executing GetFlightListingsOperation (Multi-Stop) =========="); + + GetFlightListingsOperationParams multiStopParams = GetFlightListingsOperationParams.builder().partnerTransactionID("txn-123-4").segment1(GetFlightListingsOperationSegmentParam.builder().origin("LAS").destination("ATL").departureDate(now.plusDays(5)).build()).segment2(GetFlightListingsOperationSegmentParam.builder().origin("ORD").destination("SEA").departureDate(now.plusDays(10)).build()).adult(1).senior(1).childrenAges(Arrays.asList(4, 5)).build(); - // --- Example for a Multi-Stop Search --- - LOGGER.info( - "\n========= Executing GetFlightListingsOperation (Multi-Stop) =========="); - - GetFlightListingsOperationParams multiStopParams = - GetFlightListingsOperationParams.builder() - .partnerTransactionID("txn-123-4") - .segment1Origin("LAS") - .segment1Destination("ATL") - .segment1DepartureDate(LocalDate.of(2025, 5, 1)) - .segment2Origin("ORD") - .segment2Destination("SEA") - .segment2DepartureDate(LocalDate.of(2025, 5, 5)) - .adult(1) - .senior(1) - .childrenAges(Arrays.asList(4, 5)) - .build(); - - FlightSearchResponse multiStopResponse = - xapClient.execute(new GetFlightListingsOperation(multiStopParams)).getData(); - - LOGGER.info( - "============ GetFlightListingsOperation (Multi-Stop) Executed ==========="); - - if (multiStopResponse != null && multiStopResponse.getSegments() != null - && multiStopResponse.getSegments().size() == 3) { - LOGGER.info("Multi-stop search returned {} segments.", - multiStopResponse.getSegments().size()); + FlightSearchResponse multiStopResponse = xapClient.execute(new GetFlightListingsOperation(multiStopParams)).getData(); + + LOGGER.info("============ GetFlightListingsOperation (Multi-Stop) Executed ==========="); + + if (multiStopResponse != null && multiStopResponse.getSegments() != null && multiStopResponse.getSegments().size() == 3) { + LOGGER.info("Multi-stop search returned {} segments.", multiStopResponse.getSegments().size()); + } } - } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/AvailabilityCalendarsQuickStartScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/AvailabilityCalendarsQuickStartScenario.java index fc645a330..7b848f6d6 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/AvailabilityCalendarsQuickStartScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/AvailabilityCalendarsQuickStartScenario.java @@ -20,8 +20,10 @@ import com.expediagroup.sdk.xap.models.AvailabilityCalendarResponse; import com.expediagroup.sdk.xap.operations.GetLodgingAvailabilityCalendarsOperation; import com.expediagroup.sdk.xap.operations.GetLodgingAvailabilityCalendarsOperationParams; + import java.util.Arrays; import java.util.HashSet; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,78 +34,61 @@ *

Note: this is a Vrbo scenario. You need a key that is enabled for Vrbo brand to run this. */ public class AvailabilityCalendarsQuickStartScenario implements VrboScenario { + private static final Logger LOGGER = LoggerFactory.getLogger(AvailabilityCalendarsQuickStartScenario.class); - private static final Logger LOGGER = - LoggerFactory.getLogger(AvailabilityCalendarsQuickStartScenario.class); - - public static void main(String[] args) { - new AvailabilityCalendarsQuickStartScenario().run(); - System.exit(0); - } - - @Override - public void run() { - // This example returns the availability of each day for a range of dates for given Expedia - // lodging properties. + public static void main(String[] args) { + new AvailabilityCalendarsQuickStartScenario().run(); + System.exit(0); + } - LOGGER.info( - "=================== Running AvailabilityCalendarsQuickStartScenario ==================="); + @Override + public void run() { + // This example returns the availability of each day for a range of dates for given Expedia + // lodging properties. - LOGGER.info( - "================= Executing GetLodgingAvailabilityCalendars Operation ================"); + LOGGER.info("=================== Running AvailabilityCalendarsQuickStartScenario ==================="); + LOGGER.info("================= Executing GetLodgingAvailabilityCalendars Operation ================"); - // Build the query parameters with GetLodgingAvailabilityCalendarsOperationParams - GetLodgingAvailabilityCalendarsOperationParams availabilityCalendarsOperationParams = - GetLodgingAvailabilityCalendarsOperationParams.builder() - .partnerTransactionId(PARTNER_TRANSACTION_ID) + // Build the query parameters with GetLodgingAvailabilityCalendarsOperationParams + GetLodgingAvailabilityCalendarsOperationParams availabilityCalendarsOperationParams = GetLodgingAvailabilityCalendarsOperationParams.builder().partnerTransactionId(PARTNER_TRANSACTION_ID) // Set of Expedia Property IDs. - .propertyIds(new HashSet<>(Arrays.asList("87704892", "36960201"))) - .build(); - - XapClient xapClient = createClient(); - - // Execute the operation and get the AvailabilityCalendarsResponse - AvailabilityCalendarResponse availabilityCalendarResponse = - xapClient.execute(new GetLodgingAvailabilityCalendarsOperation( - availabilityCalendarsOperationParams)).getData(); - - // If you want to use the async method, you can use the following code: - // --------------------------------------------------------------- - // CompletableFuture> completableFuture = - // xapClient.executeAsync( - // new GetLodgingAvailabilityCalendarsOperation(availabilityCalendarsOperationParams)); - // completableFuture.thenAccept(availCalendarResponse -> { - // // Your code here - // }); - // --------------------------------------------------------------- - - LOGGER.info( - "================== GetLodgingAvailabilityCalendarsOperation Executed ================="); - - if (availabilityCalendarResponse == null - || availabilityCalendarResponse.getAvailabilityCalendars() == null - || availabilityCalendarResponse.getAvailabilityCalendars().isEmpty()) { - throw new IllegalStateException("No properties found."); + .propertyIds(new HashSet<>(Arrays.asList("87704892", "36960201"))).build(); + + XapClient xapClient = createClient(); + + // Execute the operation and get the AvailabilityCalendarsResponse + AvailabilityCalendarResponse availabilityCalendarResponse = xapClient.execute(new GetLodgingAvailabilityCalendarsOperation(availabilityCalendarsOperationParams)).getData(); + + // If you want to use the async method, you can use the following code: + // --------------------------------------------------------------- + // CompletableFuture> completableFuture = + // xapClient.executeAsync( + // new GetLodgingAvailabilityCalendarsOperation(availabilityCalendarsOperationParams)); + // completableFuture.thenAccept(availCalendarResponse -> { + // // Your code here + // }); + // --------------------------------------------------------------- + + LOGGER.info("================== GetLodgingAvailabilityCalendarsOperation Executed ================="); + + if (availabilityCalendarResponse == null || availabilityCalendarResponse.getAvailabilityCalendars() == null || availabilityCalendarResponse.getAvailabilityCalendars().isEmpty()) { + throw new IllegalStateException("No properties found."); + } + + // The AvailabilityCalendarsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", availabilityCalendarResponse.getTransactionId()); + + // To access the properties, iterate through the list of properties + availabilityCalendarResponse.getAvailabilityCalendars().forEach(availCalendar -> { + LOGGER.info("========== Property:{} Start ==========", availCalendar.getPropertyId()); + + // Availability of property: A string of codes that shows property availability, one for every + // day in the specified date range. + // Valid values include Y (available) and N (unavailable). + LOGGER.info("Availability: {}", availCalendar.getAvailability()); + LOGGER.info("==================================== Property End ==================================="); + LOGGER.info("===================== End AvailabilityCalendarsQuickStartScenario ===================="); + }); } - - // The AvailabilityCalendarsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", availabilityCalendarResponse.getTransactionId()); - - // To access the properties, iterate through the list of properties - availabilityCalendarResponse.getAvailabilityCalendars().forEach(availCalendar -> { - LOGGER.info("========== Property:{} Start ==========", availCalendar.getPropertyId()); - - // Availability of property: A string of codes that shows property availability, one for every - // day in the specified date range. - // Valid values include Y (available) and N (unavailable). - LOGGER.info("Availability: {}", availCalendar.getAvailability()); - - LOGGER.info( - "==================================== Property End ==================================="); - - LOGGER.info( - "===================== End AvailabilityCalendarsQuickStartScenario ===================="); - }); - } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java index c83875a16..e7c07b386 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java @@ -29,6 +29,7 @@ import com.expediagroup.sdk.xap.operations.GetLodgingListingsOperationParams; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -43,6 +44,7 @@ import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,99 +57,85 @@ * property id list, content and prices to improve respond time of your pages. */ public class HotelIdsSearchEndToEndScenario implements XapScenario { + private final XapClient client = createClient(); - private final XapClient client = createClient(); - - private static final Logger LOGGER = - LoggerFactory.getLogger(HotelIdsSearchEndToEndScenario.class); + private static final Logger LOGGER = LoggerFactory.getLogger(HotelIdsSearchEndToEndScenario.class); - /** - * This field limits the number of line to read from the SDP DownloadURL API Listings file to - * reduce time to run the example. - * If the first 20 properties from the file are not accessible OR available when you run this - * example, it may end with "No accessible property ids found." OR NO_RESULT_FOUND. In that case, - * you can adjust the property count to get more properties. - */ - private static final int SAMPLE_ITEMS_RESTRICTION = 20; + /** + * This field limits the number of line to read from the SDP DownloadURL API Listings file to + * reduce time to run the example. + * If the first 20 properties from the file are not accessible OR available when you run this + * example, it may end with "No accessible property ids found." OR NO_RESULT_FOUND. In that case, + * you can adjust the property count to get more properties. + */ + private static final int SAMPLE_ITEMS_RESTRICTION = 20; - public static void main(String[] args) { - new HotelIdsSearchEndToEndScenario().run(); - System.exit(0); - } + public static void main(String[] args) { + new HotelIdsSearchEndToEndScenario().run(); + System.exit(0); + } - @Override - public void run() { - LOGGER.info( - "======================== Running HotelIdsSearchEndToEndScenario ======================="); + @Override + public void run() { + LOGGER.info("======================== Running HotelIdsSearchEndToEndScenario ======================="); - List propertyIds = getPropertyIdsFromDownloadUrl(); - HotelListingsResponse hotelListingsResponse = getPropertiesFromLodgingListings(propertyIds); - displayResult(hotelListingsResponse); + List propertyIds = getPropertyIdsFromDownloadUrl(); + HotelListingsResponse hotelListingsResponse = getPropertiesFromLodgingListings(propertyIds); + displayResult(hotelListingsResponse); - LOGGER.info( - "========================== End HotelIdsSearchEndToEndScenario ========================="); - } + LOGGER.info("========================== End HotelIdsSearchEndToEndScenario ========================="); + } - /** - * Retrieve accessible property ids from SDP DownloadURL API. - * - * @return property ids - */ - private List getPropertyIdsFromDownloadUrl() { - LOGGER.info( - "==================== Executing Step I: getPropertyIdsFromDownloadUrl ==================="); + /** + * Retrieve accessible property ids from SDP DownloadURL API. + * + * @return property ids + */ + private List getPropertyIdsFromDownloadUrl() { + LOGGER.info("==================== Executing Step I: getPropertyIdsFromDownloadUrl ==================="); - GetFeedDownloadUrlOperationParams getPropertyIdListParams = - GetFeedDownloadUrlOperationParams.builder() + GetFeedDownloadUrlOperationParams getPropertyIdListParams = GetFeedDownloadUrlOperationParams.builder() // Use the type LISTINGS to get the list of accessible property ids. .type(GetFeedDownloadUrlOperationParams.Type.LISTINGS) // Without any filters, this operation will return the information of all lodging // properties in en_US by default. .build(); - Response downloadUrlListingsResponse = - client.execute(new GetFeedDownloadUrlOperation(getPropertyIdListParams)); + Response downloadUrlListingsResponse = client.execute(new GetFeedDownloadUrlOperation(getPropertyIdListParams)); - if (downloadUrlListingsResponse.getData() == null - || downloadUrlListingsResponse.getData().getBestMatchedFile() == null) { - throw new IllegalStateException("No listings file found"); - } + if (downloadUrlListingsResponse.getData() == null || downloadUrlListingsResponse.getData().getBestMatchedFile() == null) { + throw new IllegalStateException("No listings file found"); + } - // The download URL points to a zip file containing various jsonl files. - // Each line in the jsonl files contains a json object representing a property. - // For demonstration purposes, we will only read a few properties from the file without - // downloading the entire file. - String listingsDownloadUrl = downloadUrlListingsResponse.getData() - .getBestMatchedFile() - .getDownloadUrl(); - LOGGER.info("Listings Download URL: {}", listingsDownloadUrl); + // The download URL points to a zip file containing various jsonl files. + // Each line in the jsonl files contains a json object representing a property. + // For demonstration purposes, we will only read a few properties from the file without + // downloading the entire file. + String listingsDownloadUrl = downloadUrlListingsResponse.getData().getBestMatchedFile().getDownloadUrl(); + LOGGER.info("Listings Download URL: {}", listingsDownloadUrl); - // Read property ids from the file. - List propertyIds = getPropertyIdsFromListingsFile(listingsDownloadUrl); + // Read property ids from the file. + List propertyIds = getPropertyIdsFromListingsFile(listingsDownloadUrl); - if (propertyIds.isEmpty()) { - throw new IllegalStateException("No accessible property ids found."); - } - LOGGER.info("Accessible Property Ids: {}", propertyIds); + if (propertyIds.isEmpty()) { + throw new IllegalStateException("No accessible property ids found."); + } + LOGGER.info("Accessible Property Ids: {}", propertyIds); + LOGGER.info("==================== Step I: getPropertyIdsFromDownloadUrl Executed ===================="); - LOGGER.info( - "==================== Step I: getPropertyIdsFromDownloadUrl Executed ===================="); - return propertyIds; - } + return propertyIds; + } - /** - * Get prices of the properties using the Lodging Listings API. - * - * @param propertyIds The property ids to get the prices. - * @return The response of the Lodging Listings API. - */ - private HotelListingsResponse getPropertiesFromLodgingListings(List propertyIds) { - LOGGER.info( - "================ Step II: Executing getPropertiesFromLodgingListings ==============="); + /** + * Get prices of the properties using the Lodging Listings API. + * + * @param propertyIds The property ids to get the prices. + * @return The response of the Lodging Listings API. + */ + private HotelListingsResponse getPropertiesFromLodgingListings(List propertyIds) { + LOGGER.info("================ Step II: Executing getPropertiesFromLodgingListings ==============="); - GetLodgingListingsOperationParams getLodgingListingsOperationParams = - GetLodgingListingsOperationParams.builder() - .partnerTransactionId(PARTNER_TRANSACTION_ID) + GetLodgingListingsOperationParams getLodgingListingsOperationParams = GetLodgingListingsOperationParams.builder().partnerTransactionId(PARTNER_TRANSACTION_ID) // Use the property ids read from the file .ecomHotelIds(new HashSet<>(propertyIds)) // The links to return, WEB includes WS (Web Search Result Page) @@ -162,43 +150,39 @@ private HotelListingsResponse getPropertiesFromLodgingListings(List prop // Use the default occupancy: 2 adults in one room .build(); - HotelListingsResponse hotelListingsResponse = - client.execute(new GetLodgingListingsOperation(getLodgingListingsOperationParams)) - .getData(); + HotelListingsResponse hotelListingsResponse = client.execute(new GetLodgingListingsOperation(getLodgingListingsOperationParams)).getData(); + LOGGER.info("================ Step II: getPropertiesFromLodgingListings Executed ================"); - LOGGER.info( - "================ Step II: getPropertiesFromLodgingListings Executed ================"); - return hotelListingsResponse; - } + return hotelListingsResponse; + } - /** - * Reads given number of property ids from the file pointed by the download URL. - * - * @param downloadUrl The download URL of the zip file containing the property information. - * @return A list of property ids read from the file. - */ - private List getPropertyIdsFromListingsFile(String downloadUrl) { - List propertyIds = new ArrayList<>(); - HttpURLConnection connection = null; - try { - // Open a connection to the URL - URL url = new URL(downloadUrl); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setDoInput(true); + /** + * Reads given number of property ids from the file pointed by the download URL. + * + * @param downloadUrl The download URL of the zip file containing the property information. + * @return A list of property ids read from the file. + */ + private List getPropertyIdsFromListingsFile(String downloadUrl) { + List propertyIds = new ArrayList<>(); + HttpURLConnection connection = null; + try { + // Open a connection to the URL + URL url = new URL(downloadUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setDoInput(true); - try (ZipInputStream zipStream = new ZipInputStream(connection.getInputStream())) { - ZipEntry entry; - while ((entry = zipStream.getNextEntry()) != null) { - if (entry.getName().endsWith(".jsonl")) { - LOGGER.info("Reading property ids from file: {}", entry.getName()); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(zipStream))) { - String line; - ObjectMapper objectMapper = new ObjectMapper(); - while ((line = reader.readLine()) != null - && propertyIds.size() < SAMPLE_ITEMS_RESTRICTION) { - // Parse the property id from the json object - // An example json line from the jsonl file: + try (ZipInputStream zipStream = new ZipInputStream(connection.getInputStream())) { + ZipEntry entry; + while ((entry = zipStream.getNextEntry()) != null) { + if (entry.getName().endsWith(".jsonl")) { + LOGGER.info("Reading property ids from file: {}", entry.getName()); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(zipStream))) { + String line; + ObjectMapper objectMapper = new ObjectMapper(); + while ((line = reader.readLine()) != null && propertyIds.size() < SAMPLE_ITEMS_RESTRICTION) { + // Parse the property id from the json object + // An example json line from the jsonl file: /* { "propertyId": { @@ -227,126 +211,113 @@ private List getPropertyIdsFromListingsFile(String downloadUrl) { } } */ - JsonNode jsonNode = objectMapper.readTree(line); - // Check if the property is accessible from Lodging Listings API - // (Vrbo properties that are not instantBookable are not accessible for now) - if (!jsonNode.get("propertyId").get("vrbo").asText().isEmpty() - && jsonNode.has("vrboPropertyType") - && !jsonNode.get("vrboPropertyType").get("instantBook").asBoolean() - ) { - // Skip the property if it is not an instant bookable Vrbo property - continue; - } else { - // Get the Expedia property id for the Lodging Listings API - propertyIds.add(jsonNode.get("propertyId").get("expedia").asText()); + JsonNode jsonNode = objectMapper.readTree(line); + // Check if the property is accessible from Lodging Listings API + // (Vrbo properties that are not instantBookable are not accessible for now) + if (!jsonNode.get("propertyId").get("vrbo").asText().isEmpty() && jsonNode.has("vrboPropertyType") && !jsonNode.get("vrboPropertyType").get("instantBook").asBoolean()) { + // Skip the property if it is not an instant bookable Vrbo property + continue; + } else { + // Get the Expedia property id for the Lodging Listings API + propertyIds.add(jsonNode.get("propertyId").get("expedia").asText()); + } + } + } + } } - } } - } - } - } - } catch (IOException e) { - LOGGER.error("Error reading property ids from download URL", e); - } finally { - if (connection != null) { - connection.disconnect(); - } + } catch (IOException e) { + LOGGER.error("Error reading property ids from download URL", e); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return propertyIds; } - return propertyIds; - } - /** - * Display the result of the operations. - * - * @param hotelListingsResponse The response of the Lodging Listings API. - */ - private static void displayResult(HotelListingsResponse hotelListingsResponse) { - LOGGER.info("====================== Executing Step III: DisplayResult ======================="); - if (hotelListingsResponse == null || hotelListingsResponse.getHotels() == null - || hotelListingsResponse.getHotels().isEmpty()) { - throw new IllegalStateException("No properties found."); - } + /** + * Display the result of the operations. + * + * @param hotelListingsResponse The response of the Lodging Listings API. + */ + private static void displayResult(HotelListingsResponse hotelListingsResponse) { + LOGGER.info("====================== Executing Step III: DisplayResult ======================="); + if (hotelListingsResponse == null || hotelListingsResponse.getHotels() == null || hotelListingsResponse.getHotels().isEmpty()) { + throw new IllegalStateException("No properties found."); + } - // The HotelListingsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", hotelListingsResponse.getTransactionId()); + // The HotelListingsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", hotelListingsResponse.getTransactionId()); - // To access the properties, iterate through the list of hotel properties - hotelListingsResponse.getHotels().forEach(hotel -> { - // Check if the property is available - if (Hotel.Status.AVAILABLE != hotel.getStatus()) { - LOGGER.info("Property {} is not available.", hotel.getId()); - return; - } - LOGGER.info( - "=================================== Property Start ==================================="); - // To get the property name - if (StringUtils.isNotEmpty(hotel.getName())) { - LOGGER.info("Property Name: {}", hotel.getName()); - } - // To get the property address - if (hotel.getLocation() != null) { - LOGGER.info("Property Address: {}", hotel.getLocation().getAddress()); - } - // To get the property thumbnail URL - if (StringUtils.isNotEmpty(hotel.getThumbnailUrl())) { - LOGGER.info("Thumbnail URL: {}", hotel.getThumbnailUrl()); - } - // To get the star rating of the property. The value is between 1.0 and 5.0 - // in a 0.5 increment. - if (hotel.getStarRating() != null) { - LOGGER.info("Star Rating: {}", hotel.getStarRating().getValue()); - } - // To get the guest rating of the property. The value is between 1.0 and 5.0 - // in a 0.1 increment. - if (StringUtils.isNotEmpty(hotel.getGuestRating())) { - LOGGER.info("Guest Rating: {}", hotel.getGuestRating()); - } - // To get the total number of reviews for the property - if (hotel.getGuestReviewCount() != null) { - LOGGER.info("Review Count: {}", hotel.getGuestReviewCount()); - } - if (hotel.getRoomTypes() != null && !hotel.getRoomTypes().isEmpty()) { - // To get the first room type information - RoomType roomType = hotel.getRoomTypes().get(0); - if (StringUtils.isNotEmpty(roomType.getDescription())) { - LOGGER.info("Room Type: {}", roomType.getDescription()); - } - if (roomType.getPrice() != null) { - // To get the total price of the room type - if (roomType.getPrice().getTotalPrice() != null) { - LOGGER.info("Price: {}, Currency: {}", - roomType.getPrice().getTotalPrice().getValue(), - roomType.getPrice().getTotalPrice().getCurrency()); - } - // To get the average nightly rate of the room type - if (roomType.getPrice().getAvgNightlyRate() != null) { - LOGGER.info("Average Nightly Rate: {}, Currency: {}", - roomType.getPrice().getAvgNightlyRate().getValue(), - roomType.getPrice().getAvgNightlyRate().getCurrency()); - } - } - // To get the free cancellation flag of the selected room - if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() - && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { - LOGGER.info("Free Cancellation: {}", - roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); - } - if (roomType.getLinks() != null) { - // To get the deeplink to the Expedia Web Search Result Page - if (roomType.getLinks().getWebSearchResult() != null) { - LOGGER.info("WebSearchResult Link: {}", - roomType.getLinks().getWebSearchResult().getHref()); - } - // To get the deeplink to the Expedia Web Details Page - if (roomType.getLinks().getWebDetails() != null) { - LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); - } - } - } - LOGGER.info( - "==================================== Property End ===================================="); - }); - LOGGER.info("====================== Step III: DisplayResult Executed ========================"); - } + // To access the properties, iterate through the list of hotel properties + hotelListingsResponse.getHotels().forEach(hotel -> { + // Check if the property is available + if (Hotel.Status.AVAILABLE != hotel.getStatus()) { + LOGGER.info("Property {} is not available.", hotel.getId()); + return; + } + LOGGER.info("=================================== Property Start ==================================="); + // To get the property name + if (StringUtils.isNotEmpty(hotel.getName())) { + LOGGER.info("Property Name: {}", hotel.getName()); + } + // To get the property address + if (hotel.getLocation() != null) { + LOGGER.info("Property Address: {}", hotel.getLocation().getAddress()); + } + // To get the property thumbnail URL + if (StringUtils.isNotEmpty(hotel.getThumbnailUrl())) { + LOGGER.info("Thumbnail URL: {}", hotel.getThumbnailUrl()); + } + // To get the star rating of the property. The value is between 1.0 and 5.0 + // in a 0.5 increment. + if (hotel.getStarRating() != null) { + LOGGER.info("Star Rating: {}", hotel.getStarRating().getValue()); + } + // To get the guest rating of the property. The value is between 1.0 and 5.0 + // in a 0.1 increment. + if (StringUtils.isNotEmpty(hotel.getGuestRating())) { + LOGGER.info("Guest Rating: {}", hotel.getGuestRating()); + } + // To get the total number of reviews for the property + if (hotel.getGuestReviewCount() != null) { + LOGGER.info("Review Count: {}", hotel.getGuestReviewCount()); + } + if (hotel.getRoomTypes() != null && !hotel.getRoomTypes().isEmpty()) { + // To get the first room type information + RoomType roomType = hotel.getRoomTypes().get(0); + if (StringUtils.isNotEmpty(roomType.getDescription())) { + LOGGER.info("Room Type: {}", roomType.getDescription()); + } + if (roomType.getPrice() != null) { + // To get the total price of the room type + if (roomType.getPrice().getTotalPrice() != null) { + LOGGER.info("Price: {}, Currency: {}", roomType.getPrice().getTotalPrice().getValue(), roomType.getPrice().getTotalPrice().getCurrency()); + } + // To get the average nightly rate of the room type + if (roomType.getPrice().getAvgNightlyRate() != null) { + LOGGER.info("Average Nightly Rate: {}, Currency: {}", roomType.getPrice().getAvgNightlyRate().getValue(), roomType.getPrice().getAvgNightlyRate().getCurrency()); + } + } + // To get the free cancellation flag of the selected room + if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { + LOGGER.info("Free Cancellation: {}", roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); + } + if (roomType.getLinks() != null) { + // To get the deeplink to the Expedia Web Search Result Page + if (roomType.getLinks().getWebSearchResult() != null) { + LOGGER.info("WebSearchResult Link: {}", roomType.getLinks().getWebSearchResult().getHref()); + } + // To get the deeplink to the Expedia Web Details Page + if (roomType.getLinks().getWebDetails() != null) { + LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); + } + } + } + LOGGER.info("==================================== Property End ===================================="); + }); + LOGGER.info("====================== Step III: DisplayResult Executed ========================"); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/ListingsQuickStartScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/ListingsQuickStartScenario.java index 4d1cb73fe..0c3ba0183 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/ListingsQuickStartScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/ListingsQuickStartScenario.java @@ -24,9 +24,11 @@ import com.expediagroup.sdk.xap.models.RoomType; import com.expediagroup.sdk.xap.operations.GetLodgingListingsOperation; import com.expediagroup.sdk.xap.operations.GetLodgingListingsOperationParams; + import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,45 +38,39 @@ * applied. */ public class ListingsQuickStartScenario implements XapScenario { + private static final Logger LOGGER = LoggerFactory.getLogger(ListingsQuickStartScenario.class); + + public static void main(String[] args) { + new ListingsQuickStartScenario().run(); + System.exit(0); + } - private static final Logger LOGGER = LoggerFactory.getLogger(ListingsQuickStartScenario.class); - - public static void main(String[] args) { - new ListingsQuickStartScenario().run(); - System.exit(0); - } - - @Override - public void run() { - // This example will search for properties with the following criteria: - // 1. Occupancy of 1 adult in the first room and 2 adults and 2 children (10 and 12 years old) - // in the second room; - // 2. Properties located within 10 km of the Space Needle in Seattle; - // 3. Check-in date 5 days from now, check-out date 10 days from now; - // 4. Return web links to Expedia website; - // 5. Limit the results to 5 properties; - // 6. Order the results by price in ascending order. - - LOGGER.info( - "========================== Running ListingsQuickStartScenario ========================="); - - LOGGER.info( - "======================== Executing GetLodgingListingsOperation ======================="); - - // Build the occupancy - ArrayList rooms = new ArrayList<>(); - // The first room, with 1 adult - rooms.add(Room.builder().adults(1L).build()); - // The second room, with 2 adults and 2 children - ArrayList childrenAges = new ArrayList<>(); - childrenAges.add(10L); - childrenAges.add(12L); - rooms.add(Room.builder().adults(2L).childAges(childrenAges).build()); - - // Build the query parameters with GetLodgingListingsOperationParams - GetLodgingListingsOperationParams getLodgingListingsOperationParams = - GetLodgingListingsOperationParams.builder() - .partnerTransactionId(PARTNER_TRANSACTION_ID) + @Override + public void run() { + // This example will search for properties with the following criteria: + // 1. Occupancy of 1 adult in the first room and 2 adults and 2 children (10 and 12 years old) + // in the second room; + // 2. Properties located within 10 km of the Space Needle in Seattle; + // 3. Check-in date 5 days from now, check-out date 10 days from now; + // 4. Return web links to Expedia website; + // 5. Limit the results to 5 properties; + // 6. Order the results by price in ascending order. + + LOGGER.info("========================== Running ListingsQuickStartScenario ========================="); + LOGGER.info("======================== Executing GetLodgingListingsOperation ======================="); + + // Build the occupancy + ArrayList rooms = new ArrayList<>(); + // The first room, with 1 adult + rooms.add(Room.builder().adults(1L).build()); + // The second room, with 2 adults and 2 children + ArrayList childrenAges = new ArrayList<>(); + childrenAges.add(10L); + childrenAges.add(12L); + rooms.add(Room.builder().adults(2L).childAges(childrenAges).build()); + + // Build the query parameters with GetLodgingListingsOperationParams + GetLodgingListingsOperationParams getLodgingListingsOperationParams = GetLodgingListingsOperationParams.builder().partnerTransactionId(PARTNER_TRANSACTION_ID) // The location keyword can be a city, address, airport or a landmark. .locationKeyword("Space Needle, Seattle") // The radius specifies the size of search area around the location keyword. @@ -94,116 +90,100 @@ public void run() { // Limit the results to 5 properties .limit(5) // Order the results by price in ascending order - .sortType(GetLodgingListingsOperationParams.SortType.PRICE) - .sortOrder(GetLodgingListingsOperationParams.SortOrder.ASC) - .build(); - - XapClient xapClient = createClient(); - - // Execute the operation and get the HotelListingsResponse - HotelListingsResponse hotelListingsResponse = - xapClient.execute(new GetLodgingListingsOperation(getLodgingListingsOperationParams)) - .getData(); - - // If you want to use the async method, you can use the following code: - // --------------------------------------------------------------- - // CompletableFuture> completableFuture = - // xapClient.executeAsync( - // new GetLodgingListingsOperation(getLodgingListingsOperationParams)); - // completableFuture.thenAccept(hotelListingsResponse -> { - // // Your code here - // }); - // --------------------------------------------------------------- - - LOGGER.info( - "======================== GetLodgingListingsOperation Executed ========================"); - - if (hotelListingsResponse == null || hotelListingsResponse.getHotels() == null - || hotelListingsResponse.getHotels().isEmpty()) { - throw new IllegalStateException("No properties found."); - } + .sortType(GetLodgingListingsOperationParams.SortType.PRICE).sortOrder(GetLodgingListingsOperationParams.SortOrder.ASC).build(); - // The HotelListingsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", hotelListingsResponse.getTransactionId()); - - // To access the properties, iterate through the list of hotel properties - hotelListingsResponse.getHotels().forEach(hotel -> { - // Check if the property is available - if (Hotel.Status.AVAILABLE != hotel.getStatus()) { - LOGGER.info("Property {} is not available.", hotel.getId()); - return; - } - LOGGER.info( - "=================================== Property Start ==================================="); - // To get the property name - if (StringUtils.isNotEmpty(hotel.getName())) { - LOGGER.info("Property Name: {}", hotel.getName()); - } - // To get the property address - if (hotel.getLocation() != null) { - LOGGER.info("Property Address: {}", hotel.getLocation().getAddress()); - } - // To get the property thumbnail URL - if (StringUtils.isNotEmpty(hotel.getThumbnailUrl())) { - LOGGER.info("Thumbnail URL: {}", hotel.getThumbnailUrl()); - } - // To get the star rating of the property. The value is between 1.0 and 5.0 - // in a 0.5 increment. - if (hotel.getStarRating() != null) { - LOGGER.info("Star Rating: {}", hotel.getStarRating().getValue()); - } - // To get the guest rating of the property. The value is between 1.0 and 5.0 - // in a 0.1 increment. - if (StringUtils.isNotEmpty(hotel.getGuestRating())) { - LOGGER.info("Guest Rating: {}", hotel.getGuestRating()); - } - // To get the total number of reviews for the property - if (hotel.getGuestReviewCount() != null) { - LOGGER.info("Review Count: {}", hotel.getGuestReviewCount()); - } - if (hotel.getRoomTypes() != null && !hotel.getRoomTypes().isEmpty()) { - // To get the first room type information - RoomType roomType = hotel.getRoomTypes().get(0); - if (StringUtils.isNotEmpty(roomType.getDescription())) { - LOGGER.info("Room Type: {}", roomType.getDescription()); - } - if (roomType.getPrice() != null) { - // To get the total price of the room type - if (roomType.getPrice().getTotalPrice() != null) { - LOGGER.info("Price: {}, Currency: {}", - roomType.getPrice().getTotalPrice().getValue(), - roomType.getPrice().getTotalPrice().getCurrency()); - } - // To get the average nightly rate of the room type - if (roomType.getPrice().getAvgNightlyRate() != null) { - LOGGER.info("Average Nightly Rate: {}, Currency: {}", - roomType.getPrice().getAvgNightlyRate().getValue(), - roomType.getPrice().getAvgNightlyRate().getCurrency()); - } - } - // To get the free cancellation flag of the selected room - if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() - && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { - LOGGER.info("Free Cancellation: {}", - roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); - } - if (roomType.getLinks() != null) { - // To get the deeplink to the Expedia Web Search Result Page - if (roomType.getLinks().getWebSearchResult() != null) { - LOGGER.info("WebSearchResult Link: {}", - roomType.getLinks().getWebSearchResult().getHref()); - } - // To get the deeplink to the Expedia Web Details Page - if (roomType.getLinks().getWebDetails() != null) { - LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); - } + XapClient xapClient = createClient(); + + // Execute the operation and get the HotelListingsResponse + HotelListingsResponse hotelListingsResponse = xapClient.execute(new GetLodgingListingsOperation(getLodgingListingsOperationParams)).getData(); + + // If you want to use the async method, you can use the following code: + // --------------------------------------------------------------- + // CompletableFuture> completableFuture = + // xapClient.executeAsync( + // new GetLodgingListingsOperation(getLodgingListingsOperationParams)); + // completableFuture.thenAccept(hotelListingsResponse -> { + // // Your code here + // }); + // --------------------------------------------------------------- + + LOGGER.info("======================== GetLodgingListingsOperation Executed ========================"); + + if (hotelListingsResponse == null || hotelListingsResponse.getHotels() == null || hotelListingsResponse.getHotels().isEmpty()) { + throw new IllegalStateException("No properties found."); } - } - LOGGER.info( - "==================================== Property End ===================================="); - }); - - LOGGER.info( - "============================ End ListingsQuickStartScenario ==========================="); - } + + // The HotelListingsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", hotelListingsResponse.getTransactionId()); + + // To access the properties, iterate through the list of hotel properties + hotelListingsResponse.getHotels().forEach(hotel -> { + // Check if the property is available + if (Hotel.Status.AVAILABLE != hotel.getStatus()) { + LOGGER.info("Property {} is not available.", hotel.getId()); + return; + } + LOGGER.info("=================================== Property Start ==================================="); + // To get the property name + if (StringUtils.isNotEmpty(hotel.getName())) { + LOGGER.info("Property Name: {}", hotel.getName()); + } + // To get the property address + if (hotel.getLocation() != null) { + LOGGER.info("Property Address: {}", hotel.getLocation().getAddress()); + } + // To get the property thumbnail URL + if (StringUtils.isNotEmpty(hotel.getThumbnailUrl())) { + LOGGER.info("Thumbnail URL: {}", hotel.getThumbnailUrl()); + } + // To get the star rating of the property. The value is between 1.0 and 5.0 + // in a 0.5 increment. + if (hotel.getStarRating() != null) { + LOGGER.info("Star Rating: {}", hotel.getStarRating().getValue()); + } + // To get the guest rating of the property. The value is between 1.0 and 5.0 + // in a 0.1 increment. + if (StringUtils.isNotEmpty(hotel.getGuestRating())) { + LOGGER.info("Guest Rating: {}", hotel.getGuestRating()); + } + // To get the total number of reviews for the property + if (hotel.getGuestReviewCount() != null) { + LOGGER.info("Review Count: {}", hotel.getGuestReviewCount()); + } + if (hotel.getRoomTypes() != null && !hotel.getRoomTypes().isEmpty()) { + // To get the first room type information + RoomType roomType = hotel.getRoomTypes().get(0); + if (StringUtils.isNotEmpty(roomType.getDescription())) { + LOGGER.info("Room Type: {}", roomType.getDescription()); + } + if (roomType.getPrice() != null) { + // To get the total price of the room type + if (roomType.getPrice().getTotalPrice() != null) { + LOGGER.info("Price: {}, Currency: {}", roomType.getPrice().getTotalPrice().getValue(), roomType.getPrice().getTotalPrice().getCurrency()); + } + // To get the average nightly rate of the room type + if (roomType.getPrice().getAvgNightlyRate() != null) { + LOGGER.info("Average Nightly Rate: {}, Currency: {}", roomType.getPrice().getAvgNightlyRate().getValue(), roomType.getPrice().getAvgNightlyRate().getCurrency()); + } + } + // To get the free cancellation flag of the selected room + if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { + LOGGER.info("Free Cancellation: {}", roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); + } + if (roomType.getLinks() != null) { + // To get the deeplink to the Expedia Web Search Result Page + if (roomType.getLinks().getWebSearchResult() != null) { + LOGGER.info("WebSearchResult Link: {}", roomType.getLinks().getWebSearchResult().getHref()); + } + // To get the deeplink to the Expedia Web Details Page + if (roomType.getLinks().getWebDetails() != null) { + LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); + } + } + } + LOGGER.info("==================================== Property End ===================================="); + }); + + LOGGER.info("============================ End ListingsQuickStartScenario ==========================="); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/QuotesQuickStartScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/QuotesQuickStartScenario.java index a4fa86f8b..ff7f1b704 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/QuotesQuickStartScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/QuotesQuickStartScenario.java @@ -23,11 +23,13 @@ import com.expediagroup.sdk.xap.models.Room; import com.expediagroup.sdk.xap.operations.GetLodgingQuotesOperation; import com.expediagroup.sdk.xap.operations.GetLodgingQuotesOperationParams; + import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,38 +39,32 @@ * Note: this is a Vrbo scenario. You need a key that is enabled for Vrbo brand to run this. */ public class QuotesQuickStartScenario implements VrboScenario { + private static final Logger LOGGER = LoggerFactory.getLogger(QuotesQuickStartScenario.class); + + public static void main(String[] args) { + new QuotesQuickStartScenario().run(); + System.exit(0); + } - private static final Logger LOGGER = LoggerFactory.getLogger(QuotesQuickStartScenario.class); - - public static void main(String[] args) { - new QuotesQuickStartScenario().run(); - System.exit(0); - } - - @Override - public void run() { - // This example will get quotes response for mentioned Expedia properties with the following - // criteria: - // 1. Occupancy of 1 adult in the first room and 2 adults and 2 children (10 and 12 years old) - // in the second room; - // 3. Check-in date 5 days from now, check-out date 10 days from now; - // 4. Return web links to Expedia website; - - LOGGER.info( - "============================ Running QuotesQuickStartScenario =========================="); - - LOGGER.info( - "========================= Executing GetLodgingQuotesOperation ========================="); - - // Build the occupancy - ArrayList rooms = new ArrayList<>(); - // The first room, with 2 adult - rooms.add(Room.builder().adults(2L).childAges(null).build()); - - // Build the query parameters with GetLodgingQuotesOperationParams - GetLodgingQuotesOperationParams quotesOperationParams = - GetLodgingQuotesOperationParams.builder() - .partnerTransactionId(PARTNER_TRANSACTION_ID) + @Override + public void run() { + // This example will get quotes response for mentioned Expedia properties with the following + // criteria: + // 1. Occupancy of 1 adult in the first room and 2 adults and 2 children (10 and 12 years old) + // in the second room; + // 3. Check-in date 5 days from now, check-out date 10 days from now; + // 4. Return web links to Expedia website; + + LOGGER.info("============================ Running QuotesQuickStartScenario =========================="); + LOGGER.info("========================= Executing GetLodgingQuotesOperation ========================="); + + // Build the occupancy + ArrayList rooms = new ArrayList<>(); + // The first room, with 2 adult + rooms.add(Room.builder().adults(2L).childAges(null).build()); + + // Build the query parameters with GetLodgingQuotesOperationParams + GetLodgingQuotesOperationParams quotesOperationParams = GetLodgingQuotesOperationParams.builder().partnerTransactionId(PARTNER_TRANSACTION_ID) // Check-in 5 days from now .checkIn(LocalDate.now().plusDays(5)) // Check-out 10 days from now @@ -77,85 +73,70 @@ public void run() { .propertyIds(new HashSet<>(Arrays.asList("87704892", "36960201"))) // The links to return, WEB includes WS (Web Search Result Page) and // WD (Web Details Page) - .links(Collections.singletonList(GetLodgingQuotesOperationParams.Links.WEB)) - .rooms(rooms) - .build(); - - XapClient xapClient = createClient(); - - // Execute the operation and get the QuotesResponse - LodgingQuotesResponse quotesResponse = - xapClient.execute(new GetLodgingQuotesOperation(quotesOperationParams)).getData(); - - // If you want to use the async method, you can use the following code: - // --------------------------------------------------------------- - // CompletableFuture> completableFuture = - // xapClient.executeAsync( - // new GetLodgingQuotesOperation(quotesOperationParams)); - // completableFuture.thenAccept(quotesResponse -> { - // // Your code here - // }); - // --------------------------------------------------------------- - - LOGGER.info( - "========================== GetLodgingQuotesOperation Executed ========================="); - - if (quotesResponse == null || quotesResponse.getProperties() == null - || quotesResponse.getProperties().isEmpty()) { - throw new IllegalStateException("No properties found."); - } + .links(Collections.singletonList(GetLodgingQuotesOperationParams.Links.WEB)).rooms(rooms).build(); - // The LodgingQuotesResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", quotesResponse.getTransactionId()); - - // To access the properties, iterate through the list of properties - quotesResponse.getProperties().forEach(quote -> { - LOGGER.info("========== Property:{} Start ==========", quote.getId()); - if (Property.Status.AVAILABLE != quote.getStatus()) { - LOGGER.info("Property is not available."); - return; - } - if (quote.getRoomTypes() != null && !quote.getRoomTypes().isEmpty()) { - // To get the first room type information - LodgingRoomType roomType = quote.getRoomTypes().get(0); - - if (roomType.getPrice() != null) { - // To get the total price of the room type - if (roomType.getPrice().getTotalPrice() != null) { - LOGGER.info("Price: {}, Currency: {}", - roomType.getPrice().getTotalPrice().getValue(), - roomType.getPrice().getTotalPrice().getCurrency()); - } - // To get the average nightly rate of the room type - if (roomType.getPrice().getAvgNightlyRate() != null) { - LOGGER.info("Average Nightly Rate: {}, Currency: {}", - roomType.getPrice().getAvgNightlyRate().getValue(), - roomType.getPrice().getAvgNightlyRate().getCurrency()); - } - } - // To get the free cancellation flag of the selected room - if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() - && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { - LOGGER.info("Free Cancellation: {}", - roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); - } - if (roomType.getLinks() != null) { - // To get the deeplink to the Expedia Web Search Result Page - if (roomType.getLinks().getWebSearchResult() != null) { - LOGGER.info("WebSearchResult Link: {}", - roomType.getLinks().getWebSearchResult().getHref()); - } - // To get the deeplink to the Expedia Web Details Page - if (roomType.getLinks().getWebDetails() != null) { - LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); - } + XapClient xapClient = createClient(); + + // Execute the operation and get the QuotesResponse + LodgingQuotesResponse quotesResponse = xapClient.execute(new GetLodgingQuotesOperation(quotesOperationParams)).getData(); + + // If you want to use the async method, you can use the following code: + // --------------------------------------------------------------- + // CompletableFuture> completableFuture = + // xapClient.executeAsync( + // new GetLodgingQuotesOperation(quotesOperationParams)); + // completableFuture.thenAccept(quotesResponse -> { + // // Your code here + // }); + // --------------------------------------------------------------- + + LOGGER.info("========================== GetLodgingQuotesOperation Executed ========================="); + + if (quotesResponse == null || quotesResponse.getProperties() == null || quotesResponse.getProperties().isEmpty()) { + throw new IllegalStateException("No properties found."); } - } - LOGGER.info( - "=================================== Property End ==================================="); - }); - - LOGGER.info( - "============================= End QuotesQuickStartScenario ============================"); - } + + // The LodgingQuotesResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", quotesResponse.getTransactionId()); + + // To access the properties, iterate through the list of properties + quotesResponse.getProperties().forEach(quote -> { + LOGGER.info("========== Property:{} Start ==========", quote.getId()); + if (Property.Status.AVAILABLE != quote.getStatus()) { + LOGGER.info("Property is not available."); + return; + } + if (quote.getRoomTypes() != null && !quote.getRoomTypes().isEmpty()) { + // To get the first room type information + LodgingRoomType roomType = quote.getRoomTypes().get(0); + + if (roomType.getPrice() != null) { + // To get the total price of the room type + if (roomType.getPrice().getTotalPrice() != null) { + LOGGER.info("Price: {}, Currency: {}", roomType.getPrice().getTotalPrice().getValue(), roomType.getPrice().getTotalPrice().getCurrency()); + } + // To get the average nightly rate of the room type + if (roomType.getPrice().getAvgNightlyRate() != null) { + LOGGER.info("Average Nightly Rate: {}, Currency: {}", roomType.getPrice().getAvgNightlyRate().getValue(), roomType.getPrice().getAvgNightlyRate().getCurrency()); + } + } + // To get the free cancellation flag of the selected room + if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { + LOGGER.info("Free Cancellation: {}", roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); + } + if (roomType.getLinks() != null) { + // To get the deeplink to the Expedia Web Search Result Page + if (roomType.getLinks().getWebSearchResult() != null) { + LOGGER.info("WebSearchResult Link: {}", roomType.getLinks().getWebSearchResult().getHref()); + } + // To get the deeplink to the Expedia Web Details Page + if (roomType.getLinks().getWebDetails() != null) { + LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); + } + } + } + LOGGER.info("=================================== Property End ==================================="); + }); + LOGGER.info("============================= End QuotesQuickStartScenario ============================"); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboPropertySearchEndToEndScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboPropertySearchEndToEndScenario.java index 0d5ff3731..bfaff850a 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboPropertySearchEndToEndScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboPropertySearchEndToEndScenario.java @@ -29,6 +29,7 @@ import com.expediagroup.sdk.xap.operations.GetLodgingQuotesOperationParams; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -43,6 +44,7 @@ import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,144 +60,120 @@ *

Note: this is a Vrbo scenario. You need a key that is enabled for Vrbo brand to run this. */ public class VrboPropertySearchEndToEndScenario implements VrboScenario { + private final XapClient client = createClient(); + private static final Logger LOGGER = LoggerFactory.getLogger(VrboPropertySearchEndToEndScenario.class); + + /** + * This field limits the number of line to read from the SDP DownloadURL API Listings file to + * reduce time to run the example. + * If the first 20 properties from the file are not accessible OR available when you run this + * example, it may end with "No accessible property ids found." OR NO_RESULT_FOUND. In that case, + * you can adjust the property count to get more properties. + */ + private static final int SAMPLE_ITEMS_RESTRICTION = 20; + + /** + * A property id to location map. This mocks a cache in this example to store the static content + * of the properties. + */ + private static final Map PROPERTY_ID_AND_LOCATION_CACHE = new HashMap<>(); + + public static void main(String[] args) { + new VrboPropertySearchEndToEndScenario().run(); + System.exit(0); + } + + @Override + public void run() { + LOGGER.info("====================== Running VrboPropertySearchEndToEndScenario ======================"); + + List propertyIds = getPropertyIdsFromDownloadUrl(); + cachePropertyLocationFromDownloadUrl(propertyIds); + LodgingQuotesResponse lodgingQuotesResponse = getPropertyPriceFromLodgingQuotes(propertyIds); + displayResult(lodgingQuotesResponse); + + LOGGER.info("======================= End VrboPropertySearchEndToEndScenario ========================="); + } + + private List getPropertyIdsFromDownloadUrl() { + LOGGER.info("==================== Executing Step I: getPropertyIdsFromDownloadUrl ==================="); - private final XapClient client = createClient(); - - private static final Logger LOGGER = - LoggerFactory.getLogger(VrboPropertySearchEndToEndScenario.class); - - /** - * This field limits the number of line to read from the SDP DownloadURL API Listings file to - * reduce time to run the example. - * If the first 20 properties from the file are not accessible OR available when you run this - * example, it may end with "No accessible property ids found." OR NO_RESULT_FOUND. In that case, - * you can adjust the property count to get more properties. - */ - private static final int SAMPLE_ITEMS_RESTRICTION = 20; - - /** - * A property id to location map. This mocks a cache in this example to store the static content - * of the properties. - */ - private static final Map PROPERTY_ID_AND_LOCATION_CACHE = new HashMap<>(); - - public static void main(String[] args) { - new VrboPropertySearchEndToEndScenario().run(); - System.exit(0); - } - - @Override - public void run() { - LOGGER.info( - "====================== Running VrboPropertySearchEndToEndScenario ======================"); - - List propertyIds = getPropertyIdsFromDownloadUrl(); - cachePropertyLocationFromDownloadUrl(propertyIds); - LodgingQuotesResponse lodgingQuotesResponse = getPropertyPriceFromLodgingQuotes(propertyIds); - displayResult(lodgingQuotesResponse); - - LOGGER.info( - "======================= End VrboPropertySearchEndToEndScenario ========================="); - } - - private List getPropertyIdsFromDownloadUrl() { - LOGGER.info( - "==================== Executing Step I: getPropertyIdsFromDownloadUrl ==================="); - - GetFeedDownloadUrlOperationParams getPropertyIdListParams = - GetFeedDownloadUrlOperationParams.builder() + GetFeedDownloadUrlOperationParams getPropertyIdListParams = GetFeedDownloadUrlOperationParams.builder() // Use the type VACATION_RENTAL to get the list of accessible Vrbo property ids. .type(GetFeedDownloadUrlOperationParams.Type.VACATION_RENTAL) // Without any filters, this operation will return the information of all Vrbo // properties in en_US by default. .build(); - Response downloadUrlListingsResponse = - client.execute(new GetFeedDownloadUrlOperation(getPropertyIdListParams)); + Response downloadUrlListingsResponse = client.execute(new GetFeedDownloadUrlOperation(getPropertyIdListParams)); - if (downloadUrlListingsResponse.getData() == null - || downloadUrlListingsResponse.getData().getBestMatchedFile() == null) { - throw new IllegalStateException("No vacation rental file found"); - } + if (downloadUrlListingsResponse.getData() == null || downloadUrlListingsResponse.getData().getBestMatchedFile() == null) { + throw new IllegalStateException("No vacation rental file found"); + } + + // The download URL points to a zip file containing various jsonl files. + // Each line in the jsonl files contains a json object representing a Vrbo property. + // For demonstration purposes, we will only read a few properties from the file without + // downloading the entire file. + String vacationRentalDownloadUrl = downloadUrlListingsResponse.getData().getBestMatchedFile().getDownloadUrl(); + LOGGER.info("Vacation Rental Download URL: {}", vacationRentalDownloadUrl); + + // Read property ids from the file. + List propertyIds = getPropertyIdsFromVacationRentalFile(vacationRentalDownloadUrl); - // The download URL points to a zip file containing various jsonl files. - // Each line in the jsonl files contains a json object representing a Vrbo property. - // For demonstration purposes, we will only read a few properties from the file without - // downloading the entire file. - String vacationRentalDownloadUrl = downloadUrlListingsResponse.getData() - .getBestMatchedFile() - .getDownloadUrl(); - LOGGER.info("Vacation Rental Download URL: {}", vacationRentalDownloadUrl); - - // Read property ids from the file. - List propertyIds = getPropertyIdsFromVacationRentalFile(vacationRentalDownloadUrl - ); - - if (propertyIds.isEmpty()) { - throw new IllegalStateException("No accessible Vrbo property ids found."); + if (propertyIds.isEmpty()) { + throw new IllegalStateException("No accessible Vrbo property ids found."); + } + LOGGER.info("Accessible Vrbo Property Ids: {}", propertyIds); + + LOGGER.info("==================== Step I: getPropertyIdsFromDownloadUrl Executed ===================="); + return propertyIds; } - LOGGER.info("Accessible Vrbo Property Ids: {}", propertyIds); - - LOGGER.info( - "==================== Step I: getPropertyIdsFromDownloadUrl Executed ===================="); - return propertyIds; - } - - /** - * Cache the location content from SDP DownloadURL API. - * - * @param propertyIds The property ids that need the location content. - */ - private void cachePropertyLocationFromDownloadUrl(List propertyIds) { - LOGGER.info( - "================ Executing Step II: CachePropertyLocationFromDownloadUrl ==============="); - GetFeedDownloadUrlOperationParams getPropertyLocationParams = - GetFeedDownloadUrlOperationParams.builder() + + /** + * Cache the location content from SDP DownloadURL API. + * + * @param propertyIds The property ids that need the location content. + */ + private void cachePropertyLocationFromDownloadUrl(List propertyIds) { + LOGGER.info("================ Executing Step II: CachePropertyLocationFromDownloadUrl ==============="); + GetFeedDownloadUrlOperationParams getPropertyLocationParams = GetFeedDownloadUrlOperationParams.builder() // Use the type LOCATIONS to get the address of accessible properties. .type(GetFeedDownloadUrlOperationParams.Type.LOCATIONS) // Filter the properties by brand. - .brand(GetFeedDownloadUrlOperationParams.Brand.VRBO) - .build(); + .brand(GetFeedDownloadUrlOperationParams.Brand.VRBO).build(); + + Response downloadUrlLocationsResponse = client.execute(new GetFeedDownloadUrlOperation(getPropertyLocationParams)); + + if (downloadUrlLocationsResponse.getData() == null || downloadUrlLocationsResponse.getData().getBestMatchedFile() == null) { + throw new IllegalStateException("No location file found"); + } + + String locationsDownloadUrl = downloadUrlLocationsResponse.getData().getBestMatchedFile().getDownloadUrl(); + LOGGER.info("Locations Download URL: {}", locationsDownloadUrl); - Response downloadUrlLocationsResponse = - client.execute(new GetFeedDownloadUrlOperation(getPropertyLocationParams)); + // Read and cache property locations from the file. + cachePropertyLocationFromLocationsFile(locationsDownloadUrl, propertyIds); - if (downloadUrlLocationsResponse.getData() == null - || downloadUrlLocationsResponse.getData().getBestMatchedFile() == null) { - throw new IllegalStateException("No location file found"); + LOGGER.info("================= Step II: CachePropertyLocationFromDownloadUrl Executed ==============="); } - String locationsDownloadUrl = downloadUrlLocationsResponse.getData() - .getBestMatchedFile() - .getDownloadUrl(); - LOGGER.info("Locations Download URL: {}", locationsDownloadUrl); - - // Read and cache property locations from the file. - cachePropertyLocationFromLocationsFile(locationsDownloadUrl, propertyIds); - - LOGGER.info( - "================= Step II: CachePropertyLocationFromDownloadUrl Executed ==============="); - } - - /** - * Get prices of the properties using the Lodging Quotes API. - * - * @param propertyIds The property ids to get the prices. - * @return The response of the Lodging Quotes API. - */ - private LodgingQuotesResponse getPropertyPriceFromLodgingQuotes(List propertyIds) { - LOGGER.info( - "================= Executing Step III: GetPropertyPriceFromLodgingQuotes ================"); - - // Build the occupancy - ArrayList rooms = new ArrayList<>(); - // The first room, with 2 adult - rooms.add(Room.builder().adults(2L).childAges(null).build()); - - // Build the query parameters with GetLodgingQuotesOperationParams - GetLodgingQuotesOperationParams quotesOperationParams = - GetLodgingQuotesOperationParams.builder() - .partnerTransactionId(PARTNER_TRANSACTION_ID) + /** + * Get prices of the properties using the Lodging Quotes API. + * + * @param propertyIds The property ids to get the prices. + * @return The response of the Lodging Quotes API. + */ + private LodgingQuotesResponse getPropertyPriceFromLodgingQuotes(List propertyIds) { + LOGGER.info("================= Executing Step III: GetPropertyPriceFromLodgingQuotes ================"); + + // Build the occupancy + ArrayList rooms = new ArrayList<>(); + // The first room, with 2 adult + rooms.add(Room.builder().adults(2L).childAges(null).build()); + + // Build the query parameters with GetLodgingQuotesOperationParams + GetLodgingQuotesOperationParams quotesOperationParams = GetLodgingQuotesOperationParams.builder().partnerTransactionId(PARTNER_TRANSACTION_ID) // Check-in 5 days from now .checkIn(LocalDate.now().plusDays(5)) // Check-out 10 days from now @@ -204,47 +182,41 @@ private LodgingQuotesResponse getPropertyPriceFromLodgingQuotes(List pro .propertyIds(new HashSet<>(propertyIds)) // The links to return, WEB includes WS (Web Search Result Page) and // WD (Web Details Page) - .links(Collections.singletonList(GetLodgingQuotesOperationParams.Links.WEB)) - .rooms(rooms) - .build(); + .links(Collections.singletonList(GetLodgingQuotesOperationParams.Links.WEB)).rooms(rooms).build(); + + LodgingQuotesResponse lodgingQuotesResponse = client.execute(new GetLodgingQuotesOperation(quotesOperationParams)).getData(); + + LOGGER.info("================= Step III: GetPropertyPriceFromLodgingQuotes Executed ================="); + return lodgingQuotesResponse; + } - LodgingQuotesResponse lodgingQuotesResponse = - client.execute(new GetLodgingQuotesOperation(quotesOperationParams)) - .getData(); - - LOGGER.info( - "================= Step III: GetPropertyPriceFromLodgingQuotes Executed ================="); - return lodgingQuotesResponse; - } - - /** - * Reads given number of property ids from the file pointed by the download URL. - * - * @param downloadUrl The download URL of the zip file containing the property information. - * @return A list of property ids read from the file. - */ - private List getPropertyIdsFromVacationRentalFile(String downloadUrl) { - List propertyIds = new ArrayList<>(); - HttpURLConnection connection = null; - try { - // Open a connection to the URL - URL url = new URL(downloadUrl); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setDoInput(true); - - try (ZipInputStream zipStream = new ZipInputStream(connection.getInputStream())) { - ZipEntry entry; - while ((entry = zipStream.getNextEntry()) != null) { - if (entry.getName().endsWith(".jsonl")) { - LOGGER.info("Reading property ids from file: {}", entry.getName()); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(zipStream))) { - String line; - ObjectMapper objectMapper = new ObjectMapper(); - while ((line = reader.readLine()) != null - && propertyIds.size() < SAMPLE_ITEMS_RESTRICTION) { - // Parse the property id from the json object - // An example json line from the jsonl file: + /** + * Reads given number of property ids from the file pointed by the download URL. + * + * @param downloadUrl The download URL of the zip file containing the property information. + * @return A list of property ids read from the file. + */ + private List getPropertyIdsFromVacationRentalFile(String downloadUrl) { + List propertyIds = new ArrayList<>(); + HttpURLConnection connection = null; + try { + // Open a connection to the URL + URL url = new URL(downloadUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setDoInput(true); + + try (ZipInputStream zipStream = new ZipInputStream(connection.getInputStream())) { + ZipEntry entry; + while ((entry = zipStream.getNextEntry()) != null) { + if (entry.getName().endsWith(".jsonl")) { + LOGGER.info("Reading property ids from file: {}", entry.getName()); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(zipStream))) { + String line; + ObjectMapper objectMapper = new ObjectMapper(); + while ((line = reader.readLine()) != null && propertyIds.size() < SAMPLE_ITEMS_RESTRICTION) { + // Parse the property id from the json object + // An example json line from the jsonl file: /* { "propertyId": { @@ -290,52 +262,50 @@ private List getPropertyIdsFromVacationRentalFile(String downloadUrl) { "propertyLiveDate": "2022-05-31" } */ - JsonNode jsonNode = objectMapper.readTree(line); - propertyIds.add(jsonNode.get("propertyId").get("expedia").asText()); - } + JsonNode jsonNode = objectMapper.readTree(line); + propertyIds.add(jsonNode.get("propertyId").get("expedia").asText()); + } + } + } + } + } + + } catch (IOException e) { + LOGGER.error("Error reading property ids from download URL", e); + } finally { + if (connection != null) { + connection.disconnect(); } - } } - } - - } catch (IOException e) { - LOGGER.error("Error reading property ids from download URL", e); - } finally { - if (connection != null) { - connection.disconnect(); - } + return propertyIds; } - return propertyIds; - } - - /** - * Caches the location content of the properties from the file pointed by the download URL. - * - * @param locationsDownloadUrl The download URL of the zip file containing the property locations. - * @param propertyIds The property ids to get the location content. - */ - private void cachePropertyLocationFromLocationsFile(String locationsDownloadUrl, - List propertyIds) { - HttpURLConnection connection = null; - try { - // Open a connection to the URL - URL url = new URL(locationsDownloadUrl); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setDoInput(true); - - try (ZipInputStream zipStream = new ZipInputStream(connection.getInputStream())) { - ZipEntry entry; - while ((entry = zipStream.getNextEntry()) != null) { - if (entry.getName().endsWith(".jsonl")) { - LOGGER.info("Reading property locations from file: {}", entry.getName()); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(zipStream))) { - String line; - ObjectMapper objectMapper = new ObjectMapper(); - while ((line = reader.readLine()) != null - && PROPERTY_ID_AND_LOCATION_CACHE.size() < propertyIds.size()) { - // Parse the property location from the json object - // An example json line from the jsonl file: + + /** + * Caches the location content of the properties from the file pointed by the download URL. + * + * @param locationsDownloadUrl The download URL of the zip file containing the property locations. + * @param propertyIds The property ids to get the location content. + */ + private void cachePropertyLocationFromLocationsFile(String locationsDownloadUrl, List propertyIds) { + HttpURLConnection connection = null; + try { + // Open a connection to the URL + URL url = new URL(locationsDownloadUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setDoInput(true); + + try (ZipInputStream zipStream = new ZipInputStream(connection.getInputStream())) { + ZipEntry entry; + while ((entry = zipStream.getNextEntry()) != null) { + if (entry.getName().endsWith(".jsonl")) { + LOGGER.info("Reading property locations from file: {}", entry.getName()); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(zipStream))) { + String line; + ObjectMapper objectMapper = new ObjectMapper(); + while ((line = reader.readLine()) != null && PROPERTY_ID_AND_LOCATION_CACHE.size() < propertyIds.size()) { + // Parse the property location from the json object + // An example json line from the jsonl file: /* { "propertyId": { @@ -386,106 +356,89 @@ private void cachePropertyLocationFromLocationsFile(String locationsDownloadUrl, } } */ - JsonNode jsonNode = objectMapper.readTree(line); - // Check if the property id is in the list - if (propertyIds.contains(jsonNode.get("propertyId").get("expedia").asText())) { - // Get the location content of the property - String location = jsonNode.get("propertyName").asText() + ", " - + jsonNode.get("city").asText() + ", " - + jsonNode.get("province").asText() + ", " - + jsonNode.get("country").asText(); - // Store the location content in the cache - PROPERTY_ID_AND_LOCATION_CACHE.put( - jsonNode.get("propertyId") - .get("expedia") - .asText(), - location); + JsonNode jsonNode = objectMapper.readTree(line); + // Check if the property id is in the list + if (propertyIds.contains(jsonNode.get("propertyId").get("expedia").asText())) { + // Get the location content of the property + String location = jsonNode.get("propertyName").asText() + ", " + jsonNode.get("city").asText() + ", " + jsonNode.get("province").asText() + ", " + jsonNode.get("country").asText(); + // Store the location content in the cache + PROPERTY_ID_AND_LOCATION_CACHE.put(jsonNode.get("propertyId").get("expedia").asText(), location); + } + } + } + } } - } } - } + + } catch (IOException e) { + LOGGER.error("Error reading property locations from download URL", e); + } finally { + if (connection != null) { + connection.disconnect(); + } } - } - - } catch (IOException e) { - LOGGER.error("Error reading property locations from download URL", e); - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - - /** - * Display the result of the operations. - * - * @param lodgingQuotesResponse The response of the Lodging Quotes API. - */ - private static void displayResult(LodgingQuotesResponse lodgingQuotesResponse) { - LOGGER.info("======================= Executing Step IV: DisplayResult ======================="); - if (lodgingQuotesResponse == null || lodgingQuotesResponse.getProperties() == null - || lodgingQuotesResponse.getProperties().isEmpty()) { - throw new IllegalStateException("No properties found."); } - // The HotelListingsResponse contains a transaction ID for troubleshooting - LOGGER.info("Transaction ID: {}", lodgingQuotesResponse.getTransactionId()); - - // To access the properties, iterate through the list of hotel properties - lodgingQuotesResponse.getProperties().forEach(property -> { - // Check if the property is available - if (Property.Status.AVAILABLE != property.getStatus()) { - LOGGER.info("Property {} is not available.", property.getId()); - return; - } - LOGGER.info( - "=================================== Property Start ==================================="); - String propertyId = property.getId(); - - // Get the location content of the property from the cache - LOGGER.info("Property Id: {}", propertyId); - LOGGER.info("Cached Property Location: {}", PROPERTY_ID_AND_LOCATION_CACHE.get(propertyId)); - - // Get the price of the property from the room type - if (property.getRoomTypes() != null && !property.getRoomTypes().isEmpty()) { - // To get the first room type information - LodgingRoomType roomType = property.getRoomTypes().get(0); - - if (roomType.getPrice() != null) { - // To get the total price of the room type - if (roomType.getPrice().getTotalPrice() != null) { - LOGGER.info("Price: {}, Currency: {}", - roomType.getPrice().getTotalPrice().getValue(), - roomType.getPrice().getTotalPrice().getCurrency()); - } - // To get the average nightly rate of the room type - if (roomType.getPrice().getAvgNightlyRate() != null) { - LOGGER.info("Average Nightly Rate: {}, Currency: {}", - roomType.getPrice().getAvgNightlyRate().getValue(), - roomType.getPrice().getAvgNightlyRate().getCurrency()); - } + /** + * Display the result of the operations. + * + * @param lodgingQuotesResponse The response of the Lodging Quotes API. + */ + private static void displayResult(LodgingQuotesResponse lodgingQuotesResponse) { + LOGGER.info("======================= Executing Step IV: DisplayResult ======================="); + if (lodgingQuotesResponse == null || lodgingQuotesResponse.getProperties() == null || lodgingQuotesResponse.getProperties().isEmpty()) { + throw new IllegalStateException("No properties found."); } - // To get the free cancellation flag of the selected room - if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() - && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { - LOGGER.info("Free Cancellation: {}", - roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); - } - if (roomType.getLinks() != null) { - // To get the deeplink to the website Search Result Page - if (roomType.getLinks().getWebSearchResult() != null) { - LOGGER.info("WebSearchResult Link: {}", - roomType.getLinks().getWebSearchResult().getHref()); - } - // To get the deeplink to the website Details Page - if (roomType.getLinks().getWebDetails() != null) { - LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); - } - } - } - LOGGER.info( - "==================================== Property End ===================================="); - }); - LOGGER.info("======================= Step IV: DisplayResult Executed ========================"); - } + + // The HotelListingsResponse contains a transaction ID for troubleshooting + LOGGER.info("Transaction ID: {}", lodgingQuotesResponse.getTransactionId()); + + // To access the properties, iterate through the list of hotel properties + lodgingQuotesResponse.getProperties().forEach(property -> { + // Check if the property is available + if (Property.Status.AVAILABLE != property.getStatus()) { + LOGGER.info("Property {} is not available.", property.getId()); + return; + } + LOGGER.info("=================================== Property Start ==================================="); + String propertyId = property.getId(); + + // Get the location content of the property from the cache + LOGGER.info("Property Id: {}", propertyId); + LOGGER.info("Cached Property Location: {}", PROPERTY_ID_AND_LOCATION_CACHE.get(propertyId)); + + // Get the price of the property from the room type + if (property.getRoomTypes() != null && !property.getRoomTypes().isEmpty()) { + // To get the first room type information + LodgingRoomType roomType = property.getRoomTypes().get(0); + + if (roomType.getPrice() != null) { + // To get the total price of the room type + if (roomType.getPrice().getTotalPrice() != null) { + LOGGER.info("Price: {}, Currency: {}", roomType.getPrice().getTotalPrice().getValue(), roomType.getPrice().getTotalPrice().getCurrency()); + } + // To get the average nightly rate of the room type + if (roomType.getPrice().getAvgNightlyRate() != null) { + LOGGER.info("Average Nightly Rate: {}, Currency: {}", roomType.getPrice().getAvgNightlyRate().getValue(), roomType.getPrice().getAvgNightlyRate().getCurrency()); + } + } + // To get the free cancellation flag of the selected room + if (roomType.getRatePlans() != null && !roomType.getRatePlans().isEmpty() && roomType.getRatePlans().get(0).getCancellationPolicy() != null) { + LOGGER.info("Free Cancellation: {}", roomType.getRatePlans().get(0).getCancellationPolicy().getFreeCancellation()); + } + if (roomType.getLinks() != null) { + // To get the deeplink to the website Search Result Page + if (roomType.getLinks().getWebSearchResult() != null) { + LOGGER.info("WebSearchResult Link: {}", roomType.getLinks().getWebSearchResult().getHref()); + } + // To get the deeplink to the website Details Page + if (roomType.getLinks().getWebDetails() != null) { + LOGGER.info("WebDetails Link: {}", roomType.getLinks().getWebDetails().getHref()); + } + } + } + LOGGER.info("==================================== Property End ===================================="); + }); + LOGGER.info("======================= Step IV: DisplayResult Executed ========================"); + } } diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java index 6a523f5aa..31a5fb7ff 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java @@ -25,20 +25,16 @@ */ public interface VrboScenario extends XapScenario { - /** - * Create a client with Vrbo key and secret. - * - * @return XapClient - */ - @Override - default XapClient createClient() { - String key = System.getProperty("com.expediagroup.xapjavasdk.vrbokey"); - String secret = System.getProperty("com.expediagroup.xapjavasdk.vrbosecret"); - return XapClient - .builder() - .key(key) - .secret(secret) - .build(); - } + /** + * Create a client with Vrbo key and secret. + * + * @return XapClient + */ + @Override + default XapClient createClient() { + String key = System.getProperty("com.expediagroup.xapjavasdk.vrbokey"); + String secret = System.getProperty("com.expediagroup.xapjavasdk.vrbosecret"); + return XapClient.builder().key(key).secret(secret).build(); + } } From ad5226899932262df3ed5c496fa90bba0065324a Mon Sep 17 00:00:00 2001 From: mohnoor94 Date: Wed, 14 May 2025 17:56:27 +0300 Subject: [PATCH 2/2] refactor: improve code formatting for better readability in scenario classes Signed-off-by: mohnoor94 --- .../HotelIdsSearchEndToEndScenario.java | 36 +++++++++---------- .../scenarios/lodging/VrboScenario.java | 6 +++- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java index e7c07b386..73c308ec3 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/HotelIdsSearchEndToEndScenario.java @@ -95,11 +95,11 @@ private List getPropertyIdsFromDownloadUrl() { LOGGER.info("==================== Executing Step I: getPropertyIdsFromDownloadUrl ==================="); GetFeedDownloadUrlOperationParams getPropertyIdListParams = GetFeedDownloadUrlOperationParams.builder() - // Use the type LISTINGS to get the list of accessible property ids. - .type(GetFeedDownloadUrlOperationParams.Type.LISTINGS) - // Without any filters, this operation will return the information of all lodging - // properties in en_US by default. - .build(); + // Use the type LISTINGS to get the list of accessible property ids. + .type(GetFeedDownloadUrlOperationParams.Type.LISTINGS) + // Without any filters, this operation will return the information of all lodging + // properties in en_US by default. + .build(); Response downloadUrlListingsResponse = client.execute(new GetFeedDownloadUrlOperation(getPropertyIdListParams)); @@ -136,19 +136,19 @@ private HotelListingsResponse getPropertiesFromLodgingListings(List prop LOGGER.info("================ Step II: Executing getPropertiesFromLodgingListings ==============="); GetLodgingListingsOperationParams getLodgingListingsOperationParams = GetLodgingListingsOperationParams.builder().partnerTransactionId(PARTNER_TRANSACTION_ID) - // Use the property ids read from the file - .ecomHotelIds(new HashSet<>(propertyIds)) - // The links to return, WEB includes WS (Web Search Result Page) - // and WD (Web Details Page) - .links(Collections.singletonList(GetLodgingListingsOperationParams.Links.WEB)) - // Check-in 5 days from now - .checkIn(LocalDate.now().plusDays(5)) - // Check-out 10 days from now - .checkOut(LocalDate.now().plusDays(10)) - // Filter the properties that are available only - .availOnly(true) - // Use the default occupancy: 2 adults in one room - .build(); + // Use the property ids read from the file + .ecomHotelIds(new HashSet<>(propertyIds)) + // The links to return, WEB includes WS (Web Search Result Page) + // and WD (Web Details Page) + .links(Collections.singletonList(GetLodgingListingsOperationParams.Links.WEB)) + // Check-in 5 days from now + .checkIn(LocalDate.now().plusDays(5)) + // Check-out 10 days from now + .checkOut(LocalDate.now().plusDays(10)) + // Filter the properties that are available only + .availOnly(true) + // Use the default occupancy: 2 adults in one room + .build(); HotelListingsResponse hotelListingsResponse = client.execute(new GetLodgingListingsOperation(getLodgingListingsOperationParams)).getData(); LOGGER.info("================ Step II: getPropertiesFromLodgingListings Executed ================"); diff --git a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java index 31a5fb7ff..994a2880e 100644 --- a/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java +++ b/examples/src/main/java/com/expediagroup/sdk/xap/examples/scenarios/lodging/VrboScenario.java @@ -34,7 +34,11 @@ public interface VrboScenario extends XapScenario { default XapClient createClient() { String key = System.getProperty("com.expediagroup.xapjavasdk.vrbokey"); String secret = System.getProperty("com.expediagroup.xapjavasdk.vrbosecret"); - return XapClient.builder().key(key).secret(secret).build(); + + return XapClient.builder() + .key(key) + .secret(secret) + .build(); } }