From a24fac5fc5d16e3fc6bec7ae4d854404167e02c1 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 16 Jul 2023 15:58:01 +0300 Subject: [PATCH] Update code formatting for consistency This commit includes changes in various files to maintain the consistency in code. Extraneous line breaks have been removed in some files and needed line breaks have been added in others for readability. The sequence of the import statements have been altered in some files for it to be in proper alphabetical order. In files like 'PopulationStatServiceImpl.java', 'GoldPriceStatServiceImpl.java' and more, indentation has been adjusted to maintain consistency across code base. The rearrangement does not change any functionality, it is purely for readability and code maintainability. --- .../goldprice/GoldPriceController.java | 2 +- .../economatic/goldprice/GoldPriceMapper.java | 2 +- .../goldprice/GoldPriceService.java | 2 +- .../goldprice/GoldPriceServiceImpl.java | 117 +++++++++--------- .../goldprice/GoldPriceUpdateService.java | 2 +- .../economatic/item/ItemServiceImpl.java | 50 ++++---- .../itemprice/ItemPriceController.java | 2 +- .../economatic/itemprice/ItemPriceMapper.java | 2 +- .../itemprice/ItemPriceService.java | 2 +- .../itemprice/ItemPriceServiceImpl.java | 95 +++++++------- .../itemprice/ItemPriceUpdateService.java | 16 +-- .../economatic/itemprice/NexusHubService.java | 23 ++-- .../population/PopulationController.java | 2 +- .../population/PopulationMapper.java | 2 +- .../population/PopulationService.java | 2 +- .../population/PopulationServiceImpl.java | 76 ++++++------ .../population/PopulationUpdateService.java | 3 - .../BasicRecommendationService.java | 1 - .../GoldPriceScoreProvider.java | 4 +- .../ItemPriceScoreProvider.java | 2 +- .../PopulationScoreProvider.java | 7 +- .../recommendation/RecommendationMapper.java | 1 - .../recommendation/RecommendationProp.java | 1 + .../recommendation/RecommendationRequest.java | 1 - .../economatic/search/PredicateBuilder.java | 2 +- .../economatic/search/SearchRequest.java | 1 + .../search/SpecificationBuilder.java | 4 +- .../AfterOrEqualsPredicateFactory.java | 1 + .../factories/AfterPredicateFactory.java | 3 +- .../BeforeOrEqualsPredicateFactory.java | 1 + .../factories/BeforePredicateFactory.java | 1 + .../BetweenDateTimePredicateFactory.java | 18 +-- .../BetweenNumericPredicateFactory.java | 24 ++-- .../factories/EqualsPredicateFactory.java | 14 +-- .../GreaterThanOrEqualsPredicateFactory.java | 1 + .../GreaterThanPredicateFactory.java | 1 + .../search/factories/InPredicateFactory.java | 1 + .../LessThanOrEqualsPredicateFactory.java | 1 + .../factories/LessThanPredicateFactory.java | 1 + .../factories/LikePredicateFactory.java | 1 + .../factories/PredicateFactoryProvider.java | 4 +- .../thoroldvix/economatic/server/Faction.java | 1 + .../economatic/server/ServerListResponse.java | 1 + .../server/ServerNotFoundException.java | 1 + .../economatic/server/ServerServiceImpl.java | 2 +- .../economatic/server/ServerType.java | 1 + .../economatic/stats/StatsProjection.java | 1 + .../stats/goldprice/GoldPriceStatMapper.java | 1 + .../goldprice/GoldPriceStatRepository.java | 45 +++---- .../goldprice/GoldPriceStatServiceImpl.java | 6 +- .../population/PopulationStatController.java | 2 +- .../population/PopulationStatMapper.java | 2 - .../population/PopulationStatRepository.java | 46 +++---- .../population/PopulationStatResponse.java | 1 + .../population/PopulationStatServiceImpl.java | 7 +- .../summary/item/ItemSummaryProjection.java | 1 + .../summary/item/ItemSummaryResponse.java | 30 +++-- .../summary/item/ItemSummaryService.java | 1 + .../server/ServerSummaryProjection.java | 1 + .../server/ServerSummaryRepository.java | 2 +- .../summary/server/ServerSummaryResponse.java | 6 + .../summary/server/ServerSummaryService.java | 1 + .../economatic/util/StringEnumConverter.java | 3 +- .../com/thoroldvix/economatic/util/Utils.java | 5 +- .../economatic/util/ValidationUtils.java | 2 +- .../economatic/deal/BaseItemDealTest.java | 1 + .../deal/ItemDealsRepositoryTest.java | 3 +- .../deal/ItemDealsServiceImplTest.java | 1 + .../goldprice/GoldPriceControllerTest.java | 8 +- .../goldprice/GoldPriceDataInitializer.java | 2 +- .../goldprice/GoldPriceMapperTest.java | 2 +- .../goldprice/GoldPriceServiceImplTest.java | 5 +- .../GoldPriceStatServiceImplTest.java | 5 +- .../economatic/util/ValidationUtilsTest.java | 4 +- 74 files changed, 360 insertions(+), 336 deletions(-) diff --git a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceController.java b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceController.java index c4ce2845..a29ec1ab 100644 --- a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceController.java +++ b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceController.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.goldprice; -import com.thoroldvix.economatic.search.SearchRequest; import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.search.SearchRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; diff --git a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceMapper.java b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceMapper.java index 05db5c9b..972fdb90 100644 --- a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceMapper.java +++ b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceMapper.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.goldprice; -import com.thoroldvix.economatic.server.Server; import com.thoroldvix.economatic.dto.PaginationInfo; +import com.thoroldvix.economatic.server.Server; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; diff --git a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceService.java b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceService.java index abc9faf9..6c99af4b 100644 --- a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceService.java +++ b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceService.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.goldprice; -import com.thoroldvix.economatic.search.SearchRequest; import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.search.SearchRequest; import jakarta.validation.Valid; import org.springframework.data.domain.Pageable; import org.springframework.validation.annotation.Validated; diff --git a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImpl.java b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImpl.java index 93e049c1..2b33eef4 100644 --- a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImpl.java +++ b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImpl.java @@ -1,12 +1,12 @@ package com.thoroldvix.economatic.goldprice; +import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.search.SearchRequest; +import com.thoroldvix.economatic.search.SpecificationBuilder; import com.thoroldvix.economatic.server.Faction; import com.thoroldvix.economatic.server.Region; import com.thoroldvix.economatic.server.ServerResponse; import com.thoroldvix.economatic.server.ServerService; -import com.thoroldvix.economatic.search.SearchRequest; -import com.thoroldvix.economatic.dto.TimeRange; -import com.thoroldvix.economatic.search.SpecificationBuilder; import com.thoroldvix.economatic.util.StringEnumConverter; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -48,7 +48,6 @@ public GoldPriceResponse getForId(long id) { .orElseThrow(() -> new GoldPriceNotFoundException("No gold price found with id " + id)); } - @Override public GoldPricePageResponse getAll(TimeRange timeRange, Pageable pageable) { validateInputs(timeRange, pageable); @@ -58,6 +57,34 @@ public GoldPricePageResponse getAll(TimeRange timeRange, Pageable pageable) { return goldPriceMapper.toPageResponse(page); } + private Page findAllForTimeRange(TimeRange timeRange, Pageable pageable) { + return goldPriceRepository.findAllForTimeRange(timeRange.start(), timeRange.end(), pageable); + } + + private void validateInputs(TimeRange timeRange, Pageable pageable) { + requireNonNull(timeRange, TIME_RANGE_CANNOT_BE_NULL); + requireNonNull(pageable, PAGEABLE_CANNOT_BE_NULL); + } + + @Override + public GoldPricePageResponse getForServer(String serverIdentifier, TimeRange timeRange, Pageable pageable) { + notEmpty(serverIdentifier, SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); + validateInputs(timeRange, pageable); + + ServerResponse server = serverService.getServer(serverIdentifier); + Page prices = findAllForServer(server, timeRange, pageable); + + notEmpty(prices.getContent(), + () -> new GoldPriceNotFoundException("No prices found for server identifier %s and time range: %s-%s".formatted( + serverIdentifier, timeRange.start(), timeRange.end()))); + + return goldPriceMapper.toPageResponse(prices); + } + + private Page findAllForServer(ServerResponse server, TimeRange timeRange, Pageable pageable) { + return goldPriceRepository.findAllForServerAndTimeRange(server.id(), timeRange.start(), timeRange.end(), pageable); + } + @Override public GoldPriceListResponse getAllRecent() { List prices = goldPriceRepository.findAllRecent(); @@ -79,21 +106,12 @@ public GoldPricePageResponse search(@Valid SearchRequest searchRequest, Pageable return goldPriceMapper.toPageResponse(prices); } - @Override - public GoldPricePageResponse getForServer(String serverIdentifier, TimeRange timeRange, Pageable pageable) { - notEmpty(serverIdentifier, SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); - validateInputs(timeRange, pageable); - - ServerResponse server = serverService.getServer(serverIdentifier); - Page prices = findAllForServer(server, timeRange, pageable); - - notEmpty(prices.getContent(), - () -> new GoldPriceNotFoundException("No prices found for server identifier %s and time range: %s-%s".formatted( - serverIdentifier, timeRange.start(), timeRange.end()))); - - return goldPriceMapper.toPageResponse(prices); + private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { + Specification spec = SpecificationBuilder.from(searchRequest); + return goldPriceRepository.findAll(spec, pageable); } + @Override public GoldPriceResponse getRecentForServer(String serverIdentifier) { notEmpty(serverIdentifier, SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); @@ -105,6 +123,10 @@ public GoldPriceResponse getRecentForServer(String serverIdentifier) { return goldPriceMapper.toResponse(price); } + private Optional findRecentForServer(ServerResponse server) { + return goldPriceRepository.findRecentForServer(server.id()); + } + @Override public GoldPriceListResponse getRecentForRegion(String regionName) { notEmpty(regionName, REGION_NAME_CANNOT_BE_NULL_OR_EMPTY); @@ -115,6 +137,11 @@ public GoldPriceListResponse getRecentForRegion(String regionName) { return goldPriceMapper.toGoldPriceList(prices); } + private List findRecentForRegion(String regionName) { + Region region = StringEnumConverter.fromString(regionName, Region.class); + return goldPriceRepository.findRecentForRegion(region.ordinal()); + } + @Override public GoldPriceListResponse getRecentForFaction(String factionName) { notEmpty(factionName, FACTION_NAME_CANNOT_BE_NULL_OR_EMPTY); @@ -125,6 +152,11 @@ public GoldPriceListResponse getRecentForFaction(String factionName) { return goldPriceMapper.toGoldPriceList(prices); } + private List findRecentForFaction(String factionName) { + Faction faction = StringEnumConverter.fromString(factionName, Faction.class); + return goldPriceRepository.findRecentForFaction(faction.ordinal()); + } + @Override public GoldPriceListResponse getRecentForServerList(@Valid GoldPriceRequest request) { requireNonNull(request, "Gold price request cannot be null"); @@ -136,54 +168,21 @@ public GoldPriceListResponse getRecentForServerList(@Valid GoldPriceRequest requ return goldPriceMapper.toGoldPriceList(prices); } - @Override - @Transactional - public void saveAll(List pricesToSave) { - notEmpty(pricesToSave, () -> new IllegalArgumentException("Prices cannot be null or empty")); - - goldPriceRepository.saveAll(pricesToSave); - } - - private Page findAllForServer(ServerResponse server, TimeRange timeRange, Pageable pageable) { - return goldPriceRepository.findAllForServerAndTimeRange(server.id(), timeRange.start(), timeRange.end(), pageable); - } - - private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { - Specification spec = SpecificationBuilder.from(searchRequest); - return goldPriceRepository.findAll(spec, pageable); - } - - private Page findAllForTimeRange(TimeRange timeRange, Pageable pageable) { - return goldPriceRepository.findAllForTimeRange(timeRange.start(), timeRange.end(), pageable); - } - - private List findRecentForRegion(String regionName) { - Region region = StringEnumConverter.fromString(regionName, Region.class); - return goldPriceRepository.findRecentForRegion(region.ordinal()); - } - - private List findRecentForFaction(String factionName) { - Faction faction = StringEnumConverter.fromString(factionName, Faction.class); - return goldPriceRepository.findRecentForFaction(faction.ordinal()); - } - - private Optional findRecentForServer(ServerResponse server) { - return goldPriceRepository.findRecentForServer(server.id()); - } - - private List findRecentForServerIds(Set serverIds) { - return goldPriceRepository.findRecentForServerIds(serverIds); - } - private Set getServerIds(Set serverList) { return serverList.stream() .map(server -> serverService.getServer(server).id()) .collect(Collectors.toSet()); } - private void validateInputs(TimeRange timeRange, Pageable pageable) { - requireNonNull(timeRange, TIME_RANGE_CANNOT_BE_NULL); - requireNonNull(pageable, PAGEABLE_CANNOT_BE_NULL); + private List findRecentForServerIds(Set serverIds) { + return goldPriceRepository.findRecentForServerIds(serverIds); } + @Override + @Transactional + public void saveAll(List pricesToSave) { + notEmpty(pricesToSave, () -> new IllegalArgumentException("Prices cannot be null or empty")); + + goldPriceRepository.saveAll(pricesToSave); + } } \ No newline at end of file diff --git a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceUpdateService.java b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceUpdateService.java index d0f8570a..f2e78785 100644 --- a/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceUpdateService.java +++ b/src/main/java/com/thoroldvix/economatic/goldprice/GoldPriceUpdateService.java @@ -24,6 +24,7 @@ class GoldPriceUpdateService { public static final String UPDATE_ON_STARTUP_OR_DEFAULT = "#{${economatic.update-on-startup} ? -1 : ${economatic.gold-price.update-rate}}"; public static final String UPDATE_RATE = "${economatic.gold-price.update-rate}"; + @PersistenceContext private final EntityManager entityManager; private final GoldPriceServiceImpl goldPriceServiceImpl; @@ -44,7 +45,6 @@ protected void update() { List pricesToSave = getPriceList(servers, prices); goldPriceServiceImpl.saveAll(pricesToSave); - log.info("Finished updating gold prices in {} ms", elapsedTimeInMillis(start)); } diff --git a/src/main/java/com/thoroldvix/economatic/item/ItemServiceImpl.java b/src/main/java/com/thoroldvix/economatic/item/ItemServiceImpl.java index 1c8b5649..e0d4fcea 100644 --- a/src/main/java/com/thoroldvix/economatic/item/ItemServiceImpl.java +++ b/src/main/java/com/thoroldvix/economatic/item/ItemServiceImpl.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.item; -import com.thoroldvix.economatic.search.SpecificationBuilder; import com.thoroldvix.economatic.search.SearchRequest; +import com.thoroldvix.economatic.search.SpecificationBuilder; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -28,7 +28,6 @@ class ItemServiceImpl implements ItemService { public static final String ITEMS_NOT_FOUND = "Items not found"; - private final ItemMapper itemMapper; private final ItemRepository itemRepository; @@ -43,6 +42,11 @@ public ItemPageResponse search(@Valid SearchRequest searchRequest, Pageable page return itemMapper.toPageResponse(items); } + private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { + Specification spec = SpecificationBuilder.from(searchRequest); + return itemRepository.findAll(spec, pageable); + } + @Override public ItemPageResponse getAll(Pageable pageable) { requireNonNull(pageable, PAGEABLE_CANNOT_BE_NULL); @@ -53,7 +57,6 @@ public ItemPageResponse getAll(Pageable pageable) { return itemMapper.toPageResponse(page); } - @Override public ItemResponse getItem(String itemIdentifier) { notEmpty(itemIdentifier, ITEM_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); @@ -63,18 +66,13 @@ public ItemResponse getItem(String itemIdentifier) { .orElseThrow(() -> new ItemNotFoundException("No item found for identifier " + itemIdentifier)); } - - @Override - @Transactional - public ItemResponse addItem(@Valid ItemRequest itemRequest) { - requireNonNull(itemRequest, "Item request cannot be null"); - - Item item = itemMapper.fromRequest(itemRequest); - itemRepository.findById(item.getId()).ifPresent(i -> { - throw new ItemAlreadyExistsException("Item with id " + item.getId() + " already exists"); - }); - - return itemMapper.toResponse(itemRepository.save(item)); + private Optional findItem(String itemIdentifier) { + try { + int itemId = Integer.parseInt(itemIdentifier); + return itemRepository.findById(itemId); + } catch (NumberFormatException ignored) { + return itemRepository.findByUniqueName(itemIdentifier); + } } @Override @@ -89,18 +87,18 @@ public ItemResponse deleteItem(String itemIdentifier) { return itemMapper.toResponse(item); } - private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { - Specification spec = SpecificationBuilder.from(searchRequest); - return itemRepository.findAll(spec, pageable); - } + @Override + @Transactional + public ItemResponse addItem(@Valid ItemRequest itemRequest) { + requireNonNull(itemRequest, "Item request cannot be null"); - private Optional findItem(String itemIdentifier) { - try { - int itemId = Integer.parseInt(itemIdentifier); - return itemRepository.findById(itemId); - } catch (NumberFormatException ignored) { - return itemRepository.findByUniqueName(itemIdentifier); - } + Item item = itemMapper.fromRequest(itemRequest); + itemRepository.findById(item.getId()).ifPresent(i -> { + throw new ItemAlreadyExistsException("Item with id " + item.getId() + " already exists"); + }); + + return itemMapper.toResponse(itemRepository.save(item)); } + } \ No newline at end of file diff --git a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceController.java b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceController.java index ac501f59..15ef0910 100644 --- a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceController.java +++ b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceController.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.itemprice; -import com.thoroldvix.economatic.search.SearchRequest; import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.search.SearchRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; diff --git a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceMapper.java b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceMapper.java index d284789a..0d2785bd 100644 --- a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceMapper.java +++ b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceMapper.java @@ -1,8 +1,8 @@ package com.thoroldvix.economatic.itemprice; +import com.thoroldvix.economatic.dto.PaginationInfo; import com.thoroldvix.economatic.item.Item; import com.thoroldvix.economatic.server.Server; -import com.thoroldvix.economatic.dto.PaginationInfo; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; diff --git a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceService.java b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceService.java index 92d31347..b3c8bcac 100644 --- a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceService.java +++ b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceService.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.itemprice; -import com.thoroldvix.economatic.search.SearchRequest; import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.search.SearchRequest; import jakarta.validation.Valid; import org.springframework.data.domain.Pageable; import org.springframework.validation.annotation.Validated; diff --git a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceServiceImpl.java b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceServiceImpl.java index 507e10b3..976d3578 100644 --- a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceServiceImpl.java +++ b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceServiceImpl.java @@ -39,7 +39,6 @@ @RequiredArgsConstructor class ItemPriceServiceImpl implements ItemPriceService { - private final ItemService itemService; private final ServerService serverService; private final ItemPriceRepository itemPriceRepository; @@ -61,6 +60,10 @@ public ItemPricePageResponse getRecentForServer(String serverIdentifier, Pageabl return itemPriceMapper.toPageResponse(page); } + private Page findRecentForServer(ServerResponse server, Pageable pageable) { + return itemPriceRepository.findRecentForServer(server.id(), pageable); + } + @Override public ItemPriceListResponse getRecentForRegion(String regionName, String itemIdentifier) { notEmpty(regionName, REGION_NAME_CANNOT_BE_NULL_OR_EMPTY); @@ -75,6 +78,11 @@ public ItemPriceListResponse getRecentForRegion(String regionName, String itemId return itemPriceMapper.toItemPriceList(itemPrices); } + private List findRecentForRegionAndItem(String regionName, ItemResponse item) { + Region region = StringEnumConverter.fromString(regionName, Region.class); + return itemPriceRepository.findRecentForRegionAndItem(region.ordinal(), item.id()); + } + @Override public ItemPriceListResponse getRecentForFaction(String factionName, String itemIdentifier) { notEmpty(factionName, FACTION_NAME_CANNOT_BE_NULL_OR_EMPTY); @@ -89,6 +97,11 @@ public ItemPriceListResponse getRecentForFaction(String factionName, String item return itemPriceMapper.toItemPriceList(itemPrices); } + private List findRecentForFactionAndItem(String factionName, ItemResponse item) { + Faction faction = StringEnumConverter.fromString(factionName, Faction.class); + return itemPriceRepository.findRecentForFactionAndItem(faction.ordinal(), item.id()); + } + @Override public ItemPriceListResponse getRecentForServer(String serverIdentifier, String itemIdentifier) { notEmpty(serverIdentifier, SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); @@ -105,6 +118,10 @@ public ItemPriceListResponse getRecentForServer(String serverIdentifier, String return itemPriceMapper.toItemPriceList(itemPrices); } + private List findRecentForServerAndItem(ServerResponse server, ItemResponse item) { + return itemPriceRepository.findRecentForServerAndItem(server.id(), item.id()); + } + @Override public ItemPricePageResponse search(@Valid SearchRequest searchRequest, Pageable pageable) { requireNonNull(pageable, PAGEABLE_CANNOT_BE_NULL); @@ -116,6 +133,11 @@ public ItemPricePageResponse search(@Valid SearchRequest searchRequest, Pageable return itemPriceMapper.toPageResponse(page); } + private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { + Specification specification = SpecificationBuilder.from(searchRequest); + return itemPriceRepository.findAll(specification, pageable); + } + @Override public ItemPricePageResponse getForServer(String serverIdentifier, String itemIdentifier, TimeRange timeRange, Pageable pageable) { notEmpty(serverIdentifier, SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); @@ -134,6 +156,14 @@ public ItemPricePageResponse getForServer(String serverIdentifier, String itemId return itemPriceMapper.toPageResponse(page); } + private Page findForServerAndTimeRange(ServerResponse server, + ItemResponse item, + TimeRange timeRange, + Pageable pageable) { + + return itemPriceRepository.findForServerAndTimeRange(server.id(), item.id(), timeRange.start(), timeRange.end(), pageable); + } + @Override public ItemPricePageResponse getRecentForItemListAndServers(@Valid ItemPriceRequest request, Pageable pageable) { requireNonNull(request, "Item price request cannot be null"); @@ -149,65 +179,30 @@ public ItemPricePageResponse getRecentForItemListAndServers(@Valid ItemPriceRequ return itemPriceMapper.toPageResponse(page); } - @Override - @Transactional - public void saveAll(List itemPricesToSave) { - requireNonNull(itemPricesToSave, "Item prices cannot be null"); - jdbcRepository.saveAll(itemPricesToSave); - } - - private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { - Specification specification = SpecificationBuilder.from(searchRequest); - return itemPriceRepository.findAll(specification, pageable); - } - - - private Page findRecentForServer(ServerResponse server, Pageable pageable) { - return itemPriceRepository.findRecentForServer(server.id(), pageable); - } - - - private Page findForServerAndTimeRange(ServerResponse server, - ItemResponse item, - TimeRange timeRange, - Pageable pageable) { - - return itemPriceRepository.findForServerAndTimeRange(server.id(), item.id(), timeRange.start(), timeRange.end(), pageable); - } - - - private List findRecentForServerAndItem(ServerResponse server, ItemResponse item) { - return itemPriceRepository.findRecentForServerAndItem(server.id(), item.id()); - } - - - private List findRecentForRegionAndItem(String regionName, ItemResponse item) { - Region region = StringEnumConverter.fromString(regionName, Region.class); - return itemPriceRepository.findRecentForRegionAndItem(region.ordinal(), item.id()); + private Set getItemIds(Set itemList) { + return itemList.parallelStream() + .map(item -> itemService.getItem(item).id()) + .collect(Collectors.toSet()); } - - private List findRecentForFactionAndItem(String factionName, ItemResponse item) { - Faction faction = StringEnumConverter.fromString(factionName, Faction.class); - return itemPriceRepository.findRecentForFactionAndItem(faction.ordinal(), item.id()); + private Set getServerIds(Set serverList) { + return serverList.parallelStream() + .map(server -> serverService.getServer(server).id()) + .collect(Collectors.toSet()); } - private Page findRecentForItemsAndServers(Set serverIds, Set itemIds, Pageable pageable) { return isCollectionEmpty(serverIds) ? itemPriceRepository.findRecentForItemList(itemIds, pageable) : itemPriceRepository.findRecentForItemsAndServers(itemIds, serverIds, pageable); } - private Set getServerIds(Set serverList) { - return serverList.parallelStream() - .map(server -> serverService.getServer(server).id()) - .collect(Collectors.toSet()); + @Override + @Transactional + public void saveAll(List itemPricesToSave) { + requireNonNull(itemPricesToSave, "Item prices cannot be null"); + jdbcRepository.saveAll(itemPricesToSave); } - private Set getItemIds(Set itemList) { - return itemList.parallelStream() - .map(item -> itemService.getItem(item).id()) - .collect(Collectors.toSet()); - } + } diff --git a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceUpdateService.java b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceUpdateService.java index 31900025..25354f00 100644 --- a/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceUpdateService.java +++ b/src/main/java/com/thoroldvix/economatic/itemprice/ItemPriceUpdateService.java @@ -26,9 +26,9 @@ class ItemPriceUpdateService { public static final String UPDATE_RATE = "${economatic.item-price.update-rate}"; public static final String UPDATE_ON_STARTUP_OR_DEFAULT = "#{${economatic.update-on-startup} ? -1 : ${economatic.item-price.update-rate}}"; + @PersistenceContext private final EntityManager entityManager; - private final ItemPriceService itemPriceServiceImpl; private final NexusHubService nexusHubService; private final Map serverIdentifiers; @@ -44,6 +44,11 @@ public ItemPriceUpdateService(EntityManager entityManager, this.serverIdentifiers = getServerIds(serverService); } + private Map getServerIds(ServerService serverService) { + return serverService.getAll().servers().stream() + .collect(Collectors.toMap(ServerResponse::uniqueName, ServerResponse::id, (id1, id2) -> id1)); + } + @Scheduled(fixedRateString = UPDATE_RATE, initialDelayString = UPDATE_ON_STARTUP_OR_DEFAULT, timeUnit = TimeUnit.HOURS) @@ -61,27 +66,23 @@ protected void update() { log.info("Finished updating item prices in {} ms", elapsedTimeInMillis(start)); } - private List retrieveItemPricesForServer(String serverName) { List nexusHubPrices = nexusHubService.retrieveItemPricesForServer(serverName); Server server = getServer(serverName); return toItemPriceList(server, nexusHubPrices); } - private Server getServer(String uniqueServerName) { int serverId = serverIdentifiers.get(uniqueServerName); return entityManager.getReference(Server.class, serverId); } - private List toItemPriceList(Server server, List filteredPrices) { return filteredPrices.parallelStream() .map(itemResponse -> buildItemPrice(server, itemResponse)) .toList(); } - private ItemPrice buildItemPrice(Server server, NexusHubResponse.NexusHubPrice price) { Item item = entityManager.getReference(Item.class, price.itemId()); @@ -95,9 +96,4 @@ private ItemPrice buildItemPrice(Server server, NexusHubResponse.NexusHubPrice p .server(server) .build(); } - - private Map getServerIds(ServerService serverService) { - return serverService.getAll().servers().stream() - .collect(Collectors.toMap(ServerResponse::uniqueName, ServerResponse::id, (id1, id2) -> id1)); - } } diff --git a/src/main/java/com/thoroldvix/economatic/itemprice/NexusHubService.java b/src/main/java/com/thoroldvix/economatic/itemprice/NexusHubService.java index 0f6e8846..a8b78b4c 100644 --- a/src/main/java/com/thoroldvix/economatic/itemprice/NexusHubService.java +++ b/src/main/java/com/thoroldvix/economatic/itemprice/NexusHubService.java @@ -23,12 +23,25 @@ public NexusHubService(NexusHubClient nexusHubClient, ItemService itemService) { this.itemIds = getItemIds(itemService); } + private Set getItemIds(ItemService itemService) { + return itemService.getAll(Pageable.unpaged()).items().stream() + .map(ItemResponse::id) + .collect(Collectors.toSet()); + } + public List retrieveItemPricesForServer(String serverName) { RATE_LIMITER.acquire(); NexusHubResponse nexusHubResponse = nexusHubClient.fetchAllItemPricesForServer(serverName); return filterPriceList(nexusHubResponse.data()); } + + private List filterPriceList(List prices) { + return prices.stream() + .filter(this::filterPrice) + .toList(); + } + private boolean filterPrice(NexusHubResponse.NexusHubPrice price) { return itemIds.contains(price.itemId()) && price.quantity() > 0 && @@ -37,15 +50,5 @@ private boolean filterPrice(NexusHubResponse.NexusHubPrice price) { price.numAuctions() > 0; } - private List filterPriceList(List prices) { - return prices.stream() - .filter(this::filterPrice) - .toList(); - } - private Set getItemIds(ItemService itemService) { - return itemService.getAll(Pageable.unpaged()).items().stream() - .map(ItemResponse::id) - .collect(Collectors.toSet()); - } } diff --git a/src/main/java/com/thoroldvix/economatic/population/PopulationController.java b/src/main/java/com/thoroldvix/economatic/population/PopulationController.java index ee250a65..062cd4b5 100644 --- a/src/main/java/com/thoroldvix/economatic/population/PopulationController.java +++ b/src/main/java/com/thoroldvix/economatic/population/PopulationController.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.population; -import com.thoroldvix.economatic.search.SearchRequest; import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.search.SearchRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; diff --git a/src/main/java/com/thoroldvix/economatic/population/PopulationMapper.java b/src/main/java/com/thoroldvix/economatic/population/PopulationMapper.java index 1eef5937..204943e9 100644 --- a/src/main/java/com/thoroldvix/economatic/population/PopulationMapper.java +++ b/src/main/java/com/thoroldvix/economatic/population/PopulationMapper.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.population; -import com.thoroldvix.economatic.server.Server; import com.thoroldvix.economatic.dto.PaginationInfo; +import com.thoroldvix.economatic.server.Server; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; diff --git a/src/main/java/com/thoroldvix/economatic/population/PopulationService.java b/src/main/java/com/thoroldvix/economatic/population/PopulationService.java index d0f39cf4..9dc84d7b 100644 --- a/src/main/java/com/thoroldvix/economatic/population/PopulationService.java +++ b/src/main/java/com/thoroldvix/economatic/population/PopulationService.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.population; -import com.thoroldvix.economatic.search.SearchRequest; import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.search.SearchRequest; import jakarta.validation.Valid; import org.springframework.data.domain.Pageable; import org.springframework.validation.annotation.Validated; diff --git a/src/main/java/com/thoroldvix/economatic/population/PopulationServiceImpl.java b/src/main/java/com/thoroldvix/economatic/population/PopulationServiceImpl.java index 60c603b8..5aef0337 100644 --- a/src/main/java/com/thoroldvix/economatic/population/PopulationServiceImpl.java +++ b/src/main/java/com/thoroldvix/economatic/population/PopulationServiceImpl.java @@ -32,6 +32,7 @@ class PopulationServiceImpl implements PopulationService { public static final String NO_POPULATIONS_FOUND = "No populations found"; + private final PopulationRepository populationRepository; private final ServerService serverService; private final PopulationMapper populationMapper; @@ -56,6 +57,10 @@ public PopulationPageResponse getAll(TimeRange timeRange, Pageable pageable) { return populationMapper.toPageResponse(page); } + private Page findForTimeRange(TimeRange timeRange, Pageable pageable) { + return populationRepository.findAllForTimeRange(timeRange.start(), timeRange.end(), pageable); + } + @Override public PopulationPageResponse getForServer(String serverIdentifier, TimeRange timeRange, Pageable pageable) { notEmpty(serverIdentifier, SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); @@ -71,6 +76,10 @@ public PopulationPageResponse getForServer(String serverIdentifier, TimeRange ti return populationMapper.toPageResponse(page); } + private Page findAllForServer(ServerResponse server, TimeRange timeRange, Pageable pageable) { + return populationRepository.findAllForServer(server.id(), timeRange.start(), timeRange.end(), pageable); + } + @Override public TotalPopResponse getTotalPopulation(String serverName) { notEmpty(serverName, "Server name cannot be null or empty"); @@ -83,6 +92,15 @@ public TotalPopResponse getTotalPopulation(String serverName) { return populationMapper.toTotalPopResponse(totalPopProjection); } + private void validateTotalPopProj(TotalPopProjection totalPopProjection, String serverName) { + boolean isInvalid = totalPopProjection.getPopTotal() == null + || totalPopProjection.getPopHorde() == null + || totalPopProjection.getPopAlliance() == null; + if (isInvalid) { + throw new PopulationNotFoundException("No total population found for server name " + serverName); + } + } + @Override public PopulationPageResponse search(@Valid SearchRequest searchRequest, Pageable pageable) { requireNonNull(searchRequest, SEARCH_REQUEST_CANNOT_BE_NULL); @@ -95,6 +113,11 @@ public PopulationPageResponse search(@Valid SearchRequest searchRequest, Pageabl return populationMapper.toPageResponse(populations); } + private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { + Specification spec = SpecificationBuilder.from(searchRequest); + return populationRepository.findAll(spec, pageable); + } + @Override public PopulationListResponse getRecentForRegion(String regionName) { notEmpty(regionName, REGION_NAME_CANNOT_BE_NULL_OR_EMPTY); @@ -106,6 +129,11 @@ public PopulationListResponse getRecentForRegion(String regionName) { return populationMapper.toPopulationList(population); } + private List findRecentForRegion(String regionName) { + Region region = StringEnumConverter.fromString(regionName, Region.class); + return populationRepository.findRecentForRegion(region); + } + @Override public PopulationListResponse getRecentForFaction(String factionName) { notEmpty(factionName, FACTION_NAME_CANNOT_BE_NULL_OR_EMPTY); @@ -116,6 +144,12 @@ public PopulationListResponse getRecentForFaction(String factionName) { return populationMapper.toPopulationList(population); } + private List findRecentForFaction(String factionName) { + Faction faction = StringEnumConverter.fromString(factionName, Faction.class); + + return populationRepository.findRecentForFaction(faction); + } + @Override public PopulationListResponse getAllRecent() { List populations = populationRepository.findAllRecent(); @@ -136,6 +170,10 @@ public PopulationResponse getRecentForServer(String serverIdentifier) { return populationMapper.toResponse(population); } + private Optional findRecentForServer(ServerResponse server) { + return populationRepository.findRecentForServer(server.id()); + } + @Override @Transactional public void saveAll(List populations) { @@ -144,43 +182,5 @@ public void saveAll(List populations) { populationRepository.saveAll(populations); } - - private Optional findRecentForServer(ServerResponse server) { - return populationRepository.findRecentForServer(server.id()); - } - - - private Page findAllForSearch(SearchRequest searchRequest, Pageable pageable) { - Specification spec = SpecificationBuilder.from(searchRequest); - return populationRepository.findAll(spec, pageable); - } - - private List findRecentForRegion(String regionName) { - Region region = StringEnumConverter.fromString(regionName, Region.class); - return populationRepository.findRecentForRegion(region); - } - - private List findRecentForFaction(String factionName) { - Faction faction = StringEnumConverter.fromString(factionName, Faction.class); - - return populationRepository.findRecentForFaction(faction); - } - - private Page findAllForServer(ServerResponse server, TimeRange timeRange, Pageable pageable) { - return populationRepository.findAllForServer(server.id(), timeRange.start(), timeRange.end(), pageable); - } - - private Page findForTimeRange(TimeRange timeRange, Pageable pageable) { - return populationRepository.findAllForTimeRange(timeRange.start(), timeRange.end(), pageable); - } - - private void validateTotalPopProj(TotalPopProjection totalPopProjection, String serverName) { - boolean isInvalid = totalPopProjection.getPopTotal() == null - || totalPopProjection.getPopHorde() == null - || totalPopProjection.getPopAlliance() == null; - if (isInvalid) { - throw new PopulationNotFoundException("No total population found for server name " + serverName); - } - } } diff --git a/src/main/java/com/thoroldvix/economatic/population/PopulationUpdateService.java b/src/main/java/com/thoroldvix/economatic/population/PopulationUpdateService.java index 596ff397..fa00e3db 100644 --- a/src/main/java/com/thoroldvix/economatic/population/PopulationUpdateService.java +++ b/src/main/java/com/thoroldvix/economatic/population/PopulationUpdateService.java @@ -80,7 +80,4 @@ private Population buildPopulation(TotalPopResponse totalPopulation, ServerRespo .server(serverEntity) .build(); } - - - } diff --git a/src/main/java/com/thoroldvix/economatic/recommendation/BasicRecommendationService.java b/src/main/java/com/thoroldvix/economatic/recommendation/BasicRecommendationService.java index 34c899b7..7a49b21e 100644 --- a/src/main/java/com/thoroldvix/economatic/recommendation/BasicRecommendationService.java +++ b/src/main/java/com/thoroldvix/economatic/recommendation/BasicRecommendationService.java @@ -20,7 +20,6 @@ class BasicRecommendationService implements RecommendationService { private final GoldPriceScoreProvider goldPriceScoreProvider; private final RecommendationMapper recommendationMapper; - public RecommendationListResponse getRecommendationsForItemList(@Valid RecommendationRequest request, int limit) { requireNonNull(request, "Recommendation request cannot be null"); notLessThan(limit, 1, "Limit cannot be less than 1"); diff --git a/src/main/java/com/thoroldvix/economatic/recommendation/GoldPriceScoreProvider.java b/src/main/java/com/thoroldvix/economatic/recommendation/GoldPriceScoreProvider.java index c800899e..408cafde 100644 --- a/src/main/java/com/thoroldvix/economatic/recommendation/GoldPriceScoreProvider.java +++ b/src/main/java/com/thoroldvix/economatic/recommendation/GoldPriceScoreProvider.java @@ -15,16 +15,16 @@ @Service @RequiredArgsConstructor class GoldPriceScoreProvider extends ScoreProvider { + private static final BigDecimal MAX_GOLD_PRICE_USD = new BigDecimal("0.0025"); private final GoldPriceService goldPriceServiceImpl; private final RecommendationProp prop; - public Map getGoldPriceScores(BigDecimal goldPriceWeight, Set servers) { BigDecimal weight = getWeightOrDefault(goldPriceWeight, prop.goldPriceDefaultWeight()); GoldPriceRequest request = new GoldPriceRequest(servers); - List recentPrices = goldPriceServiceImpl.getRecentForServerList(request).prices(); + return createScores(recentPrices, weight); } diff --git a/src/main/java/com/thoroldvix/economatic/recommendation/ItemPriceScoreProvider.java b/src/main/java/com/thoroldvix/economatic/recommendation/ItemPriceScoreProvider.java index 63b28bb7..4068b2ad 100644 --- a/src/main/java/com/thoroldvix/economatic/recommendation/ItemPriceScoreProvider.java +++ b/src/main/java/com/thoroldvix/economatic/recommendation/ItemPriceScoreProvider.java @@ -57,7 +57,7 @@ private void validateInputs(RecommendationRequest request, Set servers) } - private static ItemPriceRequest buildItemPriceRequest(Set itemList, Set servers) { + private static ItemPriceRequest buildItemPriceRequest(Set itemList, Set servers) { return ItemPriceRequest.builder() .itemList(itemList) .serverList(servers) diff --git a/src/main/java/com/thoroldvix/economatic/recommendation/PopulationScoreProvider.java b/src/main/java/com/thoroldvix/economatic/recommendation/PopulationScoreProvider.java index ec2cf455..aa4dc4a1 100644 --- a/src/main/java/com/thoroldvix/economatic/recommendation/PopulationScoreProvider.java +++ b/src/main/java/com/thoroldvix/economatic/recommendation/PopulationScoreProvider.java @@ -18,10 +18,10 @@ class PopulationScoreProvider extends ScoreProvider { private final PopulationService populationServiceImpl; private final RecommendationProp prop; - public Map getPopulationScores(BigDecimal populationWeight) { + public Map getPopulationScores(BigDecimal populationWeight) { BigDecimal weight = getWeightOrDefault(populationWeight, prop.populationDefaultWeight()); - List recentPopulations = populationServiceImpl.getAllRecent().populations(); - return createScores(recentPopulations, weight); + List recentPopulations = populationServiceImpl.getAllRecent().populations(); + return createScores(recentPopulations, weight); } private Map createScores(List recentPopulations, BigDecimal weight) { @@ -33,7 +33,6 @@ private Map createScores(List recentPopu )); } - private boolean filterLowPopulations(PopulationResponse population) { return population.value() >= this.prop.minAllowedPopulation(); } diff --git a/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationMapper.java b/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationMapper.java index ac677d91..746ffffd 100644 --- a/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationMapper.java +++ b/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationMapper.java @@ -17,7 +17,6 @@ interface RecommendationMapper { BigDecimal DEFAULT_SCORE = BigDecimal.ZERO; int SCALE = 6; - default RecommendationListResponse toRecommendationResponse( Map itemPriceScores, Map populationScores, diff --git a/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationProp.java b/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationProp.java index cb39c7ae..ac10b6fc 100644 --- a/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationProp.java +++ b/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationProp.java @@ -11,6 +11,7 @@ record RecommendationProp( BigDecimal goldPriceDefaultWeight, int minAllowedPopulation ) { + public RecommendationProp { validate(itemPriceDefaultWeight, populationDefaultWeight, goldPriceDefaultWeight, minAllowedPopulation); } diff --git a/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationRequest.java b/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationRequest.java index d7412573..6236e802 100644 --- a/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationRequest.java +++ b/src/main/java/com/thoroldvix/economatic/recommendation/RecommendationRequest.java @@ -19,7 +19,6 @@ public record RecommendationRequest( int minAllowedPopulation, @NotEmpty(message = "Item list cannot be null or empty") Set itemList, - boolean marketValue ) { diff --git a/src/main/java/com/thoroldvix/economatic/search/PredicateBuilder.java b/src/main/java/com/thoroldvix/economatic/search/PredicateBuilder.java index b902e342..919a0323 100644 --- a/src/main/java/com/thoroldvix/economatic/search/PredicateBuilder.java +++ b/src/main/java/com/thoroldvix/economatic/search/PredicateBuilder.java @@ -1,7 +1,7 @@ package com.thoroldvix.economatic.search; -import com.thoroldvix.economatic.search.factories.PredicateFactoryProvider; import com.thoroldvix.economatic.search.factories.PredicateFactory; +import com.thoroldvix.economatic.search.factories.PredicateFactoryProvider; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; diff --git a/src/main/java/com/thoroldvix/economatic/search/SearchRequest.java b/src/main/java/com/thoroldvix/economatic/search/SearchRequest.java index 0e8503e3..d38a74a6 100644 --- a/src/main/java/com/thoroldvix/economatic/search/SearchRequest.java +++ b/src/main/java/com/thoroldvix/economatic/search/SearchRequest.java @@ -16,6 +16,7 @@ public record SearchRequest( @Schema(description = "Global operator for combining search criteria", allowableValues = {"AND", "OR", "NOT"}) GlobalOperator globalOperator ) { + public enum GlobalOperator { AND, OR, NOT } diff --git a/src/main/java/com/thoroldvix/economatic/search/SpecificationBuilder.java b/src/main/java/com/thoroldvix/economatic/search/SpecificationBuilder.java index 6f1a3664..14ea2ac0 100644 --- a/src/main/java/com/thoroldvix/economatic/search/SpecificationBuilder.java +++ b/src/main/java/com/thoroldvix/economatic/search/SpecificationBuilder.java @@ -14,10 +14,10 @@ import static com.thoroldvix.economatic.util.ValidationUtils.notEmpty; - public class SpecificationBuilder { - private SpecificationBuilder() {} + private SpecificationBuilder() { + } public static Specification from(SearchRequest request) { notEmpty(request.searchCriteria(), diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/AfterOrEqualsPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/AfterOrEqualsPredicateFactory.java index 47bdccec..403e8632 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/AfterOrEqualsPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/AfterOrEqualsPredicateFactory.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; class AfterOrEqualsPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/AfterPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/AfterPredicateFactory.java index d0800f4f..8ec0440f 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/AfterPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/AfterPredicateFactory.java @@ -7,9 +7,10 @@ import java.time.LocalDateTime; class AfterPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { - Class columnType = columnPath.getJavaType(); + Class columnType = columnPath.getJavaType(); if (columnType.equals(LocalDateTime.class)) { return cb.greaterThan(columnPath.as(LocalDateTime.class), LocalDateTime.parse(value, DATE_TIME_FORMATTER)); } diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/BeforeOrEqualsPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/BeforeOrEqualsPredicateFactory.java index caeb8023..46e7525e 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/BeforeOrEqualsPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/BeforeOrEqualsPredicateFactory.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; class BeforeOrEqualsPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/BeforePredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/BeforePredicateFactory.java index 6fc15aad..35378c85 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/BeforePredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/BeforePredicateFactory.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; class BeforePredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/BetweenDateTimePredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/BetweenDateTimePredicateFactory.java index a172ced9..9dd3da52 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/BetweenDateTimePredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/BetweenDateTimePredicateFactory.java @@ -9,15 +9,6 @@ class BetweenDateTimePredicateFactory extends AbstractBetweenPredicateFactory { - private static Predicate getLocalDateTimeBetweenPredicate(CriteriaBuilder cb, Path columnPath, String lowerBound, String upperBound) { - LocalDateTime start = LocalDateTime.parse(lowerBound, DATE_TIME_FORMATTER); - LocalDateTime end = LocalDateTime.parse(upperBound, DATE_TIME_FORMATTER); - if (end.getHour() == 0 && end.getMinute() == 0 && end.getSecond() == 0) { - return cb.between(columnPath.as(LocalDateTime.class), start, end.with(LocalTime.MAX)); - } - return cb.between(columnPath.as(LocalDateTime.class), start, end); - } - @Override Predicate buildPredicate(CriteriaBuilder cb, Path columnPath, String lowerBound, String upperBound) { Class columnType = columnPath.getJavaType(); @@ -26,4 +17,13 @@ Predicate buildPredicate(CriteriaBuilder cb, Path columnPath, String lowerBou } throw new IllegalArgumentException("Invalid operation: BETWEEN_DATE_TIME is only applicable to date-time column types."); } + + private static Predicate getLocalDateTimeBetweenPredicate(CriteriaBuilder cb, Path columnPath, String lowerBound, String upperBound) { + LocalDateTime start = LocalDateTime.parse(lowerBound, DATE_TIME_FORMATTER); + LocalDateTime end = LocalDateTime.parse(upperBound, DATE_TIME_FORMATTER); + if (end.getHour() == 0 && end.getMinute() == 0 && end.getSecond() == 0) { + return cb.between(columnPath.as(LocalDateTime.class), start, end.with(LocalTime.MAX)); + } + return cb.between(columnPath.as(LocalDateTime.class), start, end); + } } \ No newline at end of file diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/BetweenNumericPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/BetweenNumericPredicateFactory.java index 32484d8d..8fa4aebf 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/BetweenNumericPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/BetweenNumericPredicateFactory.java @@ -6,6 +6,18 @@ class BetweenNumericPredicateFactory extends AbstractBetweenPredicateFactory { + @Override + Predicate buildPredicate(CriteriaBuilder cb, Path columnPath, String lowerBound, String upperBound) { + Class columnType = columnPath.getJavaType(); + return switch (columnType.getSimpleName()) { + case "Integer" -> getIntegerBetweenPredicate(cb, columnPath, lowerBound, upperBound); + case "Long" -> getLongBetweenPredicate(cb, columnPath, lowerBound, upperBound); + case "Double" -> getDoubleBetweenPredicate(cb, columnPath, lowerBound, upperBound); + default -> + throw new IllegalArgumentException("Invalid operation: BETWEEN_NUMERIC is only applicable to numeric column types."); + }; + } + private static Predicate getDoubleBetweenPredicate(CriteriaBuilder cb, Path columnPath, String lowerBound, String upperBound) { double lowerBoundValue = Double.parseDouble(lowerBound); double upperDoubleValue = Double.parseDouble(upperBound); @@ -24,16 +36,4 @@ private static Predicate getIntegerBetweenPredicate(CriteriaBuilder cb, Path return cb.between(columnPath.as(Integer.class), lowerBoundValue, upperBoundValue); } - - @Override - Predicate buildPredicate(CriteriaBuilder cb, Path columnPath, String lowerBound, String upperBound) { - Class columnType = columnPath.getJavaType(); - return switch (columnType.getSimpleName()) { - case "Integer" -> getIntegerBetweenPredicate(cb, columnPath, lowerBound, upperBound); - case "Long" -> getLongBetweenPredicate(cb, columnPath, lowerBound, upperBound); - case "Double" -> getDoubleBetweenPredicate(cb, columnPath, lowerBound, upperBound); - default -> - throw new IllegalArgumentException("Invalid operation: BETWEEN_NUMERIC is only applicable to numeric column types."); - }; - } } diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/EqualsPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/EqualsPredicateFactory.java index 3afcc490..aad376fd 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/EqualsPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/EqualsPredicateFactory.java @@ -7,13 +7,6 @@ class EqualsPredicateFactory implements PredicateFactory { - private static > int getValueForEnumType(Class enumClass, String value) { - @SuppressWarnings("unchecked") - Class castedEnumClass = (Class) enumClass; - E enumValue = Enum.valueOf(castedEnumClass, value.toUpperCase()); - return enumValue.ordinal(); - } - @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); @@ -23,4 +16,11 @@ public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String val } return cb.equal(columnPath, value); } + + private static > int getValueForEnumType(Class enumClass, String value) { + @SuppressWarnings("unchecked") + Class castedEnumClass = (Class) enumClass; + E enumValue = Enum.valueOf(castedEnumClass, value.toUpperCase()); + return enumValue.ordinal(); + } } \ No newline at end of file diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanOrEqualsPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanOrEqualsPredicateFactory.java index 48747530..1fb50228 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanOrEqualsPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanOrEqualsPredicateFactory.java @@ -5,6 +5,7 @@ import jakarta.persistence.criteria.Predicate; class GreaterThanOrEqualsPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanPredicateFactory.java index 270c1f48..6fc7d94f 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/GreaterThanPredicateFactory.java @@ -5,6 +5,7 @@ import jakarta.persistence.criteria.Predicate; class GreaterThanPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/InPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/InPredicateFactory.java index 6064917f..608f25be 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/InPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/InPredicateFactory.java @@ -7,6 +7,7 @@ import java.util.Arrays; class InPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { String[] split = value.split(","); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/LessThanOrEqualsPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/LessThanOrEqualsPredicateFactory.java index 8e42e3f3..3631662f 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/LessThanOrEqualsPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/LessThanOrEqualsPredicateFactory.java @@ -5,6 +5,7 @@ import jakarta.persistence.criteria.Predicate; class LessThanOrEqualsPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/LessThanPredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/LessThanPredicateFactory.java index 6b04f179..7187f6d0 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/LessThanPredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/LessThanPredicateFactory.java @@ -5,6 +5,7 @@ import jakarta.persistence.criteria.Predicate; class LessThanPredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { Class columnType = columnPath.getJavaType(); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/LikePredicateFactory.java b/src/main/java/com/thoroldvix/economatic/search/factories/LikePredicateFactory.java index 53ee58e7..b82bd9eb 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/LikePredicateFactory.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/LikePredicateFactory.java @@ -5,6 +5,7 @@ import jakarta.persistence.criteria.Predicate; class LikePredicateFactory implements PredicateFactory { + @Override public Predicate getPredicate(CriteriaBuilder cb, Path columnPath, String value) { return cb.like(columnPath.as(String.class), "%" + value + "%"); diff --git a/src/main/java/com/thoroldvix/economatic/search/factories/PredicateFactoryProvider.java b/src/main/java/com/thoroldvix/economatic/search/factories/PredicateFactoryProvider.java index 4d5b4c44..77ad8926 100644 --- a/src/main/java/com/thoroldvix/economatic/search/factories/PredicateFactoryProvider.java +++ b/src/main/java/com/thoroldvix/economatic/search/factories/PredicateFactoryProvider.java @@ -7,6 +7,7 @@ import java.util.Optional; public final class PredicateFactoryProvider { + private static final Map FACTORIES_MAP = new EnumMap<>(SearchCriteria.Operation.class); static { @@ -26,7 +27,8 @@ public final class PredicateFactoryProvider { FACTORIES_MAP.put(SearchCriteria.Operation.BETWEEN_DATE_TIME, new BetweenDateTimePredicateFactory()); } - private PredicateFactoryProvider(){} + private PredicateFactoryProvider() { + } public static PredicateFactory getPredicateFactory(SearchCriteria searchCriteria) { return Optional.ofNullable(FACTORIES_MAP.get(searchCriteria.operation())) diff --git a/src/main/java/com/thoroldvix/economatic/server/Faction.java b/src/main/java/com/thoroldvix/economatic/server/Faction.java index 47abd477..36b9d862 100644 --- a/src/main/java/com/thoroldvix/economatic/server/Faction.java +++ b/src/main/java/com/thoroldvix/economatic/server/Faction.java @@ -3,6 +3,7 @@ public enum Faction { ALLIANCE, HORDE; + @Override public String toString() { return name().charAt(0) + name().substring(1).toLowerCase(); diff --git a/src/main/java/com/thoroldvix/economatic/server/ServerListResponse.java b/src/main/java/com/thoroldvix/economatic/server/ServerListResponse.java index b8766208..188d5825 100644 --- a/src/main/java/com/thoroldvix/economatic/server/ServerListResponse.java +++ b/src/main/java/com/thoroldvix/economatic/server/ServerListResponse.java @@ -8,4 +8,5 @@ public record ServerListResponse( List servers ) { + } diff --git a/src/main/java/com/thoroldvix/economatic/server/ServerNotFoundException.java b/src/main/java/com/thoroldvix/economatic/server/ServerNotFoundException.java index fcb32dea..9e3f1f1f 100644 --- a/src/main/java/com/thoroldvix/economatic/server/ServerNotFoundException.java +++ b/src/main/java/com/thoroldvix/economatic/server/ServerNotFoundException.java @@ -4,6 +4,7 @@ import com.thoroldvix.economatic.error.NotFoundException; public class ServerNotFoundException extends NotFoundException { + public ServerNotFoundException(String s) { super(s); } diff --git a/src/main/java/com/thoroldvix/economatic/server/ServerServiceImpl.java b/src/main/java/com/thoroldvix/economatic/server/ServerServiceImpl.java index 0a841789..93e8c79c 100644 --- a/src/main/java/com/thoroldvix/economatic/server/ServerServiceImpl.java +++ b/src/main/java/com/thoroldvix/economatic/server/ServerServiceImpl.java @@ -1,9 +1,9 @@ package com.thoroldvix.economatic.server; import com.thoroldvix.economatic.error.ErrorMessages; +import com.thoroldvix.economatic.search.SearchRequest; import com.thoroldvix.economatic.search.SpecificationBuilder; import com.thoroldvix.economatic.util.StringEnumConverter; -import com.thoroldvix.economatic.search.SearchRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; diff --git a/src/main/java/com/thoroldvix/economatic/server/ServerType.java b/src/main/java/com/thoroldvix/economatic/server/ServerType.java index c3652cfb..f2959d65 100644 --- a/src/main/java/com/thoroldvix/economatic/server/ServerType.java +++ b/src/main/java/com/thoroldvix/economatic/server/ServerType.java @@ -5,6 +5,7 @@ public enum ServerType { PVP, RP, PVP_RP; + @Override public String toString() { String typeName = this.name().replace("_", " "); diff --git a/src/main/java/com/thoroldvix/economatic/stats/StatsProjection.java b/src/main/java/com/thoroldvix/economatic/stats/StatsProjection.java index 6956f622..dbabdfef 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/StatsProjection.java +++ b/src/main/java/com/thoroldvix/economatic/stats/StatsProjection.java @@ -1,6 +1,7 @@ package com.thoroldvix.economatic.stats; public interface StatsProjection { + Number getMean(); Number getMaxId(); diff --git a/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatMapper.java b/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatMapper.java index 7402dcd9..cec3e0db 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatMapper.java +++ b/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatMapper.java @@ -12,6 +12,7 @@ @Mapper(componentModel = MappingConstants.ComponentModel.SPRING) interface GoldPriceStatMapper { + int SCALE = 6; RoundingMode ROUNDING_MODE = RoundingMode.HALF_UP; diff --git a/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatRepository.java b/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatRepository.java index d873e8d1..e9ed2fe5 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatRepository.java +++ b/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatRepository.java @@ -10,6 +10,7 @@ @Repository interface GoldPriceStatRepository extends JpaRepository { + String STAT_SQL = """ SELECT (SELECT CAST(AVG(gp.value) AS DECIMAL(7, 6)) FROM gold_prices gp) AS mean, @@ -20,37 +21,37 @@ interface GoldPriceStatRepository extends JpaRepository { """; @Query(value = """ - WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at - FROM gold_price gp - JOIN server s ON s.id = gp.server_id - WHERE s.region = ?1 and gp.updated_at >= ?2 and gp.updated_at <= ?3 - ) - """ + STAT_SQL, nativeQuery = true) + WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at + FROM gold_price gp + JOIN server s ON s.id = gp.server_id + WHERE s.region = ?1 and gp.updated_at >= ?2 and gp.updated_at <= ?3 + ) + """ + STAT_SQL, nativeQuery = true) StatsProjection findForRegion(int region, LocalDateTime start, LocalDateTime end); @Query(value = """ - WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at - FROM gold_price gp - JOIN server s ON s.id = gp.server_id - WHERE s.faction = ?1 and gp.updated_at >= ?2 and gp.updated_at <= ?3 - ) - """ + STAT_SQL, nativeQuery = true) + WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at + FROM gold_price gp + JOIN server s ON s.id = gp.server_id + WHERE s.faction = ?1 and gp.updated_at >= ?2 and gp.updated_at <= ?3 + ) + """ + STAT_SQL, nativeQuery = true) StatsProjection findForFaction(int faction, LocalDateTime start, LocalDateTime end); @Query(value = """ - WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at - FROM gold_price gp - WHERE gp.updated_at >= ?1 AND gp.updated_at <= ?2 - ) - """ + STAT_SQL, nativeQuery = true) + WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at + FROM gold_price gp + WHERE gp.updated_at >= ?1 AND gp.updated_at <= ?2 + ) + """ + STAT_SQL, nativeQuery = true) StatsProjection findStatsForAll(LocalDateTime start, LocalDateTime end); @Query(value = """ - WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at - FROM gold_price gp - WHERE gp.server_id = ?1 and gp.updated_at >= ?2 and gp.updated_at <= ?3 - ) - """ + STAT_SQL, nativeQuery = true) + WITH gold_prices AS (SELECT gp.value, gp.id, gp.updated_at + FROM gold_price gp + WHERE gp.server_id = ?1 and gp.updated_at >= ?2 and gp.updated_at <= ?3 + ) + """ + STAT_SQL, nativeQuery = true) StatsProjection findStatsForServer(int serverId, LocalDateTime start, LocalDateTime end); } diff --git a/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImpl.java b/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImpl.java index 42e00b41..d900beee 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImpl.java +++ b/src/main/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImpl.java @@ -1,5 +1,6 @@ package com.thoroldvix.economatic.stats.goldprice; +import com.thoroldvix.economatic.dto.TimeRange; import com.thoroldvix.economatic.error.StatisticsNotFoundException; import com.thoroldvix.economatic.goldprice.GoldPriceResponse; import com.thoroldvix.economatic.goldprice.GoldPriceService; @@ -7,9 +8,8 @@ import com.thoroldvix.economatic.server.Region; import com.thoroldvix.economatic.server.ServerResponse; import com.thoroldvix.economatic.server.ServerService; -import com.thoroldvix.economatic.util.StringEnumConverter; -import com.thoroldvix.economatic.dto.TimeRange; import com.thoroldvix.economatic.stats.StatsProjection; +import com.thoroldvix.economatic.util.StringEnumConverter; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @@ -111,7 +111,7 @@ private GoldPriceResponse getMin(StatsProjection goldPriceStat) { return goldPriceServiceImpl.getForId(minId); } - private void validateStatsProjection(StatsProjection statsProjection) { + private void validateStatsProjection(StatsProjection statsProjection) { boolean isInvalid = statsProjection.getMean() == null || statsProjection.getMaxId() == null || statsProjection.getMinId() == null diff --git a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatController.java b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatController.java index 341e051d..f49c0338 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatController.java +++ b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatController.java @@ -82,7 +82,7 @@ public ResponseEntity getStatsForRegion( required = true) @PathVariable String regionName, @Parameter(description = "Range of days to retrieve statistics for", - example = "7") + example = "7") @RequestParam(defaultValue = "7") int timeRange) { var statsForRegion = populationStatServiceImpl.getForRegion(regionName, new TimeRange(timeRange)); diff --git a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatMapper.java b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatMapper.java index 55cb2ac4..6a5b4bf9 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatMapper.java +++ b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatMapper.java @@ -26,6 +26,4 @@ default PopulationStatResponse toResponse(StatsProjection statProj, PopulationRe } - - } diff --git a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatRepository.java b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatRepository.java index 30a60fbf..41d97a10 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatRepository.java +++ b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatRepository.java @@ -20,37 +20,37 @@ interface PopulationStatRepository extends JpaRepository { (SELECT COUNT(fp.id) FROM filteredPopulations fp) AS count; """; - @Query(value = """ - WITH filteredPopulations AS (SELECT p.value, p.id, p.updated_at - FROM population p - JOIN server s ON s.id = p.server_id - WHERE s.region = ?1 AND p.updated_at >= ?2 and p.updated_at <= ?3 and p.value > 0) - """ + STAT_SQL, nativeQuery = true) - StatsProjection findStatsByRegion(int region, LocalDateTime start, LocalDateTime end); + @Query(value = """ + WITH filteredPopulations AS (SELECT p.value, p.id, p.updated_at + FROM population p + JOIN server s ON s.id = p.server_id + WHERE s.region = ?1 AND p.updated_at >= ?2 and p.updated_at <= ?3 and p.value > 0) + """ + STAT_SQL, nativeQuery = true) + StatsProjection findStatsByRegion(int region, LocalDateTime start, LocalDateTime end); @Query(value = """ - WITH filteredPopulations AS ( - SELECT p.value, p.id, p.updated_at - FROM population p - WHERE p.updated_at >= ?1 AND updated_at <= ?2 AND p.value > 0) - """ + STAT_SQL, nativeQuery = true) + WITH filteredPopulations AS ( + SELECT p.value, p.id, p.updated_at + FROM population p + WHERE p.updated_at >= ?1 AND updated_at <= ?2 AND p.value > 0) + """ + STAT_SQL, nativeQuery = true) StatsProjection findForTimeRange(LocalDateTime start, LocalDateTime end); @Query(value = """ - WITH filteredPopulations AS ( - SELECT p.value, p.id, p.updated_at - FROM population p - WHERE p.server_id = ?1 AND p.updated_at >= ?2 and p.updated_at <= ?3 and p.value > 0) - """ + STAT_SQL, nativeQuery = true) + WITH filteredPopulations AS ( + SELECT p.value, p.id, p.updated_at + FROM population p + WHERE p.server_id = ?1 AND p.updated_at >= ?2 and p.updated_at <= ?3 and p.value > 0) + """ + STAT_SQL, nativeQuery = true) StatsProjection findStatsByServer(int serverId, LocalDateTime start, LocalDateTime end); @Query(value = """ - WITH filteredPopulations AS ( - SELECT p.value, p.id, p.updated_at - FROM population p - JOIN server s ON s.id = p.server_id - WHERE s.faction = ?1 AND p.updated_at >= ?2 and p.updated_at <= ?3 and p.value > 0) - """ + STAT_SQL, nativeQuery = true) + WITH filteredPopulations AS ( + SELECT p.value, p.id, p.updated_at + FROM population p + JOIN server s ON s.id = p.server_id + WHERE s.faction = ?1 AND p.updated_at >= ?2 and p.updated_at <= ?3 and p.value > 0) + """ + STAT_SQL, nativeQuery = true) StatsProjection findStatsByFaction(int faction, LocalDateTime start, LocalDateTime end); diff --git a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatResponse.java b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatResponse.java index 7d3253c8..e6c5cc7d 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatResponse.java +++ b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatResponse.java @@ -11,4 +11,5 @@ public record PopulationStatResponse( PopulationResponse maximum, long count ) { + } diff --git a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatServiceImpl.java b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatServiceImpl.java index d454dd47..51509ce8 100644 --- a/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatServiceImpl.java +++ b/src/main/java/com/thoroldvix/economatic/stats/population/PopulationStatServiceImpl.java @@ -1,5 +1,6 @@ package com.thoroldvix.economatic.stats.population; +import com.thoroldvix.economatic.dto.TimeRange; import com.thoroldvix.economatic.error.StatisticsNotFoundException; import com.thoroldvix.economatic.population.PopulationResponse; import com.thoroldvix.economatic.population.PopulationService; @@ -7,9 +8,8 @@ import com.thoroldvix.economatic.server.Region; import com.thoroldvix.economatic.server.ServerResponse; import com.thoroldvix.economatic.server.ServerService; -import com.thoroldvix.economatic.util.StringEnumConverter; -import com.thoroldvix.economatic.dto.TimeRange; import com.thoroldvix.economatic.stats.StatsProjection; +import com.thoroldvix.economatic.util.StringEnumConverter; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,7 +30,6 @@ public class PopulationStatServiceImpl implements PopulationStatService { private final PopulationService populationServiceImpl; - @Override public PopulationStatResponse getForServer(String serverIdentifier, TimeRange timeRange) { notEmpty(serverIdentifier, SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY); @@ -110,7 +109,7 @@ private PopulationStatResponse getStatResponse(StatsProjection statsProjection) return populationStatMapper.toResponse(statsProjection, min, max); } - private void validateStatsProjection(StatsProjection statsProjection) { + private void validateStatsProjection(StatsProjection statsProjection) { boolean isInvalid = statsProjection.getMean() == null || statsProjection.getMaxId() == null || statsProjection.getMinId() == null diff --git a/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryProjection.java b/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryProjection.java index f61df202..c94da51c 100644 --- a/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryProjection.java +++ b/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryProjection.java @@ -1,6 +1,7 @@ package com.thoroldvix.economatic.summary.item; interface ItemSummaryProjection { + int getCommon(); int getUncommon(); diff --git a/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryResponse.java b/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryResponse.java index ee3d08d5..4f23977e 100644 --- a/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryResponse.java +++ b/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryResponse.java @@ -6,6 +6,7 @@ public record ItemSummaryResponse( Summary summary ) { + @Builder record Summary( Quality quality, @@ -16,6 +17,7 @@ record Summary( int total ) { + } @Builder @@ -26,6 +28,7 @@ record Quality( int epic, int legendary ) { + } @Builder @@ -60,23 +63,24 @@ record Slot( int quiver, int relic ) { + } @Builder record Type(int consumable, - int container, - int weapon, - int gem, - int armor, - int reagent, - int projectile, - int tradeGoods, - int recipe, - int quiver, - int quest, - int key, - int miscellaneous, - int glyph + int container, + int weapon, + int gem, + int armor, + int reagent, + int projectile, + int tradeGoods, + int recipe, + int quiver, + int quest, + int key, + int miscellaneous, + int glyph ) { } diff --git a/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryService.java b/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryService.java index 31f1cbf8..1a438d55 100644 --- a/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryService.java +++ b/src/main/java/com/thoroldvix/economatic/summary/item/ItemSummaryService.java @@ -1,5 +1,6 @@ package com.thoroldvix.economatic.summary.item; public interface ItemSummaryService { + ItemSummaryResponse getSummary(); } diff --git a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryProjection.java b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryProjection.java index 7b44c87a..b0a20b73 100644 --- a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryProjection.java +++ b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryProjection.java @@ -1,6 +1,7 @@ package com.thoroldvix.economatic.summary.server; interface ServerSummaryProjection { + int getAlliance(); int getHorde(); diff --git a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryRepository.java b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryRepository.java index e4bd14fb..046dd9f0 100644 --- a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryRepository.java +++ b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryRepository.java @@ -8,7 +8,7 @@ @Repository interface ServerSummaryRepository extends JpaRepository { - @Query(value = """ + @Query(value = """ SELECT SUM(CASE WHEN faction = 0 THEN 1 ELSE 0 END) AS alliance, SUM(CASE WHEN faction = 1 THEN 1 ELSE 0 END) AS horde, SUM(CASE WHEN region = 0 THEN 1 ELSE 0 END) / 2 AS eu, diff --git a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryResponse.java b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryResponse.java index c5abc9c2..5b86b677 100644 --- a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryResponse.java +++ b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryResponse.java @@ -6,6 +6,7 @@ public record ServerSummaryResponse( Summary summary ) { + @Builder public record Summary( Faction faction, @@ -14,6 +15,7 @@ public record Summary( Locale locale, int total ) { + } @Builder @@ -21,6 +23,7 @@ public record Faction( int alliance, int horde ) { + } @Builder @@ -28,6 +31,7 @@ public record Region( int eu, int us ) { + } @Builder @@ -37,6 +41,7 @@ public record Type( int pvpRp, int rp ) { + } @Builder @@ -48,5 +53,6 @@ public record Locale( int frFR, int ruRU ) { + } } diff --git a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryService.java b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryService.java index 64dec781..88087e25 100644 --- a/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryService.java +++ b/src/main/java/com/thoroldvix/economatic/summary/server/ServerSummaryService.java @@ -1,5 +1,6 @@ package com.thoroldvix.economatic.summary.server; public interface ServerSummaryService { + ServerSummaryResponse getSummary(); } diff --git a/src/main/java/com/thoroldvix/economatic/util/StringEnumConverter.java b/src/main/java/com/thoroldvix/economatic/util/StringEnumConverter.java index b2e44391..dc775b90 100644 --- a/src/main/java/com/thoroldvix/economatic/util/StringEnumConverter.java +++ b/src/main/java/com/thoroldvix/economatic/util/StringEnumConverter.java @@ -7,7 +7,8 @@ public final class StringEnumConverter { - private StringEnumConverter() {} + private StringEnumConverter() { + } public static > T fromString(String str, Class enumClass) { if (!isNonEmptyString(str)) { diff --git a/src/main/java/com/thoroldvix/economatic/util/Utils.java b/src/main/java/com/thoroldvix/economatic/util/Utils.java index aa6e4912..c2fae601 100644 --- a/src/main/java/com/thoroldvix/economatic/util/Utils.java +++ b/src/main/java/com/thoroldvix/economatic/util/Utils.java @@ -5,9 +5,10 @@ public final class Utils { - private Utils() {} + private Utils() { + } - public static long elapsedTimeInMillis(Instant start) { + public static long elapsedTimeInMillis(Instant start) { return Duration.between(start, Instant.now()).toMillis(); } } diff --git a/src/main/java/com/thoroldvix/economatic/util/ValidationUtils.java b/src/main/java/com/thoroldvix/economatic/util/ValidationUtils.java index 90bef5fc..50c05446 100644 --- a/src/main/java/com/thoroldvix/economatic/util/ValidationUtils.java +++ b/src/main/java/com/thoroldvix/economatic/util/ValidationUtils.java @@ -44,7 +44,7 @@ public static boolean isCollectionEmpty(Collection collection) { } - public static T checkNullAndGet(Supplier supplier) { + public static T checkNullAndGet(Supplier supplier) { try { return supplier.get(); } catch (NullPointerException e) { diff --git a/src/test/java/com/thoroldvix/economatic/deal/BaseItemDealTest.java b/src/test/java/com/thoroldvix/economatic/deal/BaseItemDealTest.java index 6663675a..0182222d 100644 --- a/src/test/java/com/thoroldvix/economatic/deal/BaseItemDealTest.java +++ b/src/test/java/com/thoroldvix/economatic/deal/BaseItemDealTest.java @@ -11,6 +11,7 @@ @ActiveProfiles("test") @ExtendWith(MockitoExtension.class) public abstract class BaseItemDealTest { + protected static final int MINIMUM_ITEM_QUANTITY = 3; protected static final int MINIMUM_ITEM_QUALITY = 0; protected static final int ITEM_LIMIT = 5; diff --git a/src/test/java/com/thoroldvix/economatic/deal/ItemDealsRepositoryTest.java b/src/test/java/com/thoroldvix/economatic/deal/ItemDealsRepositoryTest.java index d848b402..15702e6f 100644 --- a/src/test/java/com/thoroldvix/economatic/deal/ItemDealsRepositoryTest.java +++ b/src/test/java/com/thoroldvix/economatic/deal/ItemDealsRepositoryTest.java @@ -98,7 +98,8 @@ void findDealsForServer_returnsCorrectDeals_forServerId() { .extracting(ITEM_DEALS_PROJECTION_FIELDS) .containsExactly(itemPrice2Tuple); } - @Test + + @Test void findDealsForServer_returnsDealsOrderedByDiscountPercentage() { List dealsForServer = itemDealsRepository.findDealsForServer(1, 1, 0, 5); assertThat(dealsForServer) diff --git a/src/test/java/com/thoroldvix/economatic/deal/ItemDealsServiceImplTest.java b/src/test/java/com/thoroldvix/economatic/deal/ItemDealsServiceImplTest.java index e4a01b2e..0931c931 100644 --- a/src/test/java/com/thoroldvix/economatic/deal/ItemDealsServiceImplTest.java +++ b/src/test/java/com/thoroldvix/economatic/deal/ItemDealsServiceImplTest.java @@ -15,6 +15,7 @@ class ItemDealsServiceImplTest extends BaseItemDealTest { + @Mock private ServerService serverService; @Mock diff --git a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceControllerTest.java b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceControllerTest.java index ec5f460a..7c62134f 100644 --- a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceControllerTest.java +++ b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceControllerTest.java @@ -1,11 +1,11 @@ package com.thoroldvix.economatic.goldprice; import com.fasterxml.jackson.databind.ObjectMapper; -import com.thoroldvix.economatic.server.Faction; -import com.thoroldvix.economatic.server.Region; import com.thoroldvix.economatic.dto.PaginationInfo; import com.thoroldvix.economatic.search.SearchCriteria; import com.thoroldvix.economatic.search.SearchRequest; +import com.thoroldvix.economatic.server.Faction; +import com.thoroldvix.economatic.server.Region; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -34,9 +34,9 @@ class GoldPriceControllerTest { private static final String GOLD_PRICE_API_ENDPOINT = "/wow-classic/api/v1/servers/prices"; - private GoldPriceResponse goldPriceResponse1; + private GoldPriceResponse goldPriceResponse1; - private GoldPriceResponse goldPriceResponse2; + private GoldPriceResponse goldPriceResponse2; private GoldPriceResponse goldPriceResponse3; diff --git a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceDataInitializer.java b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceDataInitializer.java index 5be23a5d..721d4243 100644 --- a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceDataInitializer.java +++ b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceDataInitializer.java @@ -18,6 +18,7 @@ @ActiveProfiles(profiles = {"test", "integration"}) abstract class GoldPriceDataInitializer implements PostgresqlContainerInitializer { + protected final static LocalDateTime UPDATE_DATE = LocalDateTime.now(); protected GoldPrice goldPrice1; protected GoldPrice goldPrice2; @@ -80,7 +81,6 @@ void setup() { } - private GoldPrice buildGoldPrice(double value, LocalDateTime updateDate, Server server) { return GoldPrice.builder() .value(BigDecimal.valueOf(value)) diff --git a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceMapperTest.java b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceMapperTest.java index 612d5c60..936e78ee 100644 --- a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceMapperTest.java +++ b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceMapperTest.java @@ -1,10 +1,10 @@ package com.thoroldvix.economatic.goldprice; +import com.thoroldvix.economatic.dto.PaginationInfo; import com.thoroldvix.economatic.server.Faction; import com.thoroldvix.economatic.server.Region; import com.thoroldvix.economatic.server.Server; import com.thoroldvix.economatic.server.ServerType; -import com.thoroldvix.economatic.dto.PaginationInfo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; diff --git a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImplTest.java b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImplTest.java index 934adddb..1c441407 100644 --- a/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImplTest.java +++ b/src/test/java/com/thoroldvix/economatic/goldprice/GoldPriceServiceImplTest.java @@ -1,10 +1,10 @@ package com.thoroldvix.economatic.goldprice; -import com.thoroldvix.economatic.server.*; import com.thoroldvix.economatic.dto.PaginationInfo; +import com.thoroldvix.economatic.dto.TimeRange; import com.thoroldvix.economatic.search.SearchCriteria; import com.thoroldvix.economatic.search.SearchRequest; -import com.thoroldvix.economatic.dto.TimeRange; +import com.thoroldvix.economatic.server.*; import jakarta.validation.constraints.NotNull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -38,6 +38,7 @@ @ActiveProfiles("test") @ExtendWith(MockitoExtension.class) class GoldPriceServiceImplTest { + public static final String SERVER_IDENTIFIER_CANNOT_BE_NULL_OR_EMPTY = "Server identifier cannot be null or empty"; private static final LocalDateTime UPDATE_DATE = LocalDateTime.now(); public static final String PAGEABLE_CANNOT_BE_NULL = "Pageable cannot be null"; diff --git a/src/test/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImplTest.java b/src/test/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImplTest.java index 293fce61..ae7647dc 100644 --- a/src/test/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImplTest.java +++ b/src/test/java/com/thoroldvix/economatic/stats/goldprice/GoldPriceStatServiceImplTest.java @@ -1,5 +1,6 @@ package com.thoroldvix.economatic.stats.goldprice; +import com.thoroldvix.economatic.dto.TimeRange; import com.thoroldvix.economatic.error.StatisticsNotFoundException; import com.thoroldvix.economatic.goldprice.GoldPriceResponse; import com.thoroldvix.economatic.goldprice.GoldPriceService; @@ -7,7 +8,6 @@ import com.thoroldvix.economatic.server.Region; import com.thoroldvix.economatic.server.ServerResponse; import com.thoroldvix.economatic.server.ServerService; -import com.thoroldvix.economatic.dto.TimeRange; import com.thoroldvix.economatic.stats.StatsProjection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -29,6 +29,7 @@ @ActiveProfiles("test") @ExtendWith(MockitoExtension.class) class GoldPriceStatServiceImplTest { + @Mock private ServerService serverService; @Mock @@ -263,7 +264,7 @@ void getForAll_returnsCorrectGoldPriceStatResponse() { assertThat(actual).isEqualTo(expectedResponse); } - @Test + @Test void getForAll_throwsNullPointerException_whenTimeRangeIsNull() { assertThatThrownBy(() -> goldPriceStatServiceImpl.getForAll(null)) .isInstanceOf(NullPointerException.class); diff --git a/src/test/java/com/thoroldvix/economatic/util/ValidationUtilsTest.java b/src/test/java/com/thoroldvix/economatic/util/ValidationUtilsTest.java index 70565ab1..a249aaea 100644 --- a/src/test/java/com/thoroldvix/economatic/util/ValidationUtilsTest.java +++ b/src/test/java/com/thoroldvix/economatic/util/ValidationUtilsTest.java @@ -23,11 +23,11 @@ void notEmpty_collection() { @Test void notEmpty_array() { - String[] nonEmptyArray = new String[] {"a", "b", "c"}; + String[] nonEmptyArray = new String[]{"a", "b", "c"}; assertThatCode(() -> ValidationUtils.notEmpty(nonEmptyArray, () -> new IllegalArgumentException("Array should not be empty"))) .doesNotThrowAnyException(); - String[] emptyArray = new String[] {}; + String[] emptyArray = new String[]{}; assertThatThrownBy(() -> ValidationUtils.notEmpty(emptyArray, () -> new IllegalArgumentException("Array should not be empty"))) .isInstanceOf(IllegalArgumentException.class); }