├── .gitignore ├── src ├── test │ ├── resources │ │ └── fixtures │ │ │ ├── BasketUpdateRequest.json │ │ │ ├── BasketAddItemRequest.json │ │ │ ├── WishlistAddItemRequest.json │ │ │ └── BrandGetResponse.json │ └── java │ │ └── com │ │ └── scayle │ │ └── storefrontapi │ │ ├── RedirectTest.java │ │ ├── PromotionTest.java │ │ ├── AttributeTest.java │ │ ├── VariantTest.java │ │ ├── SearchTest.java │ │ ├── ShopConfigurationTest.java │ │ ├── FilterTest.java │ │ ├── BrandTest.java │ │ ├── MatchRedirectTest.java │ │ ├── ProductTest.java │ │ ├── TypeaheadTest.java │ │ ├── CampaignTest.java │ │ ├── NavigationTest.java │ │ ├── WishlistTest.java │ │ ├── CategoryTest.java │ │ ├── BasketTest.java │ │ └── BaseApiTest.java └── main │ └── java │ └── com │ └── scayle │ └── storefrontapi │ ├── model │ ├── ApiObjectInterface.java │ ├── FilterInterface.java │ ├── SuggestionInterface.java │ ├── Search.java │ ├── Packages.java │ ├── DisplayData.java │ ├── FilterValues.java │ ├── Navigation.java │ ├── ApiCollection.java │ ├── BrandCustomData.java │ ├── BasketItemPromotion.java │ ├── ResponseCustomData.java │ ├── NavigationTreeResponse.java │ ├── SearchV2ResolveResponse.java │ ├── ApiConfiguration.java │ ├── Tax.java │ ├── ProductName.java │ ├── OffsetPagination.java │ ├── ObjectParser.java │ ├── SearchResolveResponse.java │ ├── SearchV2ProductSuggestion.java │ ├── MatchRedirectBody.java │ ├── NavigationItemExtraFilter.java │ ├── SearchV2SuggestionsResponse.java │ ├── Vat.java │ ├── PriceRange.java │ ├── DeliveryDate.java │ ├── ReductionRange.java │ ├── ShopProperties.java │ ├── Wishlist.java │ ├── BasketItemPrice.java │ ├── DefiningAttribute.java │ ├── Deliverable.java │ ├── CategoryProperty.java │ ├── Image.java │ ├── SubsequentDelivery.java │ ├── BuyXGetYEffect.java │ ├── BrandsResponse.java │ ├── ProductSuggestion.java │ ├── BooleanFilterValue.java │ ├── IdentifierFilterValue.java │ ├── TypeaheadResponse.java │ ├── CampaignsResponse.java │ ├── ProductsResponse.java │ ├── RedirectsResponse.java │ ├── Typeahead.java │ ├── VariantsResponse.java │ ├── AutomaticDiscountEffect.java │ ├── PromotionsResponse.java │ ├── AppliedReductionAmount.java │ ├── SearchV2CategorySuggestion.java │ ├── Identifier.java │ ├── SearchV2AttributeFilter.java │ ├── DeliveryForecast.java │ ├── AdvancedAttributeGroupSet.java │ ├── SearchV2ProductResponse.java │ ├── SearchV2CategoryResponse.java │ ├── AttributeValue.java │ ├── Condition.java │ ├── RangeFilterValue.java │ ├── AppliedReduction.java │ ├── Package.java │ ├── TypeaheadProductSuggestion.java │ ├── TypeaheadSuggestion.java │ ├── Tier.java │ ├── ApplicablePromotion.java │ ├── Merchant.java │ ├── TypeaheadBrandOrCategorySuggestion.java │ ├── NavigationTree.java │ ├── MatchRedirect.java │ ├── AttributeFilterValue.java │ ├── ResolveMatch.java │ ├── CustomData.java │ ├── Cost.java │ ├── SearchSuggestions.java │ ├── AdvancedAttribute.java │ ├── BaseCategory.java │ ├── LowestPriorPrice.java │ ├── DisplayDataValue.java │ ├── Basket.java │ ├── Stock.java │ ├── Match.java │ ├── CreateWishlistBody.java │ ├── BrandOrCategorySuggestion.java │ ├── ShopConfiguration.java │ ├── BasketItemDisplayData.java │ ├── ApiOptions.java │ ├── Pagination.java │ ├── Redirect.java │ ├── Campaign.java │ ├── Price.java │ ├── CreateBasketItemBody.java │ ├── TypeaheadRequestBody.java │ ├── UpdateBasketItemBody.java │ ├── ItemGroup.java │ ├── Attribute.java │ ├── ProductCategory.java │ ├── TypeaheadBody.java │ ├── WishlistItem.java │ ├── Filter.java │ ├── NavigationItem.java │ ├── CreateBasketBody.java │ ├── Promotion.java │ ├── Brand.java │ ├── Variant.java │ ├── BasketItem.java │ ├── Category.java │ └── Product.java │ ├── polymorphism │ ├── PolymorphicInterface.java │ ├── PolymorphicMapping.java │ ├── Polymorphic.java │ └── PolymorphicAdapter.java │ ├── exception │ ├── ConnectionException.java │ ├── InvalidArgumentException.java │ ├── ApiError.java │ └── ApiErrorException.java │ ├── service │ ├── AttributeService.java │ ├── FilterService.java │ ├── RedirectService.java │ ├── PromotionService.java │ ├── NavigationService.java │ ├── MatchRedirectService.java │ ├── CampaignService.java │ ├── TypeaheadService.java │ ├── SearchService.java │ ├── ShopConfigurationService.java │ ├── VariantService.java │ ├── ProductService.java │ ├── BrandService.java │ ├── WishlistService.java │ ├── BasketService.java │ ├── CategoryService.java │ └── AbstractService.java │ ├── serializer │ ├── TimestampAdapter.java │ ├── AttributeValuesAdapter.java │ ├── FilterAdapter.java │ ├── MapNumberAdapter.java │ └── JsonSerializer.java │ ├── factory │ └── ServiceFactory.java │ ├── AbstractApiClient.java │ ├── http │ └── HttpClient.java │ └── StorefrontClient.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── README.md ├── .gitlab-ci.yml ├── gradlew.bat └── gradlew /.gitignore: -------------------------------------------------------------------------------- 1 | .api -------------------------------------------------------------------------------- /src/test/resources/fixtures/BasketUpdateRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "quantity": 2 3 | } -------------------------------------------------------------------------------- /src/test/resources/fixtures/BasketAddItemRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "variantId": 5, 3 | "quantity": 1 4 | } -------------------------------------------------------------------------------- /src/test/resources/fixtures/WishlistAddItemRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "productId": 7, 3 | "quantity": 1 4 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scayle/storefront-api-java-sdk/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ApiObjectInterface.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | public interface ApiObjectInterface { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/polymorphism/PolymorphicInterface.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.polymorphism; 2 | 3 | public interface PolymorphicInterface { 4 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/FilterInterface.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import com.scayle.storefrontapi.polymorphism.PolymorphicInterface; 4 | 5 | public interface FilterInterface extends PolymorphicInterface { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SuggestionInterface.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import com.scayle.storefrontapi.polymorphism.PolymorphicInterface; 4 | 5 | public interface SuggestionInterface extends PolymorphicInterface { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/exception/ConnectionException.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.exception; 2 | 3 | public class ConnectionException extends RuntimeException { 4 | public ConnectionException(String message, Throwable cause) { 5 | super(message, cause); 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/exception/InvalidArgumentException.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.exception; 2 | 3 | public class InvalidArgumentException extends RuntimeException { 4 | 5 | public InvalidArgumentException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Search.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Search implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Packages.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Packages implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/DisplayData.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class DisplayData implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/FilterValues.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class FilterValues implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Navigation.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Navigation implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ApiCollection.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | 5 | import com.google.gson.annotations.SerializedName; 6 | 7 | 8 | import lombok.Getter; 9 | 10 | @Getter 11 | public class ApiCollection implements ApiObjectInterface{ 12 | @SerializedName("entities") 13 | List entities; 14 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BrandCustomData.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BrandCustomData implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BasketItemPromotion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BasketItemPromotion implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ResponseCustomData.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ResponseCustomData implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/NavigationTreeResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class NavigationTreeResponse implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/6.6/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'StorefrontClient' -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchV2ResolveResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchV2ResolveResponse implements ApiObjectInterface { 15 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ApiConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @Builder 8 | public class ApiConfiguration { 9 | private final String url; 10 | private final String accessToken; 11 | private final String username; 12 | private final String password; 13 | private final Integer shopId; 14 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Tax.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Tax implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("vat") 19 | Vat vat; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ProductName.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ProductName implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("term") 19 | String term; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/OffsetPagination.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class OffsetPagination implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("total") 19 | Integer total; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ObjectParser.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonElement; 5 | import java.lang.reflect.Type; 6 | 7 | public final class ObjectParser { 8 | public static T parse(Object object, Type type) { 9 | Gson gson = new Gson(); 10 | JsonElement jsonElement = gson.toJsonTree(object); 11 | return gson.fromJson(jsonElement, type); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchResolveResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchResolveResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("matches") 19 | Object matches; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchV2ProductSuggestion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchV2ProductSuggestion implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("product") 19 | Product product; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/MatchRedirectBody.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class MatchRedirectBody implements ApiObjectInterface { 15 | /** 16 | * The url to find a redirect for 17 | 18 | */ 19 | @SerializedName("url") 20 | String url; 21 | 22 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/NavigationItemExtraFilter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class NavigationItemExtraFilter implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("attributes") 19 | List attributes; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchV2SuggestionsResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchV2SuggestionsResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("suggestions") 19 | List suggestions; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Vat.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Vat implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("amount") 19 | Double amount; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("rate") 25 | Double rate; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/PriceRange.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class PriceRange implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("max") 19 | Price max; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("min") 25 | Price min; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/DeliveryDate.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class DeliveryDate implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("min") 19 | String min; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("max") 25 | String max; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ReductionRange.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ReductionRange implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("max") 19 | Price max; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("min") 25 | Price min; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ShopProperties.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ShopProperties implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("value") 25 | String value; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Wishlist.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Wishlist implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("items") 25 | List items; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BasketItemPrice.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BasketItemPrice implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("total") 19 | Price total; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("unit") 25 | Price unit; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/DefiningAttribute.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class DefiningAttribute implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("label") 25 | String label; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Deliverable.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Deliverable implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("quantity") 25 | Integer quantity; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/CategoryProperty.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class CategoryProperty implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("name") 19 | String name; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("value") 25 | Object value; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Image.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Image implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("attributes") 19 | Map attributes; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("hash") 25 | String hash; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SubsequentDelivery.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SubsequentDelivery implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("quantity") 25 | Integer quantity; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BuyXGetYEffect.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BuyXGetYEffect implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("type") 19 | String type; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("additionalData") 25 | Object additionalData; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BrandsResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BrandsResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("entities") 19 | List entities; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("pagination") 25 | Object pagination; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ProductSuggestion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ProductSuggestion implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("suggestion") 19 | String suggestion; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("product") 25 | Product product; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BooleanFilterValue.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BooleanFilterValue implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("name") 19 | Boolean name; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("productCount") 25 | Integer productCount; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/IdentifierFilterValue.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class IdentifierFilterValue implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("productCount") 19 | Integer productCount; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("id") 25 | Integer id; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/TypeaheadResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class TypeaheadResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("suggestions") 19 | Object suggestions; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("topMatch") 25 | Object topMatch; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/CampaignsResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class CampaignsResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("pagination") 19 | Object pagination; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("entities") 25 | List entities; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ProductsResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ProductsResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("entities") 19 | List entities; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("pagination") 25 | Object pagination; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/RedirectsResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class RedirectsResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("entities") 19 | List entities; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("pagination") 25 | Object pagination; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Typeahead.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Typeahead implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("suggestions") 19 | Object suggestions; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("topMatch") 25 | BrandOrCategorySuggestion topMatch; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/VariantsResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class VariantsResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("entities") 19 | List entities; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("pagination") 25 | Pagination pagination; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/AutomaticDiscountEffect.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class AutomaticDiscountEffect implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("type") 19 | String type; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("additionalData") 25 | Object additionalData; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/PromotionsResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class PromotionsResponse implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("entities") 19 | List entities; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("pagination") 25 | Pagination pagination; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/AppliedReductionAmount.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class AppliedReductionAmount implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("absoluteWithTax") 19 | Integer absoluteWithTax; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("relative") 25 | Double relative; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchV2CategorySuggestion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchV2CategorySuggestion implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("category") 19 | Category category; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("filters") 25 | List filters; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Identifier.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | public class Identifier { 4 | private String identifier; 5 | 6 | private Identifier(String identifier) { 7 | this.identifier = identifier; 8 | } 9 | 10 | public static Identifier fromId(Integer id) { 11 | return new Identifier(Integer.toString(id)); 12 | } 13 | 14 | public static Identifier fromKey(String referenceKey) { 15 | return new Identifier("key=" + referenceKey); 16 | } 17 | 18 | public String toString() { 19 | return this.identifier; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchV2AttributeFilter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchV2AttributeFilter implements ApiObjectInterface, FilterInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("type") 19 | String type; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("attributeFilter") 25 | Object attributeFilter; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/DeliveryForecast.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class DeliveryForecast implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("deliverable") 19 | Deliverable deliverable; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("subsequentDelivery") 25 | SubsequentDelivery subsequentDelivery; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/exception/ApiError.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.exception; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | public class ApiError { 8 | @SerializedName("errorKey") 9 | String errorKey; 10 | 11 | @SerializedName("message") 12 | String message; 13 | 14 | @SerializedName("context") 15 | Object context; 16 | 17 | public ApiError(String errorKey, String message, Object context) { 18 | this.errorKey = errorKey; 19 | this.message = message; 20 | this.context = context; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/AdvancedAttributeGroupSet.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class AdvancedAttributeGroupSet implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("fieldSet") 19 | List fieldSet; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("groupSet") 25 | List groupSet; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchV2ProductResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchV2ProductResponse implements ApiObjectInterface, SuggestionInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("type") 19 | String type; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("productSuggestion") 25 | SearchV2ProductSuggestion productSuggestion; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchV2CategoryResponse.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchV2CategoryResponse implements ApiObjectInterface, SuggestionInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("type") 19 | String type; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("categorySuggestion") 25 | SearchV2CategorySuggestion categorySuggestion; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/AttributeValue.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class AttributeValue implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("label") 25 | String label; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("value") 31 | String value; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Condition.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Condition implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("level") 19 | String level; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("key") 25 | String key; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("condition") 31 | String condition; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/RangeFilterValue.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class RangeFilterValue implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("max") 19 | Integer max; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("min") 25 | Integer min; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("productCount") 31 | Integer productCount; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/AppliedReduction.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class AppliedReduction implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("amount") 19 | AppliedReductionAmount amount; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("category") 25 | String category; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("type") 31 | String type; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Package.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Package implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * The carrier key which will deliver the package 23 | */ 24 | @SerializedName("carrierKey") 25 | String carrierKey; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("deliveryDate") 31 | DeliveryDate deliveryDate; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/TypeaheadProductSuggestion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class TypeaheadProductSuggestion implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("productSuggestion") 19 | ProductSuggestion productSuggestion; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("score") 25 | Double score; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("type") 31 | String type; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/TypeaheadSuggestion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class TypeaheadSuggestion implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("brandOrCategorySuggestion") 19 | BrandOrCategorySuggestion brandOrCategorySuggestion; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("score") 25 | Double score; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("type") 31 | String type; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Tier.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Tier implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("name") 25 | String name; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("MOV") 31 | Integer MOV; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("effect") 37 | Object effect; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ApplicablePromotion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ApplicablePromotion implements ApiObjectInterface { 15 | /** 16 | * The Basket Item ID to which the promotion should be applied. This can be null in case of a `bux_x_get_y` effect where the free item is not in the basket yet. 17 | */ 18 | @SerializedName("itemId") 19 | String itemId; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("promotion") 25 | Promotion promotion; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Merchant.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Merchant implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("key") 25 | String key; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("name") 31 | String name; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("legal") 37 | Object legal; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/TypeaheadBrandOrCategorySuggestion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class TypeaheadBrandOrCategorySuggestion implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("brandOrCategorySuggestion") 19 | BrandOrCategorySuggestion brandOrCategorySuggestion; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("score") 25 | Double score; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("type") 31 | String type; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/NavigationTree.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class NavigationTree implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("key") 25 | String key; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("name") 31 | String name; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("items") 37 | List items; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/MatchRedirect.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class MatchRedirect implements ApiObjectInterface { 15 | /** 16 | * The source URL for the redirect 17 | */ 18 | @SerializedName("source") 19 | String source; 20 | 21 | /** 22 | * The target URL for the redirect 23 | */ 24 | @SerializedName("target") 25 | String target; 26 | 27 | /** 28 | * The status code for the redirect 29 | */ 30 | @SerializedName("statusCode") 31 | Integer statusCode; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/AttributeFilterValue.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class AttributeFilterValue implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("name") 19 | String name; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("productCount") 25 | Integer productCount; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("id") 31 | Integer id; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("value") 37 | String value; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ResolveMatch.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ResolveMatch implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("count") 19 | Integer count; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("match") 25 | String match; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("category") 31 | Object category; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("attributes") 37 | List attributes; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/CustomData.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class CustomData implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("value") 25 | String value; 26 | 27 | /** 28 | * Adjust variant price based on the specified `pricePromotionKey`. If the variant does not have a matching price promotion, the default price is returned. 29 | */ 30 | @SerializedName("pricePromotionKey") 31 | String pricePromotionKey; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Cost.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Cost implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("appliedReductions") 19 | List appliedReductions; 20 | 21 | /** 22 | * The currency of the price. 23 | */ 24 | @SerializedName("currencyCode") 25 | String currencyCode; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("withoutTax") 31 | Integer withoutTax; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("withTax") 37 | Integer withTax; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/SearchSuggestions.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class SearchSuggestions implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("brands") 19 | List brands; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("categories") 25 | List categories; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("productNames") 31 | List productNames; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("products") 37 | List products; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/polymorphism/PolymorphicMapping.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.polymorphism; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public final class PolymorphicMapping { 7 | private final String discriminator; 8 | private final Map mapping; 9 | 10 | public PolymorphicMapping(String discriminator) { 11 | this.discriminator = discriminator; 12 | this.mapping = new HashMap<>(); 13 | } 14 | 15 | public String getDiscriminator() { 16 | return this.discriminator; 17 | } 18 | 19 | public void addMapping(String discriminatorValue, String className) { 20 | this.mapping.put(discriminatorValue, className); 21 | } 22 | 23 | public Map getMapping() { 24 | return this.mapping; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/AdvancedAttribute.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class AdvancedAttribute implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("key") 25 | String key; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("label") 31 | String label; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("type") 37 | String type; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("values") 43 | List values; 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BaseCategory.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BaseCategory implements ApiObjectInterface { 15 | /** 16 | * Unique identifier of the category 17 | */ 18 | @SerializedName("categoryId") 19 | Integer categoryId; 20 | 21 | /** 22 | * Name of the category 23 | */ 24 | @SerializedName("categoryName") 25 | String categoryName; 26 | 27 | /** 28 | * Parent ID of the category 29 | */ 30 | @SerializedName("categoryParentId") 31 | Integer categoryParentId; 32 | 33 | /** 34 | * Category path as text 35 | */ 36 | @SerializedName("categoryPath") 37 | String categoryPath; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/LowestPriorPrice.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class LowestPriorPrice implements ApiObjectInterface { 15 | /** 16 | * The lowest price including tax. 17 | */ 18 | @SerializedName("withTax") 19 | Integer withTax; 20 | 21 | /** 22 | * The relative difference from the lowest prior price to the current price. 23 | 24 | If the value is positive, it means that the current price is higher than the lowest prior price. 25 | If the value is negative, it means that the current price is lower than the lowest prior price. 26 | 27 | */ 28 | @SerializedName("relativeDifferenceToPrice") 29 | Double relativeDifferenceToPrice; 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/DisplayDataValue.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class DisplayDataValue implements ApiObjectInterface { 15 | /** 16 | * A key identifying which data is displayed here. 17 | The value is not shown in the Scayle Checkout. 18 | 19 | */ 20 | @SerializedName("key") 21 | String key; 22 | 23 | /** 24 | * The label explaining the value which will be displayed in the Scayle Checkout for the Basket Item. 25 | */ 26 | @SerializedName("label") 27 | String label; 28 | 29 | /** 30 | * The value which will be displayed in the Scayle Checkout for the Basket Item. 31 | */ 32 | @SerializedName("value") 33 | String value; 34 | 35 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Basket.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Basket implements ApiObjectInterface { 15 | /** 16 | * A unique key identifying the basket. 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("items") 25 | List items; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("cost") 31 | Price cost; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("packages") 37 | List packages; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("applicablePromotions") 43 | List applicablePromotions; 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Stock.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Stock implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("supplierId") 19 | Integer supplierId; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("warehouseId") 25 | Integer warehouseId; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("quantity") 31 | Integer quantity; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("isSellableWithoutStock") 37 | Boolean isSellableWithoutStock; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("expectedAvailabilityAt") 43 | String expectedAvailabilityAt; 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Match.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Match implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("type") 19 | String type; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("id") 25 | Integer id; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("name") 31 | String name; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("match") 37 | String match; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("attributeGroup") 43 | Object attributeGroup; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("attributeIds") 49 | List attributeIds; 50 | 51 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/RedirectTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class RedirectTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGet() throws Exception { 19 | 20 | RedirectsResponse responseEntity = this.api.redirects().get( null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/RedirectGetResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/PromotionTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class PromotionTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGet() throws Exception { 19 | 20 | PromotionsResponse responseEntity = this.api.promotions().get( null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/PromotionGetResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/AttributeTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class AttributeTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGetByKey() throws Exception { 19 | 20 | Attribute responseEntity = this.api.attributes().getByKey("1", null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/AttributeGetByKeyResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/VariantTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class VariantTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGetByIds() throws Exception { 19 | 20 | VariantsResponse responseEntity = this.api.variants().getByIds("1", null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/VariantGetByIdsResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/AttributeService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class AttributeService extends AbstractService { 14 | public AttributeService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public Attribute getByKey(String groupName) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)Attribute.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("get", this.resolvePath("attributes/%s", groupName), options, responseModel); 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/SearchTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class SearchTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testSuggestions() throws Exception { 19 | 20 | SearchSuggestions responseEntity = this.api.searches().suggestions("1", null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/SearchSuggestionsResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/CreateWishlistBody.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class CreateWishlistBody implements ApiObjectInterface { 15 | /** 16 | * Variant ID to add to the wishlist. 17 | */ 18 | @SerializedName("variantId") 19 | Integer variantId; 20 | 21 | /** 22 | * Product ID to add to the wishlist. When provided, the first found in-stock variant of the product will be added. 23 | */ 24 | @SerializedName("productId") 25 | Integer productId; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("customData") 31 | Map customData; 32 | 33 | /** 34 | * The quantity for the variant. 35 | */ 36 | @SerializedName("quantity") 37 | Integer quantity = "1"; 38 | 39 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/ShopConfigurationTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class ShopConfigurationTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGet() throws Exception { 19 | 20 | ShopConfiguration responseEntity = this.api.shopConfigurations().get("1", null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/ShopConfigurationGetResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/FilterTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class FilterTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGet() throws Exception { 19 | 20 | ApiCollection responseEntity = this.api.filters().get( null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/FilterGetResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | for (Filter entity : responseEntity.getEntities()) { 29 | } 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BrandOrCategorySuggestion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BrandOrCategorySuggestion implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("attributeFilters") 19 | List attributeFilters; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("brand") 25 | Object brand; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("category") 31 | Category category; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("primaryMatch") 37 | String primaryMatch; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("productCount") 43 | Integer productCount; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("suggestion") 49 | String suggestion; 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ShopConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ShopConfiguration implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("shopId") 19 | Integer shopId; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("name") 25 | String name; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("shopCustomData") 31 | Map shopCustomData; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("properties") 37 | List properties; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("customData") 43 | Map customData; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("country") 49 | String country; 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BasketItemDisplayData.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BasketItemDisplayData implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("meta") 19 | DisplayDataValue meta; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("name") 25 | DisplayDataValue name; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("identifier") 31 | DisplayDataValue identifier; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("attribute-1") 37 | DisplayDataValue attribute-1; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("attribute-2") 43 | DisplayDataValue attribute-2; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("attribute-3") 49 | DisplayDataValue attribute-3; 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ApiOptions.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class ApiOptions { 7 | private final Map options; 8 | 9 | private ApiOptions(Map options) { 10 | this.options = options; 11 | } 12 | 13 | public Map getOptions() { 14 | return this.options; 15 | } 16 | 17 | public static ApiOptionsBuilder builder() { 18 | return new ApiOptionsBuilder(); 19 | } 20 | 21 | public static class ApiOptionsBuilder { 22 | private final Map options; 23 | 24 | public ApiOptionsBuilder() { 25 | this.options = new HashMap(); 26 | } 27 | 28 | public ApiOptionsBuilder addOption(String key, Object value) { 29 | this.options.put(key, value); 30 | return this; 31 | } 32 | 33 | public ApiOptions build() { 34 | return new ApiOptions(this.options); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/serializer/TimestampAdapter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.serializer; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.Map; 5 | import java.time.OffsetDateTime; 6 | 7 | import com.google.gson.JsonDeserializationContext; 8 | import com.google.gson.JsonDeserializer; 9 | import com.google.gson.JsonElement; 10 | import com.google.gson.JsonObject; 11 | import com.google.gson.JsonParseException; 12 | import com.google.gson.JsonSerializationContext; 13 | import com.google.gson.JsonSerializer; 14 | 15 | public class TimestampAdapter implements JsonSerializer, JsonDeserializer { 16 | 17 | @Override 18 | public OffsetDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 19 | String timestamp = json.getAsString(); 20 | 21 | return OffsetDateTime.parse(timestamp); 22 | } 23 | 24 | @Override 25 | public JsonElement serialize(OffsetDateTime src, Type typeOfSrc, JsonSerializationContext context) { 26 | return context.serialize(src); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Pagination.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Pagination implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("current") 19 | Integer current; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("first") 25 | Integer first; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("last") 31 | Integer last; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("next") 37 | Integer next; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("page") 43 | Integer page; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("perPage") 49 | Integer perPage; 50 | 51 | /** 52 | * 53 | */ 54 | @SerializedName("prev") 55 | Integer prev; 56 | 57 | /** 58 | * 59 | */ 60 | @SerializedName("total") 61 | Integer total; 62 | 63 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Redirect.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Redirect implements ApiObjectInterface { 15 | /** 16 | * The unique identifier of the redirect 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * The source URL for the redirect 23 | */ 24 | @SerializedName("source") 25 | String source; 26 | 27 | /** 28 | * The target URL for the redirect 29 | */ 30 | @SerializedName("target") 31 | String target; 32 | 33 | /** 34 | * The status code for the redirect 35 | */ 36 | @SerializedName("statusCode") 37 | Integer statusCode; 38 | 39 | /** 40 | * The priority for the redirect 41 | */ 42 | @SerializedName("priority") 43 | Integer priority; 44 | 45 | /** 46 | * The flag if the source is a regex 47 | */ 48 | @SerializedName("isRegex") 49 | Boolean isRegex; 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Campaign.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Campaign implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("name") 25 | String name; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("key") 31 | String key; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("description") 37 | String description; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("reduction") 43 | Integer reduction; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("customData") 49 | Object customData; 50 | 51 | /** 52 | * 53 | */ 54 | @SerializedName("start_at") 55 | String start_at; 56 | 57 | /** 58 | * 59 | */ 60 | @SerializedName("end_at") 61 | String end_at; 62 | 63 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Price.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Price implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("appliedReductions") 19 | List appliedReductions; 20 | 21 | /** 22 | * The currency of the price. 23 | */ 24 | @SerializedName("currencyCode") 25 | String currencyCode; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("reference") 31 | Object reference; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("tax") 37 | Tax tax; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("withoutTax") 43 | Integer withoutTax; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("withTax") 49 | Integer withTax; 50 | 51 | /** 52 | * 53 | */ 54 | @SerializedName("recommendedRetailPrice") 55 | Integer recommendedRetailPrice; 56 | 57 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/CreateBasketItemBody.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class CreateBasketItemBody implements ApiObjectInterface { 15 | /** 16 | * The quantity for the variant. 17 | */ 18 | @SerializedName("quantity") 19 | Integer quantity; 20 | 21 | /** 22 | * The variant to be added to the basket. 23 | */ 24 | @SerializedName("variantId") 25 | Integer variantId; 26 | 27 | /** 28 | * An optional promotion ID which should be applied to this item. 29 | */ 30 | @SerializedName("promotionId") 31 | String promotionId; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("customData") 37 | BasketItemCustomData customData; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("displayData") 43 | BasketItemDisplayData displayData; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("itemGroup") 49 | ItemGroup itemGroup; 50 | 51 | } -------------------------------------------------------------------------------- /src/test/resources/fixtures/BrandGetResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "entities": [ 3 | { 4 | "id": 21, 5 | "name": "About You", 6 | "slug": "aboutyou", 7 | "group": "default", 8 | "isActive": true, 9 | "logoHash": "01dfae6e5d4d90d9892622325959afbe", 10 | "createdAt": "2019-04-17 16:05:36", 11 | "updatedAt": "2019-04-17 16:05:36", 12 | "indexedAt": "2023-04-26 16:05:36" 13 | }, 14 | { 15 | "id": 22, 16 | "name": "Edited", 17 | "slug": "edited", 18 | "group": "default", 19 | "externalReference": "0815", 20 | "isActive": true, 21 | "logoHash": "8743b52063cd84097a65d1633f5c74f5", 22 | "createdAt": "2019-04-17 16:05:36", 23 | "updatedAt": "2019-04-17 16:05:36", 24 | "indexedAt": "2023-04-26 16:05:36" 25 | } 26 | ], 27 | "pagination": { 28 | "current": 2, 29 | "first": 1, 30 | "last": 49, 31 | "next": 2, 32 | "page": 1, 33 | "perPage": 2, 34 | "prev": 1, 35 | "total": 4879 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/TypeaheadRequestBody.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class TypeaheadRequestBody implements ApiObjectInterface { 15 | /** 16 | * The fuzziness parameter can enable some typo tolerance. Available values are 0, 1, 2, and auto. Defaults to auto. Note: The value set in the SCAYLE Panel will not impact this search. 17 | */ 18 | @SerializedName("fuzziness") 19 | Object fuzziness; 20 | 21 | /** 22 | * The `categoryId` parameter can filter by category ID. 23 | */ 24 | @SerializedName("categoryId") 25 | Integer categoryId; 26 | 27 | /** 28 | * The `limit` parameter allows limiting the number of suggested products returned. 29 | */ 30 | @SerializedName("limit") 31 | Integer limit; 32 | 33 | /** 34 | * The `term` parameter allows you to query for any entity with a full or partial match with the given term. 35 | */ 36 | @SerializedName("term") 37 | String term; 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/UpdateBasketItemBody.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class UpdateBasketItemBody implements ApiObjectInterface { 15 | /** 16 | * The updated quantity for the basket item. 17 | */ 18 | @SerializedName("quantity") 19 | Integer quantity; 20 | 21 | /** 22 | * Updates the promotion id of the item. 23 | 24 | If the 'promotionId' property is not sent in the request no update is performed on the field. 25 | if the value is null then any previous applied promotion will be removed from the item. 26 | 27 | */ 28 | @SerializedName("promotionId") 29 | String promotionId; 30 | 31 | /** 32 | * 33 | */ 34 | @SerializedName("customData") 35 | BasketItemCustomData customData; 36 | 37 | /** 38 | * 39 | */ 40 | @SerializedName("displayData") 41 | BasketItemDisplayData displayData; 42 | 43 | /** 44 | * 45 | */ 46 | @SerializedName("itemGroup") 47 | ItemGroup itemGroup; 48 | 49 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ItemGroup.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ItemGroup implements ApiObjectInterface { 15 | /** 16 | * A unique identifier for the item group which should be used for all basket items of the item group. 17 | 18 | Any string based identifier can be chosen and it only has to be unique within the current basket. 19 | 20 | */ 21 | @SerializedName("id") 22 | String id; 23 | 24 | /** 25 | * Whether or not the current item is the main item within the item group. 26 | This property can be used for display purposes to only show the main item within the Checkout. 27 | 28 | */ 29 | @SerializedName("isMainItem") 30 | Boolean isMainItem; 31 | 32 | /** 33 | * Whether or not the item is required to be present for the item group. 34 | When you delete an item from your basket which is required for the item group, all other items assigned to the item group will also be deleted. 35 | 36 | */ 37 | @SerializedName("isRequired") 38 | Boolean isRequired; 39 | 40 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Attribute.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Attribute implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * Reference that identifies the attribute 23 | */ 24 | @SerializedName("key") 25 | String key; 26 | 27 | /** 28 | * The label that describes the attribute group will be set according to the shop's language in the SCAYLE Panel. 29 | */ 30 | @SerializedName("label") 31 | String label; 32 | 33 | /** 34 | * A flag which determines whether an attribute has a single or possibly multiple values. 35 | */ 36 | @SerializedName("multiSelect") 37 | Boolean multiSelect; 38 | 39 | /** 40 | * Attribute type 41 | */ 42 | @SerializedName("type") 43 | String type; 44 | 45 | /** 46 | * The values are a collection of attributes from the attribute group. 47 | */ 48 | @SerializedName("values") 49 | List values; 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/ProductCategory.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class ProductCategory implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("categoryId") 19 | Integer categoryId; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("categoryHidden") 25 | Boolean categoryHidden; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("categoryName") 31 | String categoryName; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("categoryProperties") 37 | Object categoryProperties; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("shopLevelCustomData") 43 | Object shopLevelCustomData; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("countryLevelCustomData") 49 | Object countryLevelCustomData; 50 | 51 | /** 52 | * 53 | */ 54 | @SerializedName("categoryUrl") 55 | String categoryUrl; 56 | 57 | /** 58 | * 59 | */ 60 | @SerializedName("categorySlug") 61 | String categorySlug; 62 | 63 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/FilterService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class FilterService extends AbstractService { 14 | public FilterService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public List get() throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)Filter.class; 20 | ApiOptions options = null; 21 | 22 | return this.requestCollection("get", this.resolvePath("filters"), options, responseModel); 23 | } 24 | public List get(ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)Filter.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.requestCollection("get", this.resolvePath("filters"), combinedOptions, responseModel); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/factory/ServiceFactory.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.factory; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.scayle.storefrontapi.http.HttpClient; 7 | import com.scayle.storefrontapi.service.AbstractService; 8 | 9 | public class ServiceFactory { 10 | private HttpClient httpClient; 11 | private Map instances; 12 | 13 | public ServiceFactory(HttpClient httpClient) { 14 | this.httpClient = httpClient; 15 | this.instances = new HashMap<>(); 16 | } 17 | 18 | public T getService(String className) { 19 | if (!this.instances.containsKey(className)) { 20 | try { 21 | Class clazz = Class.forName(className); 22 | Object instance = clazz.getDeclaredConstructor(HttpClient.class).newInstance(this.httpClient); 23 | 24 | if (instance instanceof AbstractService) { 25 | AbstractService service = (AbstractService) instance; 26 | this.instances.put(className, service); 27 | } 28 | } catch (Exception exception) { 29 | System.err.println(exception.getMessage()); 30 | return null; 31 | } 32 | } 33 | 34 | return (T) this.instances.get(className); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/RedirectService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class RedirectService extends AbstractService { 14 | public RedirectService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public RedirectsResponse get() throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)RedirectsResponse.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("get", this.resolvePath("redirects"), options, responseModel); 23 | } 24 | public RedirectsResponse get(ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)RedirectsResponse.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("get", this.resolvePath("redirects"), combinedOptions, responseModel); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/PromotionService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class PromotionService extends AbstractService { 14 | public PromotionService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public PromotionsResponse get() throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)PromotionsResponse.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("get", this.resolvePath("promotions"), options, responseModel); 23 | } 24 | public PromotionsResponse get(ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)PromotionsResponse.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("get", this.resolvePath("promotions"), combinedOptions, responseModel); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/TypeaheadBody.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class TypeaheadBody implements ApiObjectInterface { 15 | /** 16 | * The fuzziness parameter can enable some typo tolerance. Available values are 0, 1, 2, and auto. Defaults to auto. Note: The value set in the SCAYLE Panel will not impact this search. 17 | */ 18 | @SerializedName("fuzziness") 19 | String fuzziness; 20 | 21 | /** 22 | * The `likedBrands` parameter can boost and adjust results by matching the given brand IDs. 23 | */ 24 | @SerializedName("likedBrands") 25 | List likedBrands; 26 | 27 | /** 28 | * The `categoryId` parameter can filter by category ID. 29 | */ 30 | @SerializedName("categoryId") 31 | Integer categoryId; 32 | 33 | /** 34 | * The `limit` parameter allows limiting the number of suggested products returned. 35 | */ 36 | @SerializedName("limit") 37 | Integer limit; 38 | 39 | /** 40 | * The `term` parameter allows you to query for any entity with a full or partial match with the given term. 41 | */ 42 | @SerializedName("term") 43 | String term; 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/NavigationService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class NavigationService extends AbstractService { 14 | public NavigationService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public List getAll() throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)NavigationTree.class; 20 | ApiOptions options = null; 21 | 22 | return this.requestCollection("get", this.resolvePath("navigation/trees"), options, responseModel); 23 | } 24 | public NavigationTree getById(Integer navigationTreeId) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)NavigationTree.class; 26 | ApiOptions options = null; 27 | 28 | return this.request("get", this.resolvePath("navigation/trees/%s", navigationTreeId), options, responseModel); 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/BrandTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class BrandTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGet() throws Exception { 19 | 20 | BrandsResponse responseEntity = this.api.brands().get( null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/BrandGetResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | @Test 31 | public void testGetById() throws Exception { 32 | 33 | BrandsResponse responseEntity = this.api.brands().getById(1, null); 34 | 35 | String expectedResponseJson = this.loadFixture("/fixtures/BrandGetByIdResponse.json"); 36 | assertThatJson(expectedResponseJson) 37 | .when(TREATING_NULL_AS_ABSENT) 38 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 39 | 40 | 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/WishlistItem.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class WishlistItem implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("packageId") 25 | Integer packageId; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("quantity") 31 | Integer quantity; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("status") 37 | String status; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("product") 43 | Product product; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("variant") 49 | Variant variant; 50 | 51 | /** 52 | * 53 | */ 54 | @SerializedName("productId") 55 | Integer productId; 56 | 57 | /** 58 | * 59 | */ 60 | @SerializedName("masterKey") 61 | String masterKey; 62 | 63 | /** 64 | * 65 | */ 66 | @SerializedName("variantId") 67 | Integer variantId; 68 | 69 | /** 70 | * 71 | */ 72 | @SerializedName("customData") 73 | Map customData; 74 | 75 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/MatchRedirectTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class MatchRedirectTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testMatch() throws Exception { 19 | String expectedRequestJson = this.loadFixture("/fixtures/MatchRedirectMatchRequest.json"); 20 | MatchRedirectBody requestEntity = this.jsonSerializer.unserializeApiObject(expectedRequestJson, MatchRedirectBody.class); 21 | 22 | assertThatJson(expectedRequestJson) 23 | .when(TREATING_NULL_AS_ABSENT) 24 | .isEqualTo(this.jsonSerializer.serializeApiObject(requestEntity)); 25 | 26 | MatchRedirect responseEntity = this.api.matchRedirects().match(requestEntity, null); 27 | 28 | String expectedResponseJson = this.loadFixture("/fixtures/MatchRedirectMatchResponse.json"); 29 | assertThatJson(expectedResponseJson) 30 | .when(TREATING_NULL_AS_ABSENT) 31 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 32 | 33 | 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/MatchRedirectService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class MatchRedirectService extends AbstractService { 14 | public MatchRedirectService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public MatchRedirect match(MatchRedirectBody model) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)MatchRedirect.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("post", this.resolvePath("redirects"), options, responseModel, model); 23 | } 24 | public MatchRedirect match(MatchRedirectBody model, ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)MatchRedirect.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("post", this.resolvePath("redirects"), combinedOptions, responseModel, model); 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/ProductTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class ProductTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGetById() throws Exception { 19 | 20 | Product responseEntity = this.api.products().getById(1, null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/ProductGetByIdResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | @Test 31 | public void testQuery() throws Exception { 32 | 33 | ProductsResponse responseEntity = this.api.products().query( null); 34 | 35 | String expectedResponseJson = this.loadFixture("/fixtures/ProductQueryResponse.json"); 36 | assertThatJson(expectedResponseJson) 37 | .when(TREATING_NULL_AS_ABSENT) 38 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 39 | 40 | 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/TypeaheadTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class TypeaheadTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testPostSuggestions() throws Exception { 19 | String expectedRequestJson = this.loadFixture("/fixtures/TypeaheadPostSuggestionsRequest.json"); 20 | TypeaheadBody requestEntity = this.jsonSerializer.unserializeApiObject(expectedRequestJson, TypeaheadBody.class); 21 | 22 | assertThatJson(expectedRequestJson) 23 | .when(TREATING_NULL_AS_ABSENT) 24 | .isEqualTo(this.jsonSerializer.serializeApiObject(requestEntity)); 25 | 26 | Typeahead responseEntity = this.api.typeaheads().postSuggestions("1", requestEntity, null); 27 | 28 | String expectedResponseJson = this.loadFixture("/fixtures/TypeaheadPostSuggestionsResponse.json"); 29 | assertThatJson(expectedResponseJson) 30 | .when(TREATING_NULL_AS_ABSENT) 31 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 32 | 33 | 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/CampaignTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class CampaignTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGetAll() throws Exception { 19 | 20 | CampaignsResponse responseEntity = this.api.campaigns().getAll( null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/CampaignGetAllResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | @Test 31 | public void testGetById() throws Exception { 32 | 33 | Campaign responseEntity = this.api.campaigns().getById(1, null); 34 | 35 | String expectedResponseJson = this.loadFixture("/fixtures/CampaignGetByIdResponse.json"); 36 | assertThatJson(expectedResponseJson) 37 | .when(TREATING_NULL_AS_ABSENT) 38 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 39 | 40 | 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/polymorphism/Polymorphic.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.polymorphism; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | 7 | public final class Polymorphic { 8 | private Map, Map, PolymorphicMapping>> polymorphic; 9 | 10 | public Polymorphic() { 11 | this.polymorphic = new HashMap<>(); 12 | this.addMappings(); 13 | } 14 | 15 | private void addMappings() { 16 | // Generated 17 | } 18 | 19 | private void addMapping(Class modelClass, Class interfaceClass, String discriminator, String discriminatorValue, String concreteClassname) { 20 | if (!this.polymorphic.containsKey(modelClass)) { 21 | PolymorphicMapping polymorphicMapping = new PolymorphicMapping(discriminator); 22 | 23 | HashMap, PolymorphicMapping> interfaceMapping = new HashMap<>(); 24 | interfaceMapping.put(interfaceClass, polymorphicMapping); 25 | 26 | this.polymorphic.put(modelClass, interfaceMapping); 27 | } 28 | 29 | this.polymorphic.get(modelClass).get(interfaceClass).addMapping(discriminatorValue, concreteClassname); 30 | } 31 | 32 | public Map, PolymorphicMapping> getMappingForClass(Class className) { 33 | return this.polymorphic.get(className); 34 | } 35 | 36 | public boolean hasClassMapping(Class className) { 37 | return this.polymorphic.containsKey(className); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Filter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Filter implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("name") 25 | String name; 26 | 27 | /** 28 | * short text to describe the current category (usable, for example, in URLs as `fashion`). 29 | */ 30 | @SerializedName("slug") 31 | String slug; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("attributeGroupType") 37 | String attributeGroupType; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("type") 43 | String type; 44 | 45 | /** 46 | * If type == "boolean", this field will be populated. 47 | */ 48 | @SerializedName("booleanFilterValues") 49 | List booleanFilterValues; 50 | 51 | /** 52 | * If type == "range", this field will be populated. 53 | */ 54 | @SerializedName("rangeFilterValues") 55 | List rangeFilterValues; 56 | 57 | /** 58 | * If type == "attributes", this field will be populated. 59 | */ 60 | @SerializedName("attributeFilterValues") 61 | List attributeFilterValues; 62 | 63 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/NavigationItem.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class NavigationItem implements ApiObjectInterface { 15 | /** 16 | * 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * 23 | */ 24 | @SerializedName("assets") 25 | Object assets; 26 | 27 | /** 28 | * 29 | */ 30 | @SerializedName("name") 31 | String name; 32 | 33 | /** 34 | * 35 | */ 36 | @SerializedName("type") 37 | String type; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("visibleFrom") 43 | String visibleFrom; 44 | 45 | /** 46 | * 47 | */ 48 | @SerializedName("visibleTo") 49 | String visibleTo; 50 | 51 | /** 52 | * 53 | */ 54 | @SerializedName("options") 55 | Object options; 56 | 57 | /** 58 | * 59 | */ 60 | @SerializedName("extraFilters") 61 | NavigationItemExtraFilter extraFilters; 62 | 63 | /** 64 | * 65 | */ 66 | @SerializedName("category") 67 | Category category; 68 | 69 | /** 70 | * 71 | */ 72 | @SerializedName("children") 73 | List children; 74 | 75 | /** 76 | * 77 | */ 78 | @SerializedName("customData") 79 | Object customData; 80 | 81 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/NavigationTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class NavigationTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGetAll() throws Exception { 19 | 20 | ApiCollection responseEntity = this.api.navigations().getAll( null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/NavigationGetAllResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | for (NavigationTree entity : responseEntity.getEntities()) { 29 | } 30 | } 31 | 32 | @Test 33 | public void testGetById() throws Exception { 34 | 35 | NavigationTree responseEntity = this.api.navigations().getById(1, null); 36 | 37 | String expectedResponseJson = this.loadFixture("/fixtures/NavigationGetByIdResponse.json"); 38 | assertThatJson(expectedResponseJson) 39 | .when(TREATING_NULL_AS_ABSENT) 40 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 41 | 42 | 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/exception/ApiErrorException.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.exception; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.google.common.collect.Iterables; 7 | import com.google.gson.JsonElement; 8 | import com.google.gson.JsonObject; 9 | import com.google.gson.JsonPrimitive; 10 | 11 | public class ApiErrorException extends RuntimeException { 12 | private List errors; 13 | private Integer statusCode; 14 | 15 | public ApiErrorException(JsonObject errorResponse, Integer statusCode) { 16 | this.statusCode = statusCode; 17 | this.errors = this.parseErrorResponse(errorResponse); 18 | } 19 | 20 | public ApiError getFirstError() { 21 | return Iterables.getLast(this.errors); 22 | } 23 | 24 | public List getErrors() { 25 | return this.errors; 26 | } 27 | 28 | private List parseErrorResponse(JsonObject errorResponse) { 29 | List errors = new ArrayList<>(); 30 | JsonPrimitive errorKeyPrimitive = errorResponse.getAsJsonPrimitive("code"); 31 | String errorKey = errorKeyPrimitive == null ? String.valueOf(this.statusCode) : errorKeyPrimitive.getAsString(); 32 | JsonPrimitive messagePrimitive = errorResponse.getAsJsonPrimitive("message"); 33 | String message = messagePrimitive == null ? "" : messagePrimitive.getAsString(); 34 | ApiError apiError = new ApiError(errorKey, message, ""); 35 | errors.add(apiError); 36 | 37 | return errors; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/serializer/AttributeValuesAdapter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.serializer; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.Map; 5 | import java.util.List; 6 | import java.util.ArrayList; 7 | 8 | import com.google.gson.JsonDeserializationContext; 9 | import com.google.gson.JsonDeserializer; 10 | import com.google.gson.JsonElement; 11 | import com.google.gson.JsonObject; 12 | import com.google.gson.JsonArray; 13 | import com.google.gson.JsonParseException; 14 | import com.google.gson.JsonSerializationContext; 15 | import com.google.gson.JsonSerializer; 16 | 17 | import com.scayle.storefrontapi.model.AttributeValue; 18 | 19 | public class AttributeValuesAdapter implements JsonSerializer>, JsonDeserializer> { 20 | 21 | @Override 22 | public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 23 | List list = new ArrayList(); 24 | 25 | if (json.isJsonObject()) { 26 | list.add(context.deserialize(json, AttributeValue.class)); 27 | } else if (json.isJsonArray()) { 28 | JsonArray jsonArray = json.getAsJsonArray(); 29 | jsonArray.forEach((v) -> list.add(context.deserialize(v, AttributeValue.class))); 30 | } 31 | 32 | return list; 33 | } 34 | 35 | @Override 36 | public JsonElement serialize(List src, Type typeOfSrc, JsonSerializationContext context) { 37 | return context.serialize(src); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/CreateBasketBody.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class CreateBasketBody implements ApiObjectInterface { 15 | /** 16 | * For each item, you can add an additional custom data array. This will not change the API behavior. The data will remain attached to the basket item and you may retrieve it at any time during or after the checkout and order process. 17 | 18 | */ 19 | @SerializedName("customData") 20 | Object customData; 21 | 22 | /** 23 | * Custom basket item properties for display during SCAYLE checkout and order process can be set with displayData. 24 | */ 25 | @SerializedName("displayData") 26 | Object displayData; 27 | 28 | /** 29 | * The quantity for the variant. 30 | 31 | */ 32 | @SerializedName("quantity") 33 | Integer quantity; 34 | 35 | /** 36 | * If you are operating multiple shops (for example, for different domain names or different languages), each shop is identified by its specific `shopId`. 37 | 38 | */ 39 | @SerializedName("shopId") 40 | Integer shopId; 41 | 42 | /** 43 | * The variant to be added to the basket. This is the only required parameter. 44 | */ 45 | @SerializedName("variantId") 46 | Integer variantId; 47 | 48 | /** 49 | * 50 | */ 51 | @SerializedName("itemGroup") 52 | Object itemGroup; 53 | 54 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Promotion.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Promotion implements ApiObjectInterface { 15 | /** 16 | * The unique identifier of the promotion 17 | */ 18 | @SerializedName("id") 19 | String id; 20 | 21 | /** 22 | * Promotion name 23 | */ 24 | @SerializedName("name") 25 | String name; 26 | 27 | /** 28 | * Promotion's initial and end date, formatted according to RFC 3339. 29 | */ 30 | @SerializedName("schedule") 31 | Object schedule; 32 | 33 | /** 34 | * Promotion's status 35 | */ 36 | @SerializedName("isActive") 37 | Boolean isActive; 38 | 39 | /** 40 | * 41 | */ 42 | @SerializedName("effect") 43 | Object effect; 44 | 45 | /** 46 | * Promotion's conditions 47 | */ 48 | @SerializedName("conditions") 49 | List conditions; 50 | 51 | /** 52 | * Promotion's custom data 53 | */ 54 | @SerializedName("customData") 55 | Object customData; 56 | 57 | /** 58 | * The priority of the promotion compared to other promotions. 59 | This can be used to decide which promotion to apply if there is a conflict between two. 60 | 61 | */ 62 | @SerializedName("priority") 63 | Double priority; 64 | 65 | /** 66 | * 67 | */ 68 | @SerializedName("tiers") 69 | List tiers; 70 | 71 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/CampaignService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class CampaignService extends AbstractService { 14 | public CampaignService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public CampaignsResponse getAll() throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)CampaignsResponse.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("get", this.resolvePath("campaigns"), options, responseModel); 23 | } 24 | public CampaignsResponse getAll(ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)CampaignsResponse.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("get", this.resolvePath("campaigns"), combinedOptions, responseModel); 29 | } 30 | public Campaign getById(Integer campaignId) throws ApiErrorException, ConnectionException { 31 | Class responseModel = (Class)(Class)Campaign.class; 32 | ApiOptions options = null; 33 | 34 | return this.request("get", this.resolvePath("campaigns/%s", campaignId), options, responseModel); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/polymorphism/PolymorphicAdapter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.polymorphism; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.Map; 5 | 6 | import com.google.gson.JsonDeserializationContext; 7 | import com.google.gson.JsonDeserializer; 8 | import com.google.gson.JsonElement; 9 | import com.google.gson.JsonObject; 10 | import com.google.gson.JsonParseException; 11 | import com.google.gson.JsonSerializationContext; 12 | import com.google.gson.JsonSerializer; 13 | 14 | public class PolymorphicAdapter 15 | implements JsonSerializer, JsonDeserializer { 16 | 17 | private String discriminator; 18 | private Map classMap; 19 | 20 | public PolymorphicAdapter(String discriminator, Map classMap) { 21 | this.discriminator = discriminator; 22 | this.classMap = classMap; 23 | } 24 | 25 | @Override 26 | public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 27 | JsonObject jsonObject = json.getAsJsonObject(); 28 | String discriminatorValue = jsonObject.getAsJsonPrimitive(this.discriminator).getAsString(); 29 | 30 | String modelName = this.classMap.get(discriminatorValue); 31 | 32 | try { 33 | Class clazz = Class.forName(modelName); 34 | return context.deserialize(json, clazz); 35 | } catch (Exception e) { 36 | System.err.println("Error while deserializing: " + e.getMessage()); 37 | } 38 | 39 | return null; 40 | } 41 | 42 | @Override 43 | public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { 44 | return context.serialize(src); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/TypeaheadService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class TypeaheadService extends AbstractService { 14 | public TypeaheadService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public Typeahead postSuggestions(String term, TypeaheadBody model) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)Typeahead.class; 20 | ApiOptions options = null; 21 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 22 | optionsBuilder.addOption("term", term); 23 | options = optionsBuilder.build(); 24 | 25 | return this.request("post", this.resolvePath("typeahead"), options, responseModel, model); 26 | } 27 | public Typeahead postSuggestions(String term, TypeaheadBody model, ApiOptions options) throws ApiErrorException, ConnectionException { 28 | Class responseModel = (Class)(Class)Typeahead.class; 29 | ApiOptions combinedOptions = options; 30 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 31 | combinedOptions.getOptions().forEach(optionsBuilder::addOption); 32 | optionsBuilder.addOption("term", term); 33 | combinedOptions = optionsBuilder.build(); 34 | 35 | return this.request("post", this.resolvePath("typeahead"), combinedOptions, responseModel, model); 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/SearchService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class SearchService extends AbstractService { 14 | public SearchService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public SearchSuggestions suggestions(String term) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)SearchSuggestions.class; 20 | ApiOptions options = null; 21 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 22 | optionsBuilder.addOption("term", term); 23 | options = optionsBuilder.build(); 24 | 25 | return this.request("get", this.resolvePath("search/suggestions"), options, responseModel); 26 | } 27 | public SearchSuggestions suggestions(String term, ApiOptions options) throws ApiErrorException, ConnectionException { 28 | Class responseModel = (Class)(Class)SearchSuggestions.class; 29 | ApiOptions combinedOptions = options; 30 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 31 | combinedOptions.getOptions().forEach(optionsBuilder::addOption); 32 | optionsBuilder.addOption("term", term); 33 | combinedOptions = optionsBuilder.build(); 34 | 35 | return this.request("get", this.resolvePath("search/suggestions"), combinedOptions, responseModel); 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/ShopConfigurationService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class ShopConfigurationService extends AbstractService { 14 | public ShopConfigurationService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public ShopConfiguration get(String locale) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)ShopConfiguration.class; 20 | ApiOptions options = null; 21 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 22 | optionsBuilder.addOption("locale", locale); 23 | options = optionsBuilder.build(); 24 | 25 | return this.request("get", this.resolvePath("shop-configuration"), options, responseModel); 26 | } 27 | public ShopConfiguration get(String locale, ApiOptions options) throws ApiErrorException, ConnectionException { 28 | Class responseModel = (Class)(Class)ShopConfiguration.class; 29 | ApiOptions combinedOptions = options; 30 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 31 | combinedOptions.getOptions().forEach(optionsBuilder::addOption); 32 | optionsBuilder.addOption("locale", locale); 33 | combinedOptions = optionsBuilder.build(); 34 | 35 | return this.request("get", this.resolvePath("shop-configuration"), combinedOptions, responseModel); 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Brand.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | import java.time.OffsetDateTime; 12 | 13 | @Getter 14 | @Setter 15 | public class Brand implements ApiObjectInterface { 16 | /** 17 | * The unique identifier of the brand (referred as `attributeId`), can be used for retrieving specific brand. ID which would be used to filter for brands in the `products` and `filters` endpoint 18 | */ 19 | @SerializedName("id") 20 | Integer id; 21 | 22 | /** 23 | * short text to describe the current category (usable, for example, in URLs as `fashion`). 24 | */ 25 | @SerializedName("slug") 26 | String slug; 27 | 28 | /** 29 | * 30 | */ 31 | @SerializedName("name") 32 | String name; 33 | 34 | /** 35 | * 36 | */ 37 | @SerializedName("customData") 38 | BrandCustomData customData; 39 | 40 | /** 41 | * External reference set by the client to integrate a third-party party system. 42 | */ 43 | @SerializedName("externalReference") 44 | String externalReference; 45 | 46 | /** 47 | * Brand group. 48 | */ 49 | @SerializedName("group") 50 | String group; 51 | 52 | /** 53 | * Whether the brand is currently active or not. 54 | */ 55 | @SerializedName("isActive") 56 | Boolean isActive; 57 | 58 | /** 59 | * Logo hash used for generating the full url. 60 | */ 61 | @SerializedName("logoHash") 62 | String logoHash; 63 | 64 | /** 65 | * 66 | */ 67 | @SerializedName("createdAt") 68 | OffsetDateTime createdAt; 69 | 70 | /** 71 | * 72 | */ 73 | @SerializedName("updatedAt") 74 | OffsetDateTime updatedAt; 75 | 76 | /** 77 | * 78 | */ 79 | @SerializedName("indexedAt") 80 | Timestamp indexedAt; 81 | 82 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/VariantService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class VariantService extends AbstractService { 14 | public VariantService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public VariantsResponse getByIds(List variantIds) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)VariantsResponse.class; 20 | ApiOptions options = null; 21 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 22 | optionsBuilder.addOption("ids", variantIds.stream().map(String::valueOf).collect(Collectors.joining(","))); 23 | options = optionsBuilder.build(); 24 | 25 | return this.request("get", this.resolvePath("variants"), options, responseModel); 26 | } 27 | public VariantsResponse getByIds(List variantIds, ApiOptions options) throws ApiErrorException, ConnectionException { 28 | Class responseModel = (Class)(Class)VariantsResponse.class; 29 | ApiOptions combinedOptions = options; 30 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 31 | combinedOptions.getOptions().forEach(optionsBuilder::addOption); 32 | optionsBuilder.addOption("ids", variantIds.stream().map(String::valueOf).collect(Collectors.joining(","))); 33 | combinedOptions = optionsBuilder.build(); 34 | 35 | return this.request("get", this.resolvePath("variants"), combinedOptions, responseModel); 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/AbstractApiClient.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.exception.InvalidArgumentException; 4 | import com.scayle.storefrontapi.factory.ServiceFactory; 5 | import com.scayle.storefrontapi.http.HttpClient; 6 | import com.scayle.storefrontapi.model.ApiConfiguration; 7 | 8 | public abstract class AbstractApiClient { 9 | protected ApiConfiguration apiConfiguration; 10 | private ServiceFactory serviceFactory; 11 | 12 | public AbstractApiClient(ApiConfiguration apiConfiguration) { 13 | this.validateConfig(apiConfiguration); 14 | 15 | this.apiConfiguration = apiConfiguration; 16 | this.serviceFactory = new ServiceFactory(new HttpClient(apiConfiguration)); 17 | } 18 | 19 | protected T getService(String className) { 20 | return this.serviceFactory.getService(className); 21 | } 22 | 23 | /** 24 | * 25 | * @param apiConfiguration 26 | * @throws InvalidArgumentException 27 | */ 28 | private void validateConfig(ApiConfiguration apiConfiguration) throws InvalidArgumentException { 29 | String url = apiConfiguration.getUrl(); 30 | String accessToken = apiConfiguration.getAccessToken(); 31 | String username = apiConfiguration.getUsername(); 32 | String password = apiConfiguration.getPassword(); 33 | Integer shopId = apiConfiguration.getShopId(); 34 | 35 | if (url == null || url.isEmpty()) { 36 | throw new InvalidArgumentException("A valid API Url has to be set"); 37 | } 38 | 39 | if ((accessToken == null || accessToken.isEmpty()) && (username == null || username.isEmpty() || password == null || password.isEmpty())) { 40 | throw new InvalidArgumentException("A valid accessToken or username and password have to be set"); 41 | } 42 | 43 | if (shopId == null) { 44 | throw new InvalidArgumentException("A valid shopId has to be set"); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class ProductService extends AbstractService { 14 | public ProductService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public Product getById(Integer productId) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)Product.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("get", this.resolvePath("products/%s", productId), options, responseModel); 23 | } 24 | public Product getById(Integer productId, ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)Product.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("get", this.resolvePath("products/%s", productId), combinedOptions, responseModel); 29 | } 30 | public ProductsResponse query() throws ApiErrorException, ConnectionException { 31 | Class responseModel = (Class)(Class)ProductsResponse.class; 32 | ApiOptions options = null; 33 | 34 | return this.request("get", this.resolvePath("products"), options, responseModel); 35 | } 36 | public ProductsResponse query(ApiOptions options) throws ApiErrorException, ConnectionException { 37 | Class responseModel = (Class)(Class)ProductsResponse.class; 38 | ApiOptions combinedOptions = options; 39 | 40 | return this.request("get", this.resolvePath("products"), combinedOptions, responseModel); 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Variant.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | import java.time.OffsetDateTime; 12 | 13 | @Getter 14 | @Setter 15 | public class Variant implements ApiObjectInterface { 16 | /** 17 | * 18 | */ 19 | @SerializedName("id") 20 | Integer id; 21 | 22 | /** 23 | * 24 | */ 25 | @SerializedName("advancedAttributes") 26 | Map advancedAttributes; 27 | 28 | /** 29 | * 30 | */ 31 | @SerializedName("appliedPricePromotionKey") 32 | String appliedPricePromotionKey; 33 | 34 | /** 35 | * 36 | */ 37 | @SerializedName("attributes") 38 | Map attributes; 39 | 40 | /** 41 | * 42 | */ 43 | @SerializedName("lowestPriorPrice") 44 | LowestPriorPrice lowestPriorPrice; 45 | 46 | /** 47 | * 48 | */ 49 | @SerializedName("price") 50 | Price price; 51 | 52 | /** 53 | * 54 | */ 55 | @SerializedName("productId") 56 | Integer productId; 57 | 58 | /** 59 | * 60 | */ 61 | @SerializedName("referenceKey") 62 | String referenceKey; 63 | 64 | /** 65 | * 66 | */ 67 | @SerializedName("firstLiveAt") 68 | OffsetDateTime firstLiveAt; 69 | 70 | /** 71 | * 72 | */ 73 | @SerializedName("stock") 74 | Stock stock; 75 | 76 | /** 77 | * 78 | */ 79 | @SerializedName("customData") 80 | Map customData; 81 | 82 | /** 83 | * 84 | */ 85 | @SerializedName("merchant") 86 | Merchant merchant; 87 | 88 | /** 89 | * 90 | */ 91 | @SerializedName("createdAt") 92 | OffsetDateTime createdAt; 93 | 94 | /** 95 | * 96 | */ 97 | @SerializedName("updatedAt") 98 | OffsetDateTime updatedAt; 99 | 100 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/BrandService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class BrandService extends AbstractService { 14 | public BrandService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public BrandsResponse get() throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)BrandsResponse.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("get", this.resolvePath("brands"), options, responseModel); 23 | } 24 | public BrandsResponse get(ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)BrandsResponse.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("get", this.resolvePath("brands"), combinedOptions, responseModel); 29 | } 30 | public BrandsResponse getById(Integer brandId) throws ApiErrorException, ConnectionException { 31 | Class responseModel = (Class)(Class)BrandsResponse.class; 32 | ApiOptions options = null; 33 | 34 | return this.request("get", this.resolvePath("brands/%s", brandId), options, responseModel); 35 | } 36 | public BrandsResponse getById(Integer brandId, ApiOptions options) throws ApiErrorException, ConnectionException { 37 | Class responseModel = (Class)(Class)BrandsResponse.class; 38 | ApiOptions combinedOptions = options; 39 | 40 | return this.request("get", this.resolvePath("brands/%s", brandId), combinedOptions, responseModel); 41 | } 42 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![scayle-logo-cr](https://cdn-prod.scayle.com/public/media/general/SCAYLE-Commerce-Engine-header.png) 2 | 3 |

4 | SCAYLE Storefront API Java SDK 5 |

6 | 7 |

8 | Documentation | 9 | Website 10 |

11 | 12 |

13 | The SCAYLE Storefront API Java SDK streamlines interactions with Storefront REST APIs. 14 |

15 |

16 | SCAYLE's **Storefront API PHP SDK is released under the MIT license. 17 |

18 | 19 | ## Getting Started 20 | 21 | Visit the [Quickstart Guide](https://new.scayle.dev/en/dev/storefront-api/sdk-setup) to set up the Storefront API Java SDK 22 | 23 | Visit the [Docs](https://new.scayle.dev) to learn more about our system requirements. 24 | 25 | ## Installation 26 | ```java 27 | # Maven 28 | 29 | com.scayle.storefrontapi 30 | StorefrontClient 31 | 1.136.1 32 | 33 | 34 | #Gradle 35 | implementation 'com.scayle.storefrontapi:StorefrontClient:1.136.1' 36 | ``` 37 | ## What is Scayle ? 38 | 39 | [SCAYLE](https://scayle.com) is a full-featured e-commerce software solution that comes with flexible APIs. Within SCAYLE, you can manage all aspects of your shop, such as products, stocks, customers, and transactions. 40 | 41 | Learn more about Scayles’s architecture and commerce modules in the [Docs] (https://new.scayle.dev/en/user-guide). 42 | 43 | 44 | 45 | ## Community 46 | 47 | The community and core teams are available in [GitHub](https://github.com/scayle/), where you can ask for support, discuss roadmap, and share ideas. 48 | 49 | ## Other channels 50 | 51 | - [GitHub Issues](https://github.com/scayle/storefront-api-java-sdk/issues) 52 | - [LinkedIn](https://www.linkedin.com/company/scaylecommerce/) 53 | - [Jobs](https://careers.smartrecruiters.com/ABOUTYOUGmbH/scayle) 54 | - [AboutYou Tech Blog](https://aboutyou.tech/) 55 | 56 | ## License 57 | Licensed under the [MIT](https://opensource.org/license/mit/) 58 | -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/WishlistTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class WishlistTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testAddItem() throws Exception { 19 | String expectedRequestJson = this.loadFixture("/fixtures/WishlistAddItemRequest.json"); 20 | CreateWishlistBody requestEntity = this.jsonSerializer.unserializeApiObject(expectedRequestJson, CreateWishlistBody.class); 21 | 22 | assertThatJson(expectedRequestJson) 23 | .when(TREATING_NULL_AS_ABSENT) 24 | .isEqualTo(this.jsonSerializer.serializeApiObject(requestEntity)); 25 | 26 | Wishlist responseEntity = this.api.wishlists().addItem("1", requestEntity, null); 27 | 28 | String expectedResponseJson = this.loadFixture("/fixtures/WishlistAddItemResponse.json"); 29 | assertThatJson(expectedResponseJson) 30 | .when(TREATING_NULL_AS_ABSENT) 31 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 32 | 33 | 34 | } 35 | 36 | @Test 37 | public void testGet() throws Exception { 38 | 39 | Wishlist responseEntity = this.api.wishlists().get("1", null); 40 | 41 | String expectedResponseJson = this.loadFixture("/fixtures/WishlistGetResponse.json"); 42 | assertThatJson(expectedResponseJson) 43 | .when(TREATING_NULL_AS_ABSENT) 44 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 45 | 46 | 47 | } 48 | 49 | @Test 50 | public void testRemove() throws Exception { 51 | 52 | Wishlist responseEntity = this.api.wishlists().remove("1", "1", null); 53 | 54 | String expectedResponseJson = this.loadFixture("/fixtures/WishlistRemoveResponse.json"); 55 | assertThatJson(expectedResponseJson) 56 | .when(TREATING_NULL_AS_ABSENT) 57 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 58 | 59 | 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | workflow: 2 | rules: 3 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 4 | - if: $CI_PIPELINE_SOURCE == "pipeline" && $API_COMMIT_SHA 5 | - if: $CI_PIPELINE_SOURCE == "web" && $API_COMMIT_SHA 6 | 7 | default: 8 | image: docker:20 9 | services: 10 | - name: docker:dind 11 | command: ["--tls=false"] 12 | tags: 13 | - ay-shared-runner 14 | before_script: 15 | # Configure docker to also use our auth config for building the docker image 16 | # https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#option-3-use-docker_auth_config 17 | - mkdir -p $HOME/.docker 18 | - echo $DOCKER_AUTH_CONFIG > $HOME/.docker/config.json 19 | 20 | - apk add --no-cache curl git 21 | 22 | - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY 23 | - docker pull $CI_REGISTRY/aboutyou/scayle/core-engine/storefront-unit/storefront-api/sdks/generator:latest 24 | 25 | stages: 26 | - build 27 | 28 | Build SDK: 29 | stage: build 30 | rules: 31 | - if: $CI_PIPELINE_SOURCE == "pipeline" && $API_COMMIT_SHA 32 | - if: $CI_PIPELINE_SOURCE == "web" && $API_COMMIT_SHA 33 | script: 34 | - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/aboutyou/scayle/core-engine/storefront-unit/storefront-api/storefront-api.git .api 35 | - cd .api 36 | - git checkout $API_COMMIT_SHA 37 | - cd .. 38 | 39 | - echo "Initializing Git" 40 | - git config user.name $SDK_AUTOMATION_USER 41 | - git config user.email $SDK_AUTOMATION_EMAIL 42 | - git remote set-url origin https://$SDK_AUTOMATION_USER:$SDK_AUTOMATION_TOKEN@gitlab.com/${CI_PROJECT_PATH}.git 43 | 44 | - git checkout -b chore/update-sdk-$API_COMMIT_SHA 45 | 46 | - cp .api/http/docs/swagger.yaml swagger.yaml 47 | - docker run 48 | --rm 49 | -v "$(pwd)":/gen/out/java 50 | -v "$(pwd)/swagger.yaml":/gen/swagger.yaml 51 | $CI_REGISTRY/aboutyou/scayle/core-engine/storefront-unit/storefront-api/sdks/generator:latest 52 | php ./src/CodeGen.php generate java-storefront swagger.yaml 53 | 54 | - git add . 55 | - 'git commit -m "chore: Upgrade to $API_COMMIT_SHA"' 56 | - git push -o merge_request.create --set-upstream origin chore/update-sdk-$API_COMMIT_SHA 57 | 58 | MR Check: 59 | stage: build 60 | script: 61 | - echo "Success" 62 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/serializer/FilterAdapter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.serializer; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.Map; 5 | import java.util.List; 6 | import java.util.ArrayList; 7 | 8 | import com.google.gson.JsonDeserializationContext; 9 | import com.google.gson.JsonDeserializer; 10 | import com.google.gson.JsonElement; 11 | import com.google.gson.JsonObject; 12 | import com.google.gson.JsonArray; 13 | import com.google.gson.JsonParseException; 14 | import com.google.gson.JsonSerializationContext; 15 | import com.google.gson.JsonSerializer; 16 | import com.google.gson.Gson; 17 | import com.google.common.reflect.TypeToken; 18 | 19 | import com.scayle.storefrontapi.model.Filter; 20 | import com.scayle.storefrontapi.model.RangeFilterValue; 21 | import com.scayle.storefrontapi.model.BooleanFilterValue; 22 | import com.scayle.storefrontapi.model.AttributeFilterValue; 23 | import com.scayle.storefrontapi.model.IdentifierFilterValue; 24 | 25 | public class FilterAdapter implements JsonSerializer, JsonDeserializer { 26 | 27 | @Override 28 | public Filter deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 29 | Gson gson = new Gson(); 30 | JsonObject jsonObject = json.getAsJsonObject(); 31 | JsonElement values = jsonObject.get("values"); 32 | 33 | Filter filter = gson.fromJson(json, Filter.class); 34 | 35 | switch (filter.getType()) { 36 | case "range": 37 | filter.setRangeFilterValues(context.deserialize(values, new TypeToken>(){}.getType())); 38 | break; 39 | case "boolean": 40 | filter.setBooleanFilterValues(context.deserialize(values, new TypeToken>(){}.getType())); 41 | break; 42 | case "attributes": 43 | filter.setAttributeFilterValues(context.deserialize(values, new TypeToken>(){}.getType())); 44 | break; 45 | case "identifier": 46 | filter.setAttributeFilterValues(context.deserialize(values, new TypeToken>(){}.getType())); 47 | break; 48 | } 49 | 50 | return filter; 51 | } 52 | 53 | @Override 54 | public JsonElement serialize(Filter src, Type typeOfSrc, JsonSerializationContext context) { 55 | return context.serialize(src); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/serializer/MapNumberAdapter.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.serializer; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Set; 8 | 9 | import com.google.gson.JsonArray; 10 | import com.google.gson.JsonDeserializationContext; 11 | import com.google.gson.JsonDeserializer; 12 | import com.google.gson.JsonElement; 13 | import com.google.gson.JsonObject; 14 | import com.google.gson.JsonParseException; 15 | import com.google.gson.JsonPrimitive; 16 | import com.google.gson.internal.LinkedTreeMap; 17 | 18 | 19 | public class MapNumberAdapter implements JsonDeserializer>{ 20 | 21 | @Override @SuppressWarnings("unchecked") 22 | public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 23 | return (Map) read(json); 24 | } 25 | 26 | public Object read(JsonElement in) { 27 | 28 | if (in.isJsonArray()){ 29 | List list = new ArrayList(); 30 | JsonArray arr = in.getAsJsonArray(); 31 | 32 | for (JsonElement anArr : arr) { 33 | list.add(read(anArr)); 34 | } 35 | 36 | return list; 37 | } else if (in.isJsonObject()) { 38 | Map map = new LinkedTreeMap(); 39 | JsonObject obj = in.getAsJsonObject(); 40 | Set> entitySet = obj.entrySet(); 41 | 42 | for(Map.Entry entry: entitySet){ 43 | map.put(entry.getKey(), read(entry.getValue())); 44 | } 45 | 46 | return map; 47 | } else if( in.isJsonPrimitive()) { 48 | JsonPrimitive prim = in.getAsJsonPrimitive(); 49 | if (prim.isBoolean()) { 50 | return prim.getAsBoolean(); 51 | } else if (prim.isString()) { 52 | return prim.getAsString(); 53 | } else if (prim.isNumber()) { 54 | Number num = prim.getAsNumber(); 55 | // Only use doubles if the number is really a double 56 | if(Math.ceil(num.doubleValue()) == num.longValue()) 57 | return num.longValue(); 58 | else{ 59 | return num.doubleValue(); 60 | } 61 | } 62 | } 63 | return null; 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/http/HttpClient.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.http; 2 | 3 | import java.io.IOException; 4 | import java.util.Map; 5 | import java.util.Base64; 6 | 7 | import com.scayle.storefrontapi.model.ApiConfiguration; 8 | import okhttp3.HttpUrl; 9 | import okhttp3.MediaType; 10 | import okhttp3.OkHttpClient; 11 | import okhttp3.Request; 12 | import okhttp3.RequestBody; 13 | import okhttp3.Response; 14 | 15 | public class HttpClient { 16 | private OkHttpClient httpClient; 17 | private ApiConfiguration apiConfiguration; 18 | 19 | public HttpClient(ApiConfiguration apiConfiguration) { 20 | this.httpClient = new OkHttpClient(); 21 | this.apiConfiguration = apiConfiguration; 22 | } 23 | 24 | public Response request(String httpMethod, String relativeUrl, Map options, String body) throws IOException { 25 | httpMethod = httpMethod.toUpperCase(); 26 | 27 | HttpUrl.Builder urlBuilder = HttpUrl.parse(this.apiConfiguration.getUrl() + relativeUrl).newBuilder(); 28 | 29 | if (options != null) { 30 | for (String key : options.keySet()) { 31 | urlBuilder.addQueryParameter(key, String.valueOf(options.get(key))); 32 | } 33 | } 34 | 35 | RequestBody requestBody = null; 36 | if (body != null) { 37 | MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); 38 | requestBody = RequestBody.create(body, mediaType); 39 | } 40 | 41 | Request.Builder requestBuilder = new Request.Builder() 42 | .header("X-Shop-Id", this.apiConfiguration.getShopId().toString()) 43 | .header("Content-Type", "application/json") 44 | .header("X-SDK", "java/1.0.0") 45 | .url(urlBuilder.build().toString()) 46 | .method(httpMethod, requestBody); 47 | 48 | String accessToken = this.apiConfiguration.getAccessToken(); 49 | if (accessToken != null) { 50 | requestBuilder.header("X-Access-Token", accessToken); 51 | } else { 52 | String credentials = Base64.getEncoder().encodeToString( 53 | String.format( 54 | "%s:%s", this.apiConfiguration.getUsername(), this.apiConfiguration.getPassword() 55 | ).getBytes("UTF-8") 56 | ); 57 | requestBuilder.header("Authorization", String.format("Basic %s", credentials)); 58 | } 59 | 60 | return httpClient.newCall(requestBuilder.build()).execute(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/CategoryTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class CategoryTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGetRoots() throws Exception { 19 | 20 | ApiCollection responseEntity = this.api.categories().getRoots( null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/CategoryGetRootsResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | for (Category entity : responseEntity.getEntities()) { 29 | } 30 | } 31 | 32 | @Test 33 | public void testGetByIds() throws Exception { 34 | 35 | ApiCollection responseEntity = this.api.categories().getByIds("1", null); 36 | 37 | String expectedResponseJson = this.loadFixture("/fixtures/CategoryGetByIdsResponse.json"); 38 | assertThatJson(expectedResponseJson) 39 | .when(TREATING_NULL_AS_ABSENT) 40 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 41 | 42 | 43 | for (Category entity : responseEntity.getEntities()) { 44 | } 45 | } 46 | 47 | @Test 48 | public void testGetById() throws Exception { 49 | 50 | Category responseEntity = this.api.categories().getById(1, null); 51 | 52 | String expectedResponseJson = this.loadFixture("/fixtures/CategoryGetByIdResponse.json"); 53 | assertThatJson(expectedResponseJson) 54 | .when(TREATING_NULL_AS_ABSENT) 55 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 56 | 57 | 58 | } 59 | 60 | @Test 61 | public void testGetByPath() throws Exception { 62 | 63 | Category responseEntity = this.api.categories().getByPath("1", null); 64 | 65 | String expectedResponseJson = this.loadFixture("/fixtures/CategoryGetByPathResponse.json"); 66 | assertThatJson(expectedResponseJson) 67 | .when(TREATING_NULL_AS_ABSENT) 68 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 69 | 70 | 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/BasketItem.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class BasketItem implements ApiObjectInterface { 15 | /** 16 | * A unique key for the basket item which can be used for updating or deleting it. 17 | */ 18 | @SerializedName("key") 19 | String key; 20 | 21 | /** 22 | * The package in which the basket item will be send. 23 | 24 | Corresponds to a package id in the `packages` list of a `Basket`. 25 | 26 | */ 27 | @SerializedName("packageId") 28 | Integer packageId; 29 | 30 | /** 31 | * The quantity of the item. 32 | */ 33 | @SerializedName("quantity") 34 | Integer quantity; 35 | 36 | /** 37 | * The total available quantity for the variant which can be added to the basket. 38 | */ 39 | @SerializedName("availableQuantity") 40 | Integer availableQuantity; 41 | 42 | /** 43 | * The status of the basket item, either it is 'available' which means in stock 44 | or it's unavailable meaning it's out of stock. 45 | 46 | */ 47 | @SerializedName("status") 48 | String status; 49 | 50 | /** 51 | * 52 | */ 53 | @SerializedName("variant") 54 | Variant variant; 55 | 56 | /** 57 | * 58 | */ 59 | @SerializedName("product") 60 | Product product; 61 | 62 | /** 63 | * 64 | */ 65 | @SerializedName("price") 66 | BasketItemPrice price; 67 | 68 | /** 69 | * 70 | */ 71 | @SerializedName("lowestPriorPrice") 72 | LowestPriorPrice lowestPriorPrice; 73 | 74 | /** 75 | * The promotion which will be applied to the item. 76 | */ 77 | @SerializedName("promotionId") 78 | String promotionId; 79 | 80 | /** 81 | * 82 | */ 83 | @SerializedName("itemGroup") 84 | ItemGroup itemGroup; 85 | 86 | /** 87 | * 88 | */ 89 | @SerializedName("customData") 90 | BasketItemCustomData customData; 91 | 92 | /** 93 | * 94 | */ 95 | @SerializedName("displayData") 96 | BasketItemDisplayData displayData; 97 | 98 | /** 99 | * 100 | */ 101 | @SerializedName("deliveryForecast") 102 | DeliveryForecast deliveryForecast; 103 | 104 | /** 105 | * 106 | */ 107 | @SerializedName("promotion") 108 | BasketItemPromotion promotion; 109 | 110 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/WishlistService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class WishlistService extends AbstractService { 14 | public WishlistService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public Wishlist addItem(String wishlistId, CreateWishlistBody model) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)Wishlist.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("post", this.resolvePath("wishlists/%s/items", wishlistId), options, responseModel, model); 23 | } 24 | public Wishlist addItem(String wishlistId, CreateWishlistBody model, ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)Wishlist.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("post", this.resolvePath("wishlists/%s/items", wishlistId), combinedOptions, responseModel, model); 29 | } 30 | public Wishlist get(String wishlistId) throws ApiErrorException, ConnectionException { 31 | Class responseModel = (Class)(Class)Wishlist.class; 32 | ApiOptions options = null; 33 | 34 | return this.request("get", this.resolvePath("wishlists/%s", wishlistId), options, responseModel); 35 | } 36 | public Wishlist get(String wishlistId, ApiOptions options) throws ApiErrorException, ConnectionException { 37 | Class responseModel = (Class)(Class)Wishlist.class; 38 | ApiOptions combinedOptions = options; 39 | 40 | return this.request("get", this.resolvePath("wishlists/%s", wishlistId), combinedOptions, responseModel); 41 | } 42 | public Wishlist remove(String wishlistId, String itemKey) throws ApiErrorException, ConnectionException { 43 | Class responseModel = (Class)(Class)Wishlist.class; 44 | ApiOptions options = null; 45 | 46 | return this.request("delete", this.resolvePath("wishlists/%s/items/%s", wishlistId, itemKey), options, responseModel); 47 | } 48 | public Wishlist remove(String wishlistId, String itemKey, ApiOptions options) throws ApiErrorException, ConnectionException { 49 | Class responseModel = (Class)(Class)Wishlist.class; 50 | ApiOptions combinedOptions = options; 51 | 52 | return this.request("delete", this.resolvePath("wishlists/%s/items/%s", wishlistId, itemKey), combinedOptions, responseModel); 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Category.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | 12 | @Getter 13 | @Setter 14 | public class Category implements ApiObjectInterface { 15 | /** 16 | * The unique identifier of the category. 17 | */ 18 | @SerializedName("id") 19 | Integer id; 20 | 21 | /** 22 | * The slugs for all `rootlineIds` combined with `/` (e.g., `/women/fashion`). 23 | */ 24 | @SerializedName("path") 25 | String path; 26 | 27 | /** 28 | * The name of the category 29 | */ 30 | @SerializedName("name") 31 | String name; 32 | 33 | /** 34 | * A short string to describe the current category (usable, for example, in URLs as). 35 | */ 36 | @SerializedName("slug") 37 | String slug; 38 | 39 | /** 40 | * The parent category ID (root-level categories have a parent ID of `0`) 41 | */ 42 | @SerializedName("parentId") 43 | Integer parentId; 44 | 45 | /** 46 | * The IDs for the path from the topmost root category to the current category, which is included as the last item. 47 | */ 48 | @SerializedName("rootlineIds") 49 | List rootlineIds; 50 | 51 | /** 52 | * The child category IDs attached to the current category 53 | */ 54 | @SerializedName("childrenIds") 55 | List childrenIds; 56 | 57 | /** 58 | * Properties attached to this category. 59 | */ 60 | @SerializedName("properties") 61 | List properties; 62 | 63 | /** 64 | * A flag that defines if a category should be displayed by the frontend 65 | */ 66 | @SerializedName("isHidden") 67 | Boolean isHidden; 68 | 69 | /** 70 | * The nesting level of the category (root-level depth = 1, child nodes = 2, child nodes' children = 3, etc.) 71 | */ 72 | @SerializedName("depth") 73 | Integer depth; 74 | 75 | /** 76 | * A list of filters that can be used for filtering products in the category 77 | */ 78 | @SerializedName("supportedFilter") 79 | List supportedFilter; 80 | 81 | /** 82 | * 83 | */ 84 | @SerializedName("parent") 85 | Object parent; 86 | 87 | /** 88 | * Additional category data defined on the shop level 89 | */ 90 | @SerializedName("shopLevelCustomData") 91 | Object shopLevelCustomData; 92 | 93 | /** 94 | * Additional category data defined on the country level 95 | */ 96 | @SerializedName("countryLevelCustomData") 97 | Object countryLevelCustomData; 98 | 99 | /** 100 | * An array of child category objects. 101 | Returned if requested as `tree format` or using `with`. 102 | 103 | */ 104 | @SerializedName("children") 105 | List children; 106 | 107 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/BasketTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.*; 4 | 5 | import org.junit.Test; 6 | 7 | import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; 8 | import static net.javacrumbs.jsonunit.core.Option.TREATING_NULL_AS_ABSENT; 9 | 10 | import java.util.Map; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unchecked") 15 | public class BasketTest extends BaseApiTest { 16 | 17 | @Test 18 | public void testGet() throws Exception { 19 | 20 | Basket responseEntity = this.api.baskets().get("1", null); 21 | 22 | String expectedResponseJson = this.loadFixture("/fixtures/BasketGetResponse.json"); 23 | assertThatJson(expectedResponseJson) 24 | .when(TREATING_NULL_AS_ABSENT) 25 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 26 | 27 | 28 | } 29 | 30 | @Test 31 | public void testAddItem() throws Exception { 32 | String expectedRequestJson = this.loadFixture("/fixtures/BasketAddItemRequest.json"); 33 | CreateBasketItemBody requestEntity = this.jsonSerializer.unserializeApiObject(expectedRequestJson, CreateBasketItemBody.class); 34 | 35 | assertThatJson(expectedRequestJson) 36 | .when(TREATING_NULL_AS_ABSENT) 37 | .isEqualTo(this.jsonSerializer.serializeApiObject(requestEntity)); 38 | 39 | Basket responseEntity = this.api.baskets().addItem("1", requestEntity, null); 40 | 41 | String expectedResponseJson = this.loadFixture("/fixtures/BasketAddItemResponse.json"); 42 | assertThatJson(expectedResponseJson) 43 | .when(TREATING_NULL_AS_ABSENT) 44 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 45 | 46 | 47 | } 48 | 49 | @Test 50 | public void testRemove() throws Exception { 51 | 52 | Basket responseEntity = this.api.baskets().remove("1", "1", null); 53 | 54 | String expectedResponseJson = this.loadFixture("/fixtures/BasketRemoveResponse.json"); 55 | assertThatJson(expectedResponseJson) 56 | .when(TREATING_NULL_AS_ABSENT) 57 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 58 | 59 | 60 | } 61 | 62 | @Test 63 | public void testUpdate() throws Exception { 64 | String expectedRequestJson = this.loadFixture("/fixtures/BasketUpdateRequest.json"); 65 | UpdateBasketItemBody requestEntity = this.jsonSerializer.unserializeApiObject(expectedRequestJson, UpdateBasketItemBody.class); 66 | 67 | assertThatJson(expectedRequestJson) 68 | .when(TREATING_NULL_AS_ABSENT) 69 | .isEqualTo(this.jsonSerializer.serializeApiObject(requestEntity)); 70 | 71 | Basket responseEntity = this.api.baskets().update("1", "1", requestEntity, null); 72 | 73 | String expectedResponseJson = this.loadFixture("/fixtures/BasketUpdateResponse.json"); 74 | assertThatJson(expectedResponseJson) 75 | .when(TREATING_NULL_AS_ABSENT) 76 | .isEqualTo(this.jsonSerializer.serializeApiObject(responseEntity)); 77 | 78 | 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | import java.time.OffsetDateTime; 12 | 13 | @Getter 14 | @Setter 15 | public class Product implements ApiObjectInterface { 16 | /** 17 | * 18 | */ 19 | @SerializedName("id") 20 | Integer id; 21 | 22 | /** 23 | * 24 | */ 25 | @SerializedName("advancedAttributes") 26 | Map advancedAttributes; 27 | 28 | /** 29 | * 30 | */ 31 | @SerializedName("attributes") 32 | Map attributes; 33 | 34 | /** 35 | * 36 | */ 37 | @SerializedName("baseCategories") 38 | List baseCategories; 39 | 40 | /** 41 | * 42 | */ 43 | @SerializedName("categories") 44 | List> categories; 45 | 46 | /** 47 | * 48 | */ 49 | @SerializedName("definingAttributes") 50 | DefiningAttribute definingAttributes; 51 | 52 | /** 53 | * 54 | */ 55 | @SerializedName("images") 56 | List images; 57 | 58 | /** 59 | * 60 | */ 61 | @SerializedName("customData") 62 | ResponseCustomData customData; 63 | 64 | /** 65 | * Identifies whether a product is active or not 66 | */ 67 | @SerializedName("isActive") 68 | Boolean isActive; 69 | 70 | /** 71 | * Identifies whether a product is new or not 72 | */ 73 | @SerializedName("isNew") 74 | Boolean isNew; 75 | 76 | /** 77 | * Identifies if a product is still available to sell 78 | */ 79 | @SerializedName("isSoldOut") 80 | Boolean isSoldOut; 81 | 82 | /** 83 | * Identifies the master product which this product belongs 84 | */ 85 | @SerializedName("masterKey") 86 | String masterKey; 87 | 88 | /** 89 | * 90 | */ 91 | @SerializedName("firstLiveAt") 92 | Timestamp firstLiveAt; 93 | 94 | /** 95 | * 96 | */ 97 | @SerializedName("priceRange") 98 | PriceRange priceRange; 99 | 100 | /** 101 | * 102 | */ 103 | @SerializedName("reductionRange") 104 | ReductionRange reductionRange; 105 | 106 | /** 107 | * 108 | */ 109 | @SerializedName("lowestPriorPrice") 110 | LowestPriorPrice lowestPriorPrice; 111 | 112 | /** 113 | * 114 | */ 115 | @SerializedName("referenceKey") 116 | String referenceKey; 117 | 118 | /** 119 | * 120 | */ 121 | @SerializedName("searchCategoryIds") 122 | List searchCategoryIds; 123 | 124 | /** 125 | * list of Products 126 | */ 127 | @SerializedName("siblings") 128 | List siblings; 129 | 130 | /** 131 | * 132 | */ 133 | @SerializedName("variants") 134 | List variants; 135 | 136 | /** 137 | * 138 | */ 139 | @SerializedName("createdAt") 140 | OffsetDateTime createdAt; 141 | 142 | /** 143 | * 144 | */ 145 | @SerializedName("updatedAt") 146 | OffsetDateTime updatedAt; 147 | 148 | /** 149 | * 150 | */ 151 | @SerializedName("indexedAt") 152 | Timestamp indexedAt; 153 | 154 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/BasketService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class BasketService extends AbstractService { 14 | public BasketService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public Basket get(String basketId) throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)Basket.class; 20 | ApiOptions options = null; 21 | 22 | return this.request("get", this.resolvePath("baskets/%s", basketId), options, responseModel); 23 | } 24 | public Basket get(String basketId, ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)Basket.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.request("get", this.resolvePath("baskets/%s", basketId), combinedOptions, responseModel); 29 | } 30 | public Basket addItem(String basketId, CreateBasketItemBody model) throws ApiErrorException, ConnectionException { 31 | Class responseModel = (Class)(Class)Basket.class; 32 | ApiOptions options = null; 33 | 34 | return this.request("post", this.resolvePath("baskets/%s/items", basketId), options, responseModel, model); 35 | } 36 | public Basket addItem(String basketId, CreateBasketItemBody model, ApiOptions options) throws ApiErrorException, ConnectionException { 37 | Class responseModel = (Class)(Class)Basket.class; 38 | ApiOptions combinedOptions = options; 39 | 40 | return this.request("post", this.resolvePath("baskets/%s/items", basketId), combinedOptions, responseModel, model); 41 | } 42 | public Basket remove(String basketId, String itemKey) throws ApiErrorException, ConnectionException { 43 | Class responseModel = (Class)(Class)Basket.class; 44 | ApiOptions options = null; 45 | 46 | return this.request("delete", this.resolvePath("baskets/%s/items/%s", basketId, itemKey), options, responseModel); 47 | } 48 | public Basket remove(String basketId, String itemKey, ApiOptions options) throws ApiErrorException, ConnectionException { 49 | Class responseModel = (Class)(Class)Basket.class; 50 | ApiOptions combinedOptions = options; 51 | 52 | return this.request("delete", this.resolvePath("baskets/%s/items/%s", basketId, itemKey), combinedOptions, responseModel); 53 | } 54 | public Basket update(String basketId, String itemKey, UpdateBasketItemBody model) throws ApiErrorException, ConnectionException { 55 | Class responseModel = (Class)(Class)Basket.class; 56 | ApiOptions options = null; 57 | 58 | return this.request("patch", this.resolvePath("baskets/%s/items/%s", basketId, itemKey), options, responseModel, model); 59 | } 60 | public Basket update(String basketId, String itemKey, UpdateBasketItemBody model, ApiOptions options) throws ApiErrorException, ConnectionException { 61 | Class responseModel = (Class)(Class)Basket.class; 62 | ApiOptions combinedOptions = options; 63 | 64 | return this.request("patch", this.resolvePath("baskets/%s/items/%s", basketId, itemKey), combinedOptions, responseModel, model); 65 | } 66 | } -------------------------------------------------------------------------------- /src/test/java/com/scayle/storefrontapi/BaseApiTest.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.lang.reflect.Field; 9 | import java.util.Map; 10 | 11 | import com.scayle.storefrontapi.model.ApiConfiguration; 12 | import com.scayle.storefrontapi.model.ApiObjectInterface; 13 | import com.scayle.storefrontapi.serializer.JsonSerializer; 14 | 15 | public class BaseApiTest { 16 | protected StorefrontClient api; 17 | protected JsonSerializer jsonSerializer; 18 | 19 | public BaseApiTest() { 20 | System.setProperty("json-unit.libraries", "moshi"); 21 | 22 | ApiConfiguration apiConfiguration = ApiConfiguration.builder() 23 | .url("http://127.0.0.1:4010") 24 | .accessToken("abc123") 25 | .build(); 26 | 27 | this.api = new StorefrontClient(apiConfiguration); 28 | this.jsonSerializer = new JsonSerializer(); 29 | } 30 | 31 | protected String loadFixture(String path) throws IOException { 32 | return this.getResourceAsString(path); 33 | } 34 | 35 | protected void assertPropertyHasCorrectPolymorphicType( 36 | ApiObjectInterface apiObject, 37 | String propertyName, 38 | String discriminator, 39 | Map> mapping 40 | ) throws Exception { 41 | Object propertyValue = this.getProperty(apiObject, propertyName); 42 | 43 | if (propertyValue == null) { 44 | return; 45 | } 46 | 47 | if (propertyValue instanceof Iterable) { 48 | for (Object propertyItem : (Iterable) propertyValue) { 49 | this.assertPropertyHasCorrectPolymorphicTypeInternal(propertyItem, propertyName, discriminator, mapping); 50 | } 51 | } else { 52 | this.assertPropertyHasCorrectPolymorphicTypeInternal(propertyValue, propertyName, discriminator, mapping); 53 | } 54 | } 55 | 56 | private void assertPropertyHasCorrectPolymorphicTypeInternal( 57 | Object obj, 58 | String propertyName, 59 | String discriminator, 60 | Map> mapping 61 | ) throws Exception { 62 | Class actualClass = obj.getClass(); 63 | String discriminatorValue = ""; 64 | Class expectedClass = null; 65 | 66 | try { 67 | discriminatorValue = (String) this.getProperty(obj, discriminator); 68 | } catch (Exception ex) { 69 | throw new AssertionError(String.format("Mising discriminator '%s' on %s", discriminator, actualClass.toString())); 70 | } 71 | 72 | if (mapping.containsKey(discriminatorValue)) { 73 | expectedClass = mapping.get(discriminatorValue); 74 | } else { 75 | throw new AssertionError(String.format("Mising polymorphic mapping for '%s'", discriminatorValue)); 76 | } 77 | 78 | assertEquals(expectedClass, actualClass); 79 | } 80 | 81 | private Object getProperty(Object obj, String propertyName) throws Exception { 82 | Class actualClass = obj.getClass(); 83 | Field field = actualClass.getDeclaredField(propertyName); 84 | field.setAccessible(true); 85 | return field.get(obj); 86 | } 87 | 88 | private String getResourceAsString(String path) throws IOException { 89 | InputStream resource = getClass().getResourceAsStream(path); 90 | 91 | ByteArrayOutputStream os = new ByteArrayOutputStream(1024); 92 | byte[] buf = new byte[1024]; 93 | 94 | for (int i = resource.read(buf); i > 0; i = resource.read(buf)) { 95 | os.write(buf, 0, i); 96 | } 97 | 98 | return os.toString("utf8"); 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/CategoryService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import com.scayle.storefrontapi.exception.ApiErrorException; 8 | import com.scayle.storefrontapi.exception.ConnectionException; 9 | import com.scayle.storefrontapi.http.HttpClient; 10 | import com.scayle.storefrontapi.model.*; 11 | 12 | @SuppressWarnings("unchecked") 13 | public class CategoryService extends AbstractService { 14 | public CategoryService(HttpClient httpClient) { 15 | super(httpClient); 16 | } 17 | 18 | public List getRoots() throws ApiErrorException, ConnectionException { 19 | Class responseModel = (Class)(Class)Category.class; 20 | ApiOptions options = null; 21 | 22 | return this.requestCollection("get", this.resolvePath("categories"), options, responseModel); 23 | } 24 | public List getRoots(ApiOptions options) throws ApiErrorException, ConnectionException { 25 | Class responseModel = (Class)(Class)Category.class; 26 | ApiOptions combinedOptions = options; 27 | 28 | return this.requestCollection("get", this.resolvePath("categories"), combinedOptions, responseModel); 29 | } 30 | public List getByIds(List categoryIds) throws ApiErrorException, ConnectionException { 31 | Class responseModel = (Class)(Class)Category.class; 32 | ApiOptions options = null; 33 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 34 | optionsBuilder.addOption("ids", categoryIds.stream().map(String::valueOf).collect(Collectors.joining(","))); 35 | options = optionsBuilder.build(); 36 | 37 | return this.requestCollection("get", this.resolvePath("categories"), options, responseModel); 38 | } 39 | public List getByIds(List categoryIds, ApiOptions options) throws ApiErrorException, ConnectionException { 40 | Class responseModel = (Class)(Class)Category.class; 41 | ApiOptions combinedOptions = options; 42 | ApiOptions.ApiOptionsBuilder optionsBuilder = ApiOptions.builder(); 43 | combinedOptions.getOptions().forEach(optionsBuilder::addOption); 44 | optionsBuilder.addOption("ids", categoryIds.stream().map(String::valueOf).collect(Collectors.joining(","))); 45 | combinedOptions = optionsBuilder.build(); 46 | 47 | return this.requestCollection("get", this.resolvePath("categories"), combinedOptions, responseModel); 48 | } 49 | public Category getById(Integer categoryId) throws ApiErrorException, ConnectionException { 50 | Class responseModel = (Class)(Class)Category.class; 51 | ApiOptions options = null; 52 | 53 | return this.request("get", this.resolvePath("categories/%s", categoryId), options, responseModel); 54 | } 55 | public Category getById(Integer categoryId, ApiOptions options) throws ApiErrorException, ConnectionException { 56 | Class responseModel = (Class)(Class)Category.class; 57 | ApiOptions combinedOptions = options; 58 | 59 | return this.request("get", this.resolvePath("categories/%s", categoryId), combinedOptions, responseModel); 60 | } 61 | public Category getByPath(String categoryPath) throws ApiErrorException, ConnectionException { 62 | Class responseModel = (Class)(Class)Category.class; 63 | ApiOptions options = null; 64 | 65 | return this.request("get", this.resolvePath("categories/%s", categoryPath), options, responseModel); 66 | } 67 | public Category getByPath(String categoryPath, ApiOptions options) throws ApiErrorException, ConnectionException { 68 | Class responseModel = (Class)(Class)Category.class; 69 | ApiOptions combinedOptions = options; 70 | 71 | return this.request("get", this.resolvePath("categories/%s", categoryPath), combinedOptions, responseModel); 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/StorefrontClient.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi; 2 | 3 | import com.scayle.storefrontapi.model.ApiConfiguration; 4 | import com.scayle.storefrontapi.service.BasketService; 5 | import com.scayle.storefrontapi.service.AttributeService; 6 | import com.scayle.storefrontapi.service.BrandService; 7 | import com.scayle.storefrontapi.service.CategoryService; 8 | import com.scayle.storefrontapi.service.FilterService; 9 | import com.scayle.storefrontapi.service.TypeaheadService; 10 | import com.scayle.storefrontapi.service.CampaignService; 11 | import com.scayle.storefrontapi.service.NavigationService; 12 | import com.scayle.storefrontapi.service.ProductService; 13 | import com.scayle.storefrontapi.service.ShopConfigurationService; 14 | import com.scayle.storefrontapi.service.VariantService; 15 | import com.scayle.storefrontapi.service.WishlistService; 16 | import com.scayle.storefrontapi.service.RedirectService; 17 | import com.scayle.storefrontapi.service.MatchRedirectService; 18 | import com.scayle.storefrontapi.service.PromotionService; 19 | 20 | public final class StorefrontClient extends AbstractApiClient { 21 | 22 | public StorefrontClient(ApiConfiguration apiConfiguration) { 23 | super(apiConfiguration); 24 | } 25 | 26 | public BasketService baskets() { 27 | BasketService service = this.getService("com.scayle.storefrontapi.service.BasketService"); 28 | return service; 29 | } 30 | 31 | public AttributeService attributes() { 32 | AttributeService service = this.getService("com.scayle.storefrontapi.service.AttributeService"); 33 | return service; 34 | } 35 | 36 | public BrandService brands() { 37 | BrandService service = this.getService("com.scayle.storefrontapi.service.BrandService"); 38 | return service; 39 | } 40 | 41 | public CategoryService categories() { 42 | CategoryService service = this.getService("com.scayle.storefrontapi.service.CategoryService"); 43 | return service; 44 | } 45 | 46 | public FilterService filters() { 47 | FilterService service = this.getService("com.scayle.storefrontapi.service.FilterService"); 48 | return service; 49 | } 50 | 51 | public TypeaheadService typeahead() { 52 | TypeaheadService service = this.getService("com.scayle.storefrontapi.service.TypeaheadService"); 53 | return service; 54 | } 55 | 56 | public CampaignService campaign() { 57 | CampaignService service = this.getService("com.scayle.storefrontapi.service.CampaignService"); 58 | return service; 59 | } 60 | 61 | public NavigationService navigation() { 62 | NavigationService service = this.getService("com.scayle.storefrontapi.service.NavigationService"); 63 | return service; 64 | } 65 | 66 | public ProductService products() { 67 | ProductService service = this.getService("com.scayle.storefrontapi.service.ProductService"); 68 | return service; 69 | } 70 | 71 | public ShopConfigurationService shopConfigurations() { 72 | ShopConfigurationService service = this.getService("com.scayle.storefrontapi.service.ShopConfigurationService"); 73 | return service; 74 | } 75 | 76 | public VariantService variants() { 77 | VariantService service = this.getService("com.scayle.storefrontapi.service.VariantService"); 78 | return service; 79 | } 80 | 81 | public WishlistService wishlists() { 82 | WishlistService service = this.getService("com.scayle.storefrontapi.service.WishlistService"); 83 | return service; 84 | } 85 | 86 | public RedirectService redirects() { 87 | RedirectService service = this.getService("com.scayle.storefrontapi.service.RedirectService"); 88 | return service; 89 | } 90 | 91 | public MatchRedirectService matchRedirects() { 92 | MatchRedirectService service = this.getService("com.scayle.storefrontapi.service.MatchRedirectService"); 93 | return service; 94 | } 95 | 96 | public PromotionService promotions() { 97 | PromotionService service = this.getService("com.scayle.storefrontapi.service.PromotionService"); 98 | return service; 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/serializer/JsonSerializer.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.serializer; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.Map; 5 | import java.util.List; 6 | import java.lang.reflect.ParameterizedType; 7 | import java.time.OffsetDateTime; 8 | 9 | import com.scayle.storefrontapi.model.ApiCollection; 10 | import com.scayle.storefrontapi.model.AttributeValue; 11 | import com.scayle.storefrontapi.model.Filter; 12 | import com.scayle.storefrontapi.polymorphism.Polymorphic; 13 | import com.scayle.storefrontapi.polymorphism.PolymorphicAdapter; 14 | import com.scayle.storefrontapi.polymorphism.PolymorphicInterface; 15 | import com.scayle.storefrontapi.polymorphism.PolymorphicMapping; 16 | import com.scayle.storefrontapi.serializer.AttributeValuesAdapter; 17 | import com.scayle.storefrontapi.serializer.FilterAdapter; 18 | import com.scayle.storefrontapi.serializer.TimestampAdapter; 19 | import com.google.common.reflect.TypeToken; 20 | import com.google.gson.Gson; 21 | import com.google.gson.GsonBuilder; 22 | import com.google.gson.internal.LinkedTreeMap; 23 | 24 | public class JsonSerializer { 25 | 26 | private Polymorphic polymorphic; 27 | 28 | public JsonSerializer() { 29 | this.polymorphic = new Polymorphic(); 30 | } 31 | 32 | public T unserializeApiObject(String json, Class modelClass) { 33 | Gson gson = this.createGson(modelClass); 34 | 35 | return (T)(gson.fromJson(json, modelClass)); 36 | } 37 | 38 | public ApiCollection unserializeApiCollection(String json, Class modelClass) { 39 | Gson gson = this.createGson(modelClass); 40 | 41 | return (ApiCollection)(gson.fromJson(json, getType(ApiCollection.class, modelClass))); 42 | } 43 | 44 | public T unserialize(String json, Class clazz) { 45 | Gson gson = new Gson(); 46 | 47 | return (T)(gson.fromJson(json, clazz)); 48 | } 49 | 50 | public List unserializeList(String json, Class clazz) { 51 | Gson gson = this.createGson(clazz); 52 | Type listType = new TypeToken>(){}.getType(); 53 | 54 | return (List)(gson.fromJson(json, getType(List.class, clazz))); 55 | } 56 | 57 | public String serializeApiObject(Object apiObject) { 58 | Gson gson = new Gson(); 59 | 60 | return gson.toJson(apiObject); 61 | } 62 | 63 | private Gson createGson(Class modelClass) { 64 | GsonBuilder gsonBuilder = new GsonBuilder(); 65 | // Dont cast int/long to doubles 66 | gsonBuilder.registerTypeAdapter(new TypeToken>(){}.getType(), new MapNumberAdapter()); 67 | // Parse Timestamp objects from string to OffsetDateTime class 68 | gsonBuilder.registerTypeAdapter(OffsetDateTime.class, new TimestampAdapter()); 69 | //Parse polymorphic array/object AttributeValues to array 70 | gsonBuilder.registerTypeAdapter(new TypeToken>(){}.getType(), new AttributeValuesAdapter()); 71 | 72 | //Parse polymorphic FilterValues to separate fields 73 | gsonBuilder.registerTypeAdapter(Filter.class, new FilterAdapter()); 74 | 75 | if (this.polymorphic.hasClassMapping(modelClass)) { 76 | for (Class interfaceClass : this.polymorphic.getMappingForClass(modelClass).keySet()) { 77 | PolymorphicMapping mapping = this.polymorphic.getMappingForClass(modelClass).get(interfaceClass); 78 | gsonBuilder.registerTypeAdapter(interfaceClass, new PolymorphicAdapter(mapping.getDiscriminator(), mapping.getMapping())); 79 | } 80 | } 81 | 82 | return gsonBuilder.create(); 83 | } 84 | 85 | private Type getType(final Class rawClass, final Class parameterClass) { 86 | return new ParameterizedType() { 87 | @Override 88 | public Type[] getActualTypeArguments() { 89 | return new Type[]{parameterClass}; 90 | } 91 | 92 | @Override 93 | public Type getRawType() { 94 | return rawClass; 95 | } 96 | 97 | @Override 98 | public Type getOwnerType() { 99 | return null; 100 | } 101 | 102 | }; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/scayle/storefrontapi/service/AbstractService.java: -------------------------------------------------------------------------------- 1 | package com.scayle.storefrontapi.service; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | 6 | import com.google.gson.JsonElement; 7 | 8 | import com.scayle.storefrontapi.serializer.JsonSerializer; 9 | import com.scayle.storefrontapi.exception.ApiErrorException; 10 | import com.scayle.storefrontapi.exception.ConnectionException; 11 | import com.scayle.storefrontapi.http.HttpClient; 12 | import com.scayle.storefrontapi.model.ApiCollection; 13 | import com.scayle.storefrontapi.model.ApiOptions; 14 | 15 | import okhttp3.Response; 16 | 17 | public abstract class AbstractService { 18 | 19 | private HttpClient httpClient; 20 | private JsonSerializer jsonSerializer; 21 | 22 | public AbstractService(HttpClient httpClient) { 23 | this.httpClient = httpClient; 24 | this.jsonSerializer = new JsonSerializer(); 25 | } 26 | 27 | protected T request(String httpMethod, String relativeUrl, ApiOptions options, Class modelClass) throws ApiErrorException, ConnectionException { 28 | return this.request(httpMethod, relativeUrl, options, modelClass, null); 29 | } 30 | 31 | protected T request(String httpMethod, String relativeUrl, ApiOptions options, Class modelClass, Object body) throws ApiErrorException, ConnectionException { 32 | try { 33 | Response response = this.executeRequest(httpMethod, relativeUrl, options, body); 34 | String responseBodyContent = response.body().string(); 35 | Integer statusCode = response.code(); 36 | 37 | if (statusCode >= 200 && statusCode < 300) { 38 | if(responseBodyContent == null || responseBodyContent.isEmpty()) { 39 | return null; 40 | } 41 | 42 | return this.jsonSerializer.unserializeApiObject(responseBodyContent, modelClass); 43 | } else { 44 | JsonElement errorResponse = this.jsonSerializer.unserialize(responseBodyContent, JsonElement.class); 45 | 46 | throw new ApiErrorException(errorResponse.getAsJsonObject(), statusCode); 47 | } 48 | } catch (ApiErrorException apiException) { 49 | throw apiException; 50 | } catch (Exception exception) { 51 | throw new ConnectionException(exception.getMessage(), exception); 52 | } 53 | } 54 | 55 | protected List requestCollection(String httpMethod, String relativeUrl, ApiOptions options, Class modelClass) throws ApiErrorException, ConnectionException { 56 | return this.requestCollection(httpMethod, relativeUrl, options, modelClass, null); 57 | } 58 | 59 | protected List requestCollection(String httpMethod, String relativeUrl, ApiOptions options, Class modelClass, Object body) throws ApiErrorException, ConnectionException { 60 | try { 61 | Response response = this.executeRequest(httpMethod, relativeUrl, options, body); 62 | String responseBodyContent = response.body().string(); 63 | Integer statusCode = response.code(); 64 | 65 | if (statusCode >= 200 && statusCode < 300) { 66 | if(responseBodyContent == null || responseBodyContent.isEmpty()) { 67 | return null; 68 | } 69 | 70 | return this.jsonSerializer.unserializeList(responseBodyContent, modelClass); 71 | } else { 72 | JsonElement errorResponse = this.jsonSerializer.unserialize(responseBodyContent, JsonElement.class); 73 | 74 | throw new ApiErrorException(errorResponse.getAsJsonObject(), statusCode); 75 | } 76 | } catch (ApiErrorException apiException) { 77 | throw apiException; 78 | } catch (Exception exception) { 79 | throw new ConnectionException(exception.getMessage(), exception); 80 | } 81 | } 82 | 83 | protected String resolvePath(String path, Object... params) { 84 | return String.format(path, params); 85 | } 86 | 87 | private Response executeRequest(String httpMethod, String relativeUrl, ApiOptions options, Object body) throws Exception { 88 | String jsonRequestBody = null; 89 | Map requestOptions = null; 90 | 91 | if (options != null) { 92 | requestOptions = options.getOptions(); 93 | } 94 | 95 | if (body != null) { 96 | jsonRequestBody = this.jsonSerializer.serializeApiObject(body); 97 | } 98 | 99 | return this.httpClient.request(httpMethod, relativeUrl, requestOptions, jsonRequestBody); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | --------------------------------------------------------------------------------