From 72fdc2077e155e920059eb47d14d539567e7542e Mon Sep 17 00:00:00 2001 From: nntthuy-axonivy Date: Fri, 5 Jul 2024 12:00:58 +0700 Subject: [PATCH] Fix conflicts --- .../assembler/ProductModelAssembler.java | 11 +-- .../market/constants/GitHubConstants.java | 1 + .../market/controller/ProductController.java | 12 +-- .../com/axonivy/market/entity/Product.java | 8 +- .../market/factory/ProductFactory.java | 24 ++++- .../com/axonivy/market/github/model/Meta.java | 5 +- .../impl/GHAxonIvyMarketRepoServiceImpl.java | 9 +- .../market/repository/ProductRepository.java | 8 +- .../market/service/ProductService.java | 2 +- .../service/impl/ProductServiceImpl.java | 97 +++++++++---------- 10 files changed, 99 insertions(+), 78 deletions(-) diff --git a/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductModelAssembler.java b/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductModelAssembler.java index a7f416edb..eabcf5da9 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductModelAssembler.java +++ b/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductModelAssembler.java @@ -20,20 +20,19 @@ public ProductModelAssembler() { @Override public ProductModel toModel(Product product) { ProductModel resource = new ProductModel(); - resource.add( - linkTo(methodOn(ProductDetailsController.class).findProductDetails(product.getId(), product.getType())) - .withSelfRel()); + resource.add(linkTo(methodOn(ProductDetailsController.class).findProductDetails(product.getId(), product.getType())) + .withSelfRel()); return createResource(resource, product); } public ProductModel createResource(ProductModel model, Product product) { model.setId(product.getId()); - model.setName(product.getName()); - model.setShortDescription(product.getShortDescription()); + model.setNames(product.getNames()); + model.setShortDescriptions(product.getShortDescriptions()); model.setType(product.getType()); model.setTags(product.getTags()); model.setLogoUrl(product.getLogoUrl()); return model; } -} +} \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/GitHubConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/GitHubConstants.java index c03c69f65..1b8a73682 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/constants/GitHubConstants.java +++ b/marketplace-service/src/main/java/com/axonivy/market/constants/GitHubConstants.java @@ -8,5 +8,6 @@ public class GitHubConstants { public static final String AXONIVY_MARKET_ORGANIZATION_NAME = "axonivy-market"; public static final String AXONIVY_MARKETPLACE_REPO_NAME = "market"; public static final String AXONIVY_MARKETPLACE_PATH = "market"; + public static final String DEFAULT_BRANCH = "feature/MARP-463-Multilingualism-for-Website"; public static final String PRODUCT_JSON_FILE_PATH_FORMAT = "%s/product.json"; } \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java index 55d0444ff..5476f8e3c 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java @@ -35,7 +35,7 @@ public class ProductController { private final PagedResourcesAssembler pagedResourcesAssembler; public ProductController(ProductService service, ProductModelAssembler assembler, - PagedResourcesAssembler pagedResourcesAssembler) { + PagedResourcesAssembler pagedResourcesAssembler) { this.service = service; this.assembler = assembler; this.pagedResourcesAssembler = pagedResourcesAssembler; @@ -44,9 +44,9 @@ public ProductController(ProductService service, ProductModelAssembler assembler @Operation(summary = "Find all products", description = "Be default system will finds product by type as 'all'") @GetMapping() public ResponseEntity> findProducts( - @RequestParam(required = true, name = "type") String type, - @RequestParam(required = false, name = "keyword") String keyword, - @RequestParam(required = true, name = "language") String language, Pageable pageable) { + @RequestParam(required = true, name = "type") String type, + @RequestParam(required = false, name = "keyword") String keyword, + @RequestParam(required = true, name = "language") String language, Pageable pageable) { Page results = service.findProducts(type, keyword, language, pageable); if (results.isEmpty()) { return generateEmptyPagedModel(); @@ -76,7 +76,7 @@ public ResponseEntity syncProducts() { @SuppressWarnings("unchecked") private ResponseEntity> generateEmptyPagedModel() { var emptyPagedModel = (PagedModel) pagedResourcesAssembler - .toEmptyModel(Page.empty(), ProductModel.class); + .toEmptyModel(Page.empty(), ProductModel.class); return new ResponseEntity<>(emptyPagedModel, HttpStatus.OK); } -} +} \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/entity/Product.java b/marketplace-service/src/main/java/com/axonivy/market/entity/Product.java index 71410fb0a..30f4a0d56 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/entity/Product.java +++ b/marketplace-service/src/main/java/com/axonivy/market/entity/Product.java @@ -6,6 +6,8 @@ import java.util.Date; import java.util.List; +import com.axonivy.market.model.MultilingualismValue; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -30,9 +32,11 @@ public class Product implements Serializable { @Id private String id; private String marketDirectory; - private String name; + @JsonProperty + private MultilingualismValue names; private String version; - private String shortDescription; + @JsonProperty + private MultilingualismValue shortDescriptions; private String logoUrl; private Boolean listed; private String type; diff --git a/marketplace-service/src/main/java/com/axonivy/market/factory/ProductFactory.java b/marketplace-service/src/main/java/com/axonivy/market/factory/ProductFactory.java index 8f66bb3e3..0a6acb2d8 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/factory/ProductFactory.java +++ b/marketplace-service/src/main/java/com/axonivy/market/factory/ProductFactory.java @@ -5,10 +5,14 @@ import static com.axonivy.market.constants.MetaConstants.*; import static org.apache.commons.lang3.StringUtils.EMPTY; +import com.axonivy.market.enums.Language; import com.axonivy.market.github.util.GitHubUtils; +import com.axonivy.market.model.DisplayValue; +import com.axonivy.market.model.MultilingualismValue; import org.apache.commons.lang3.BooleanUtils; import java.io.IOException; +import java.util.List; import org.apache.commons.lang3.StringUtils; import org.kohsuke.github.GHContent; @@ -20,6 +24,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.log4j.Log4j2; +import org.springframework.util.CollectionUtils; @Log4j2 @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -51,13 +56,13 @@ public static Product mappingByMetaJSONFile(Product product, GHContent ghContent } product.setId(meta.getId()); - product.setName(meta.getName()); + product.setNames(mappingMultilingualismValueByMetaJSONFile(meta.getNames())); product.setMarketDirectory(extractParentDirectory(ghContent)); product.setListed(meta.getListed()); product.setType(meta.getType()); product.setTags(meta.getTags()); product.setVersion(meta.getVersion()); - product.setShortDescription(meta.getDescription()); + product.setShortDescriptions(mappingMultilingualismValueByMetaJSONFile(meta.getDescriptions())); product.setVendor(StringUtils.isBlank(meta.getVendor()) ? DEFAULT_VENDOR_NAME : meta.getVendor()); product.setVendorUrl( StringUtils.isBlank(meta.getVendorUrl()) ? DEFAULT_VENDOR_URL : meta.getVendorUrl()); @@ -73,6 +78,21 @@ public static Product mappingByMetaJSONFile(Product product, GHContent ghContent return product; } + private static MultilingualismValue mappingMultilingualismValueByMetaJSONFile(List list) { + MultilingualismValue value = new MultilingualismValue(); + if (!CollectionUtils.isEmpty(list)) { + for (DisplayValue name : list) { + if (Language.EN.getValue().equalsIgnoreCase(name.getLocale())) { + value.setEn(name.getValue()); + } else if (Language.DE.getValue().equalsIgnoreCase(name.getLocale())) { + value.setDe(name.getValue()); + } + } + } + + return value; + } + private static String extractParentDirectory(GHContent ghContent) { var path = StringUtils.defaultIfEmpty(ghContent.getPath(), EMPTY); return path.replace(ghContent.getName(), EMPTY); diff --git a/marketplace-service/src/main/java/com/axonivy/market/github/model/Meta.java b/marketplace-service/src/main/java/com/axonivy/market/github/model/Meta.java index bca390b03..606ac68a8 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/github/model/Meta.java +++ b/marketplace-service/src/main/java/com/axonivy/market/github/model/Meta.java @@ -2,6 +2,7 @@ import java.util.List; +import com.axonivy.market.model.DisplayValue; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -19,8 +20,8 @@ public class Meta { @JsonProperty("$schema") private String schema; private String id; - private String name; - private String description; + private List names; + private List descriptions; private String type; private String platformReview; private String sourceUrl; diff --git a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyMarketRepoServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyMarketRepoServiceImpl.java index b6e1471c2..00d101ddb 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyMarketRepoServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyMarketRepoServiceImpl.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.Map; -import com.axonivy.market.github.util.GitHubUtils; import org.kohsuke.github.GHCommit; import org.kohsuke.github.GHCommitQueryBuilder; import org.kohsuke.github.GHCompare; @@ -23,13 +22,13 @@ import com.axonivy.market.github.model.GitHubFile; import com.axonivy.market.github.service.GHAxonIvyMarketRepoService; import com.axonivy.market.github.service.GitHubService; +import com.axonivy.market.github.util.GitHubUtils; import lombok.extern.log4j.Log4j2; @Log4j2 @Service public class GHAxonIvyMarketRepoServiceImpl implements GHAxonIvyMarketRepoService { - private static final String DEFAULT_BRANCH = "master"; private static final LocalDateTime INITIAL_COMMIT_DATE = LocalDateTime.of(2020, 10, 30, 0, 0); private GHOrganization organization; private GHRepository repository; @@ -45,7 +44,7 @@ public Map> fetchAllMarketItems() { Map> ghContentMap = new HashMap<>(); try { List directoryContent = gitHubService.getDirectoryContent(getRepository(), - GitHubConstants.AXONIVY_MARKETPLACE_PATH); + GitHubConstants.AXONIVY_MARKETPLACE_PATH, GitHubConstants.DEFAULT_BRANCH); for (var content : directoryContent) { extractFileInDirectoryContent(content, ghContentMap); } @@ -85,7 +84,7 @@ public GHCommit getLastCommit(long lastCommitTime) { } private GHCommitQueryBuilder createQueryCommitsBuilder(long lastCommitTime) { - return getRepository().queryCommits().since(lastCommitTime).from(DEFAULT_BRANCH); + return getRepository().queryCommits().since(lastCommitTime).from(GitHubConstants.DEFAULT_BRANCH); } @Override @@ -136,4 +135,4 @@ public GHRepository getRepository() { return repository; } -} +} \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductRepository.java b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductRepository.java index 4bc4ad69a..ccd005cfd 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductRepository.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductRepository.java @@ -24,9 +24,9 @@ public interface ProductRepository extends MongoRepository { @Query("{'marketDirectory': {$regex : ?0, $options: 'i'}}") Product findByMarketDirectoryRegex(String search); - @Query("{ $and: [ { $or: [ { 'name': { $regex: ?0, $options: 'i' } }, { 'shortDescription': { $regex: ?0, $options: 'i' } } ] }, { 'type': ?1 } ] }") - Page searchByKeywordAndType(String keyword, String type, Pageable unifiedPageabe); + @Query("{ $and: [ { $or: [ { 'names.?': { $regex: ?0, $options: 'i' } }, { 'shortDescriptions.?': { $regex: ?0, $options: 'i' } } ] }, { 'type': ?1 } ] }") + Page searchByKeywordAndType(String keyword, String type, String language, Pageable unifiedPageabe); - @Query("{ $or: [ { 'name': { $regex: ?0, $options: 'i' } }, { 'shortDescription': { $regex: ?0, $options: 'i' } } ] }") - Page searchByNameOrShortDescriptionRegex(String keyword, Pageable unifiedPageabe); + @Query("{ $or: [ { 'names.?1': { $regex: ?0, $options: 'i' } }, { 'shortDescriptions.?1': { $regex: ?0, $options: 'i' } } ] }") + Page searchByNameOrShortDescriptionRegex(String keyword, String language, Pageable unifiedPageabe); } diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java b/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java index aa9142069..eb7d7ad69 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java @@ -7,7 +7,7 @@ import com.axonivy.market.entity.Product; public interface ProductService { - Page findProducts(String type, String keyword, Pageable pageable); + Page findProducts(String type, String keyword, String language, Pageable pageable); boolean syncLatestDataFromMarketRepo(); diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java index 900222513..cee9ee919 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java @@ -70,27 +70,27 @@ public ProductServiceImpl(ProductRepository productRepository, GHAxonIvyMarketRe } @Override - public Page findProducts(String type, String keyword, Pageable pageable) { + public Page findProducts(String type, String keyword, String language, Pageable pageable) { final var typeOption = TypeOption.of(type); - final var searchPageable = refinePagination(pageable); + final var searchPageable = refinePagination(language, pageable); Page result = Page.empty(); switch (typeOption) { - case ALL: - if (StringUtils.isBlank(keyword)) { - result = productRepository.findAll(searchPageable); - } else { - result = productRepository.searchByNameOrShortDescriptionRegex(keyword, searchPageable); - } - break; - case CONNECTORS, UTILITIES, SOLUTIONS: - if (StringUtils.isBlank(keyword)) { - result = productRepository.findByType(typeOption.getCode(), searchPageable); - } else { - result = productRepository.searchByKeywordAndType(keyword, typeOption.getCode(), searchPageable); - } - break; - default: - break; + case ALL: + if (StringUtils.isBlank(keyword)) { + result = productRepository.findAll(searchPageable); + } else { + result = productRepository.searchByNameOrShortDescriptionRegex(keyword, language, searchPageable); + } + break; + case CONNECTORS, UTILITIES, SOLUTIONS: + if (StringUtils.isBlank(keyword)) { + result = productRepository.findByType(typeOption.getCode(), searchPageable); + } else { + result = productRepository.searchByKeywordAndType(keyword, typeOption.getCode(), language, searchPageable); + } + break; + default: + break; } return result; } @@ -132,8 +132,7 @@ private void updateLatestChangeToProductsFromGithubRepo() { Map> groupGitHubFiles = new HashMap<>(); for (var file : gitHubFileChanges) { String filePath = file.getFileName(); - var parentPath = filePath.replace(FileType.META.getFileName(), EMPTY).replace(FileType.LOGO.getFileName(), - EMPTY); + var parentPath = filePath.replace(FileType.META.getFileName(), EMPTY).replace(FileType.LOGO.getFileName(), EMPTY); var files = groupGitHubFiles.getOrDefault(parentPath, new ArrayList<>()); files.add(file); groupGitHubFiles.putIfAbsent(parentPath, files); @@ -144,8 +143,8 @@ private void updateLatestChangeToProductsFromGithubRepo() { Product product = new Product(); GHContent fileContent; try { - fileContent = gitHubService.getGHContent(axonIvyMarketRepoService.getRepository(), - file.getFileName()); + fileContent = gitHubService.getGHContent(axonIvyMarketRepoService.getRepository(), file.getFileName(), + GitHubConstants.DEFAULT_BRANCH); } catch (IOException e) { log.error("Get GHContent failed: ", e); continue; @@ -165,44 +164,44 @@ private void updateLatestChangeToProductsFromGithubRepo() { private void modifyProductLogo(String parentPath, GitHubFile file, Product product, GHContent fileContent) { Product result = null; switch (file.getStatus()) { - case MODIFIED, ADDED: - result = productRepository.findByMarketDirectoryRegex(parentPath); - if (result != null) { - result.setLogoUrl(GitHubUtils.getDownloadUrl(fileContent)); - productRepository.save(result); - } - break; - case REMOVED: - result = productRepository.findByLogoUrl(product.getLogoUrl()); - if (result != null) { - productRepository.deleteById(result.getId()); - } - break; - default: - break; + case MODIFIED, ADDED: + result = productRepository.findByMarketDirectoryRegex(parentPath); + if (result != null) { + result.setLogoUrl(GitHubUtils.getDownloadUrl(fileContent)); + productRepository.save(result); + } + break; + case REMOVED: + result = productRepository.findByLogoUrl(product.getLogoUrl()); + if (result != null) { + productRepository.deleteById(result.getId()); + } + break; + default: + break; } } private void modifyProductByMetaContent(GitHubFile file, Product product) { switch (file.getStatus()) { - case MODIFIED, ADDED: - productRepository.save(product); - break; - case REMOVED: - productRepository.deleteById(product.getId()); - break; - default: - break; + case MODIFIED, ADDED: + productRepository.save(product); + break; + case REMOVED: + productRepository.deleteById(product.getId()); + break; + default: + break; } } - private Pageable refinePagination(Pageable pageable) { + private Pageable refinePagination(String language, Pageable pageable) { PageRequest pageRequest = (PageRequest) pageable; - if (pageable != null && pageable.getSort() != null) { + if (pageable != null) { List orders = new ArrayList<>(); for (var sort : pageable.getSort()) { final var sortOption = SortOption.of(sort.getProperty()); - Order order = new Order(sort.getDirection(), sortOption.getCode()); + Order order = new Order(sort.getDirection(), sortOption.getCode(language)); orders.add(order); } pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(orders)); @@ -236,9 +235,7 @@ private Page syncProductsFromGitHubRepo() { updateProductFromReleaseTags(product); } products.add(product); - }); - if (!products.isEmpty()) { productRepository.saveAll(products); }