From ca1ed746d6863e5300f38a22214950447b6d69e1 Mon Sep 17 00:00:00 2001
From: Thuy Nguyen <145430420+nntthuy-axonivy@users.noreply.github.com>
Date: Tue, 17 Sep 2024 15:26:14 +0700
Subject: [PATCH 01/20] MARP-1015: Fix sonar (#158)
---
marketplace-ui/src/app/app.component.ts | 2 +-
.../src/app/shared/components/header/header.component.ts | 9 +--------
2 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/marketplace-ui/src/app/app.component.ts b/marketplace-ui/src/app/app.component.ts
index 2d15456b4..720a809d8 100644
--- a/marketplace-ui/src/app/app.component.ts
+++ b/marketplace-ui/src/app/app.component.ts
@@ -24,7 +24,7 @@ export class AppComponent {
loadingService = inject(LoadingService);
routingQueryParamService = inject(RoutingQueryParamService);
route = inject(ActivatedRoute);
- isMobileMenuCollapsed: boolean = true;
+ isMobileMenuCollapsed = true;
constructor(private readonly router: Router) {}
diff --git a/marketplace-ui/src/app/shared/components/header/header.component.ts b/marketplace-ui/src/app/shared/components/header/header.component.ts
index 2812dbb8e..dee44f476 100644
--- a/marketplace-ui/src/app/shared/components/header/header.component.ts
+++ b/marketplace-ui/src/app/shared/components/header/header.component.ts
@@ -1,11 +1,5 @@
import { CommonModule } from '@angular/common';
-import {
- Component,
- EventEmitter,
- inject,
- Output,
- model
-} from '@angular/core';
+import { Component, inject, model } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { LanguageService } from '../../../core/services/language/language.service';
@@ -31,7 +25,6 @@ import { ThemeSelectionComponent } from './theme-selection/theme-selection.compo
styleUrls: ['./header.component.scss', '../../../app.component.scss']
})
export class HeaderComponent {
-
selectedNav = '/';
isMobileMenuCollapsed = model(true);
From f0eb9bcf4a387d2aa6b600ffcd33aa3728d0c157 Mon Sep 17 00:00:00 2001
From: Dinh Nguyen <127725498+ntqdinh-axonivy@users.noreply.github.com>
Date: Wed, 18 Sep 2024 15:55:46 +0700
Subject: [PATCH 02/20] Marp-1100 market website error occurring after choosing
snapshot version
---
.../product-detail-version-action.component.html | 2 +-
.../product-detail/product-detail.component.spec.ts | 11 +++++++++++
.../product-detail/product-detail.component.ts | 2 +-
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.html b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.html
index 29048377e..b6bb3e8d0 100644
--- a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.html
+++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.html
@@ -12,7 +12,7 @@
(minimum version 9.2.0)
"
- (click)="onUpdateInstallationCountForDesigner()" data-bs-custom-class="custom-tooltip"
+ data-bs-custom-class="custom-tooltip"
[ngClass]="themeService.isDarkMode() ? 'btn-light' : 'btn-primary'">
{{ 'common.product.detail.install.buttonLabel' | translate }}
diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.spec.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.spec.ts
index 407437495..bcb83a011 100644
--- a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.spec.ts
+++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.spec.ts
@@ -248,6 +248,17 @@ describe('ProductDetailComponent', () => {
expect(component.getContent('description')).toBeFalse();
});
+ it('should return false for any tab when detail content is undefined or null', () => {
+ component.productModuleContent.set(null as any as ProductModuleContent);
+ expect(component.getContent('description')).toBeFalse();
+ component.productModuleContent.set(
+ undefined as any as ProductModuleContent
+ );
+ expect(component.getContent('description')).toBeFalse();
+ component.productModuleContent.set({} as any as ProductModuleContent);
+ expect(component.getContent('description')).toBeFalse();
+ });
+
it('should return false for description when in EN language it is an empty string', () => {
const mockContent: ProductModuleContent = {
...MOCK_PRODUCT_MODULE_CONTENT,
diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts
index 46737a8dc..491d74e8f 100644
--- a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts
+++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts
@@ -208,7 +208,7 @@ export class ProductDetailComponent {
getContent(value: string): boolean {
const content = this.productModuleContent();
- if (Object.keys(content).length === 0) {
+ if (!content || Object.keys(content).length === 0) {
return false;
}
From 8e5bb1b344fdda4acf7c275bfb9fd23c43fa82d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=E1=BA=A7n=20V=C4=A9nh=20Thi=E1=BB=87n=20Ph=C3=BAc?=
<143604440+tvtphuc-axonivy@users.noreply.github.com>
Date: Thu, 19 Sep 2024 11:18:10 +0700
Subject: [PATCH 03/20] Feature/marp 1058 market website remove using of images
url from GitHub in product detail (#159)
---
.../product-card/product-card.component.html | 3 ++-
.../product-card/product-card.component.ts | 13 +++++++++++--
.../product-detail/product-detail.component.html | 6 ++++--
.../product-detail/product-detail.component.scss | 5 ++++-
.../product-detail/product-detail.component.ts | 13 ++++++++++---
.../src/app/shared/constants/common.constant.ts | 4 +++-
marketplace-ui/src/app/shared/pipes/logo.pipe.ts | 16 ----------------
7 files changed, 34 insertions(+), 26 deletions(-)
delete mode 100644 marketplace-ui/src/app/shared/pipes/logo.pipe.ts
diff --git a/marketplace-ui/src/app/modules/product/product-card/product-card.component.html b/marketplace-ui/src/app/modules/product/product-card/product-card.component.html
index dd414407c..687471ce6 100644
--- a/marketplace-ui/src/app/modules/product/product-card/product-card.component.html
+++ b/marketplace-ui/src/app/modules/product/product-card/product-card.component.html
@@ -6,7 +6,8 @@
class="card-img-top rounded"
width="70"
height="70"
- [ngSrc]="product | logo"
+ [ngSrc]="logoUrl"
+ (error)="onLogoError()"
[alt]="
product.names | multilingualism: languageService.selectedLanguage()
"
diff --git a/marketplace-ui/src/app/modules/product/product-card/product-card.component.ts b/marketplace-ui/src/app/modules/product/product-card/product-card.component.ts
index 5de39f622..c268a4421 100644
--- a/marketplace-ui/src/app/modules/product/product-card/product-card.component.ts
+++ b/marketplace-ui/src/app/modules/product/product-card/product-card.component.ts
@@ -4,14 +4,14 @@ import { TranslateModule } from '@ngx-translate/core';
import { LanguageService } from '../../../core/services/language/language.service';
import { ThemeService } from '../../../core/services/theme/theme.service';
import { Product } from '../../../shared/models/product.model';
-import { ProductLogoPipe } from '../../../shared/pipes/logo.pipe';
import { MultilingualismPipe } from '../../../shared/pipes/multilingualism.pipe';
import { ProductComponent } from '../product.component';
+import { DEFAULT_IMAGE_URL } from '../../../shared/constants/common.constant';
@Component({
selector: 'app-product-card',
standalone: true,
- imports: [CommonModule, ProductLogoPipe, MultilingualismPipe, TranslateModule, NgOptimizedImage],
+ imports: [CommonModule, MultilingualismPipe, TranslateModule, NgOptimizedImage],
templateUrl: './product-card.component.html',
styleUrl: './product-card.component.scss'
})
@@ -21,4 +21,13 @@ export class ProductCardComponent {
isShowInRESTClientEditor = inject(ProductComponent).isRESTClient();
@Input() product!: Product;
+ logoUrl = DEFAULT_IMAGE_URL;
+
+ ngOnInit(): void {
+ this.logoUrl = this.product.logoUrl;
+ }
+
+ onLogoError() {
+ this.logoUrl = DEFAULT_IMAGE_URL;
+ }
}
diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html
index b20928040..fbb560db5 100644
--- a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html
+++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html
@@ -20,13 +20,15 @@
+ "/>
(false);
installationCount = 0;
-
+ logoUrl = DEFAULT_IMAGE_URL;
@HostListener('window:popstate', ['$event'])
onPopState() {
this.activeTab = window.location.hash.split('#tab-')[1];
@@ -147,6 +149,7 @@ export class ProductDetailComponent {
this.installationCount = productDetail.installationCount;
this.handleProductContentVersion();
this.updateProductDetailActionType(productDetail);
+ this.logoUrl = productDetail.logoUrl;
});
this.productFeedbackService.initFeedbacks();
@@ -155,6 +158,10 @@ export class ProductDetailComponent {
this.updateDropdownSelection();
}
+ onLogoError() {
+ this.logoUrl = DEFAULT_IMAGE_URL;
+ }
+
handleProductContentVersion() {
if (this.isEmptyProductContent()) {
return;
diff --git a/marketplace-ui/src/app/shared/constants/common.constant.ts b/marketplace-ui/src/app/shared/constants/common.constant.ts
index ac0d39c6b..ffc6e73ef 100644
--- a/marketplace-ui/src/app/shared/constants/common.constant.ts
+++ b/marketplace-ui/src/app/shared/constants/common.constant.ts
@@ -204,4 +204,6 @@ export const ERROR_CODES = [
UNDEFINED_ERROR_CODE,
NOT_FOUND_ERROR_CODE,
INTERNAL_SERVER_ERROR_CODE
-];
\ No newline at end of file
+];
+
+export const DEFAULT_IMAGE_URL = '/assets/images/misc/axonivy-logo-round.png';
diff --git a/marketplace-ui/src/app/shared/pipes/logo.pipe.ts b/marketplace-ui/src/app/shared/pipes/logo.pipe.ts
deleted file mode 100644
index 93554c3e6..000000000
--- a/marketplace-ui/src/app/shared/pipes/logo.pipe.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Pipe, PipeTransform } from '@angular/core';
-import { Product } from '../models/product.model';
-
-@Pipe({
- standalone: true,
- name: 'logo'
-})
-export class ProductLogoPipe implements PipeTransform {
- transform(product: Product, _args?: []): string {
- let logoUrl = product.logoUrl;
- if (logoUrl === undefined || logoUrl === '') {
- logoUrl = `/assets/images/misc/axonivy-logo-round.png`;
- }
- return logoUrl;
- }
-}
From a55cbb8db834db94dcb377f3ff17c83c7f763a76 Mon Sep 17 00:00:00 2001
From: Khanh Nguyen <119989010+ndkhanh-axonivy@users.noreply.github.com>
Date: Thu, 19 Sep 2024 12:00:23 +0700
Subject: [PATCH 04/20] MARP-1104 Market website portal versions and artifacts
aren t shown marketplace website (#162)
---
.../axonivy/market/enums/NonStandardProduct.java | 2 +-
.../market/service/impl/VersionServiceImpl.java | 15 ++++++++++-----
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/marketplace-service/src/main/java/com/axonivy/market/enums/NonStandardProduct.java b/marketplace-service/src/main/java/com/axonivy/market/enums/NonStandardProduct.java
index 0535ce237..4c914204a 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/enums/NonStandardProduct.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/enums/NonStandardProduct.java
@@ -47,6 +47,6 @@ public enum NonStandardProduct {
}
public static NonStandardProduct findById(String id) {
- return NON_STANDARD_PRODUCT_MAP.getOrDefault(id,DEFAULT);
+ return NON_STANDARD_PRODUCT_MAP.getOrDefault(id, DEFAULT);
}
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java
index 2f0a81e8d..556bb8e8c 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java
@@ -48,6 +48,7 @@
import static com.axonivy.market.constants.ProductJsonConstants.NAME;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
+
@Log4j2
@Service
@Getter
@@ -96,7 +97,8 @@ public List getArtifactsAndVersionToDisplay(String pr
this.productId = productId;
artifactsFromMeta = getProductMetaArtifacts(productId);
- List versionsToDisplay = VersionUtils.getVersionsToDisplay(getVersionsFromMavenArtifacts(), isShowDevVersion, designerVersion);
+ List versionsToDisplay = VersionUtils.getVersionsToDisplay(getVersionsFromMavenArtifacts(),
+ isShowDevVersion, designerVersion);
proceedDataCache = mavenArtifactVersionRepository.findById(productId).orElse(new MavenArtifactVersion(productId));
metaProductArtifact = artifactsFromMeta.stream()
.filter(artifact -> artifact.getArtifactId().endsWith(MavenConstants.PRODUCT_ARTIFACT_POSTFIX)).findAny()
@@ -112,17 +114,18 @@ public List getArtifactsAndVersionToDisplay(String pr
}
@Override
- public Map getProductJsonContentByIdAndVersion(String productId, String version){
+ public Map getProductJsonContentByIdAndVersion(String productId, String version) {
Map result = new HashMap<>();
try {
- ProductJsonContent productJsonContent = productJsonContentRepository.findByProductIdAndVersion(productId, version);
+ ProductJsonContent productJsonContent = productJsonContentRepository.findByProductIdAndVersion(productId,
+ version);
if (ObjectUtils.isEmpty(productJsonContent)) {
return new HashMap<>();
}
result = mapper.readValue(productJsonContent.getContent(), Map.class);
result.computeIfAbsent(NAME, k -> productJsonContent.getName());
- } catch (JsonProcessingException jsonProcessingException){
+ } catch (JsonProcessingException jsonProcessingException) {
log.error(jsonProcessingException.getMessage());
}
return result;
@@ -249,7 +252,9 @@ public String getVersionTag(String version) {
public String buildProductJsonFilePath() {
String pathToProductFolderFromTagContent = metaProductArtifact.getArtifactId();
- GitHubUtils.getNonStandardProductFilePath(productId);
+ if (NonStandardProduct.DEFAULT != NonStandardProduct.findById(productId)) {
+ pathToProductFolderFromTagContent = GitHubUtils.getNonStandardProductFilePath(productId);
+ }
productJsonFilePath = String.format(GitHubConstants.PRODUCT_JSON_FILE_PATH_FORMAT,
pathToProductFolderFromTagContent);
return productJsonFilePath;
From bf33dc06e4d89805a1a3747a1eb5f29146afaaee Mon Sep 17 00:00:00 2001
From: Dinh Nguyen <127725498+ntqdinh-axonivy@users.noreply.github.com>
Date: Fri, 20 Sep 2024 15:11:55 +0700
Subject: [PATCH 05/20] MARP-1067 marketplace website can not download install
artifact snapshot
---
.../ArchivedArtifactsComparator.java | 3 +-
.../comparator/LatestVersionComparator.java | 23 +-
.../comparator/MavenVersionComparator.java | 4 +-
.../market/constants/MavenConstants.java | 4 +-
.../constants/ProductJsonConstants.java | 1 +
.../constants/RequestMappingConstants.java | 1 -
.../market/entity/MavenArtifactVersion.java | 2 -
.../service/GHAxonIvyProductRepoService.java | 3 +
.../impl/GHAxonIvyProductRepoServiceImpl.java | 10 +-
.../market/service/VersionService.java | 4 -
.../service/impl/VersionServiceImpl.java | 269 ++++++---------
.../com/axonivy/market/util/VersionUtils.java | 16 +-
.../service/impl/VersionServiceImplTest.java | 318 +++++-------------
...product-detail-version-action.component.ts | 6 +-
14 files changed, 207 insertions(+), 457 deletions(-)
diff --git a/marketplace-service/src/main/java/com/axonivy/market/comparator/ArchivedArtifactsComparator.java b/marketplace-service/src/main/java/com/axonivy/market/comparator/ArchivedArtifactsComparator.java
index d5c553ed2..c88a426cb 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/comparator/ArchivedArtifactsComparator.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/comparator/ArchivedArtifactsComparator.java
@@ -5,10 +5,9 @@
import java.util.Comparator;
public class ArchivedArtifactsComparator implements Comparator {
- private final LatestVersionComparator comparator = new LatestVersionComparator();
@Override
public int compare(ArchivedArtifact artifact1, ArchivedArtifact artifact2) {
- return comparator.compare(artifact1.getLastVersion(), artifact2.getLastVersion());
+ return MavenVersionComparator.compare(artifact2.getLastVersion(), artifact1.getLastVersion());
}
}
\ No newline at end of file
diff --git a/marketplace-service/src/main/java/com/axonivy/market/comparator/LatestVersionComparator.java b/marketplace-service/src/main/java/com/axonivy/market/comparator/LatestVersionComparator.java
index 17d90e397..108036fb0 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/comparator/LatestVersionComparator.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/comparator/LatestVersionComparator.java
@@ -6,27 +6,6 @@ public class LatestVersionComparator implements Comparator {
@Override
public int compare(String v1, String v2) {
- // Split by "."
- String[] parts1 = v1.split("\\.");
- String[] parts2 = v2.split("\\.");
-
- // Compare up to the shorter length
- int length = Math.min(parts1.length, parts2.length);
- for (int i = 0; i < length; i++) {
- try {
- int num1 = Integer.parseInt(parts1[i]);
- int num2 = Integer.parseInt(parts2[i]);
- // Return difference for numeric parts
- if (num1 != num2) {
- return num2 - num1;
- }
- // Handle non-numeric parts (e.g., "m229")
- } catch (NumberFormatException e) {
- return parts2[i].replaceAll("\\D", "").compareTo(parts1[i].replaceAll("\\D", ""));
- }
- }
-
- // Versions with more parts are considered larger
- return parts2.length - parts1.length;
+ return MavenVersionComparator.compare(v2, v1);
}
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java b/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java
index d7df9ed85..2c49ebf23 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java
@@ -11,12 +11,12 @@
import java.util.regex.Pattern;
import static com.axonivy.market.constants.CommonConstants.DASH_SEPARATOR;
+import static com.axonivy.market.constants.MavenConstants.MAIN_VERSION_REGEX;
import static com.axonivy.market.constants.MavenConstants.SNAPSHOT_VERSION;
import static org.apache.commons.lang3.StringUtils.EMPTY;
public class MavenVersionComparator {
- private static final String MAIN_VERSION_REGEX = "\\.";
private static final int GREATER_THAN = 1;
private static final int EQUAL = 0;
private static final int LESS_THAN = -1;
@@ -46,7 +46,7 @@ public static String findHighestMavenVersion(List versions) {
return highestVersion;
}
- private static int compare(String version, String otherVersion) {
+ public static int compare(String version, String otherVersion) {
version = stripLeadingChars(version);
otherVersion = stripLeadingChars(otherVersion);
String[] versionParts = createMainAndQualifierArray(version);
diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java
index 67ec50e5a..0c99d0118 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java
@@ -8,9 +8,9 @@ private MavenConstants() {
public static final String SNAPSHOT_RELEASE_POSTFIX = "-" + SNAPSHOT_VERSION;
public static final String SPRINT_RELEASE_POSTFIX = "-m";
public static final String PRODUCT_ARTIFACT_POSTFIX = "-product";
- public static final String METADATA_URL_FORMAT = "%s/%s/%s/maven-metadata.xml";
public static final String DEFAULT_IVY_MAVEN_BASE_URL = "https://maven.axonivy.com";
- public static final String ARTIFACT_DOWNLOAD_URL_FORMAT = "%s/%s/%s/%s/%s-%s.%s";
+ public static final String ARTIFACT_FILE_NAME_FORMAT = "%s-%s.%s";
public static final String ARTIFACT_NAME_FORMAT = "%s (%s)";
public static final String VERSION_EXTRACT_FORMAT_FROM_METADATA_FILE = "//versions/version/text()";
+ public static final String MAIN_VERSION_REGEX = "\\.";
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/ProductJsonConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/ProductJsonConstants.java
index fd63733dd..e0bcaaf1b 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/constants/ProductJsonConstants.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/constants/ProductJsonConstants.java
@@ -20,6 +20,7 @@ public class ProductJsonConstants {
public static final String CUSTOM_ORDER = "customOrder";
public static final String EN_LANGUAGE = "en";
public static final String NAME = "name";
+ public static final String DEFAULT_PRODUCT_TYPE = "iar";
private ProductJsonConstants() {
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java
index 8d3124988..95105083e 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java
@@ -24,7 +24,6 @@ public class RequestMappingConstants {
public static final String INSTALLATION_COUNT_BY_ID = "/installationcount/{id}";
public static final String PRODUCT_JSON_CONTENT_BY_PRODUCT_ID_AND_VERSION = "/{id}/{version}/json";
public static final String VERSIONS_IN_DESIGNER = "/{id}/designerversions";
- public static final String DESIGNER_INSTALLATION_BY_PRODUCT_ID_AND_DESIGNER_VERSION = "/installation/{productId}/designer/{designerVersion}";
public static final String DESIGNER_INSTALLATION_BY_ID = "/installation/{id}/designer";
public static final String CUSTOM_SORT = "custom-sort";
public static final String IMAGE = API + "/image";
diff --git a/marketplace-service/src/main/java/com/axonivy/market/entity/MavenArtifactVersion.java b/marketplace-service/src/main/java/com/axonivy/market/entity/MavenArtifactVersion.java
index e7a6a2e92..f4e437225 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/entity/MavenArtifactVersion.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/entity/MavenArtifactVersion.java
@@ -9,7 +9,6 @@
import java.io.Serial;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,7 +26,6 @@ public class MavenArtifactVersion implements Serializable {
@Id
private String productId;
- private List versions = new ArrayList<>();
private Map> productArtifactWithVersionReleased = new HashMap<>();
public MavenArtifactVersion(String productId) {
diff --git a/marketplace-service/src/main/java/com/axonivy/market/github/service/GHAxonIvyProductRepoService.java b/marketplace-service/src/main/java/com/axonivy/market/github/service/GHAxonIvyProductRepoService.java
index debe27c42..1a846a105 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/github/service/GHAxonIvyProductRepoService.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/github/service/GHAxonIvyProductRepoService.java
@@ -8,9 +8,12 @@
import org.kohsuke.github.GHTag;
import java.io.IOException;
+import java.io.InputStream;
import java.util.List;
public interface GHAxonIvyProductRepoService {
+
+ List extractMavenArtifactsFromContentStream(InputStream contentStream) throws IOException;
GHContent getContentFromGHRepoAndTag(String repoName, String filePath, String tagVersion);
diff --git a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyProductRepoServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyProductRepoServiceImpl.java
index 2d0e673f0..edb0e1155 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyProductRepoServiceImpl.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GHAxonIvyProductRepoServiceImpl.java
@@ -5,7 +5,6 @@
import com.axonivy.market.constants.MavenConstants;
import com.axonivy.market.constants.ProductJsonConstants;
import com.axonivy.market.constants.ReadmeConstants;
-import com.axonivy.market.entity.Image;
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.entity.ProductJsonContent;
@@ -33,7 +32,6 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
-import javax.swing.text.html.Option;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@@ -77,12 +75,16 @@ public GHAxonIvyProductRepoServiceImpl(GitHubService gitHubService, ImageService
@Override
public List convertProductJsonToMavenProductInfo(GHContent content) throws IOException {
- List artifacts = new ArrayList<>();
InputStream contentStream = extractedContentStream(content);
if (Objects.isNull(contentStream)) {
- return artifacts;
+ return new ArrayList<>();
}
+ return extractMavenArtifactsFromContentStream(contentStream);
+ }
+ @Override
+ public List extractMavenArtifactsFromContentStream(InputStream contentStream) throws IOException {
+ List artifacts = new ArrayList<>();
JsonNode rootNode = objectMapper.readTree(contentStream);
JsonNode installersNode = rootNode.path(ProductJsonConstants.INSTALLERS);
diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/VersionService.java b/marketplace-service/src/main/java/com/axonivy/market/service/VersionService.java
index e4800c5a9..b06fd5344 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/service/VersionService.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/service/VersionService.java
@@ -7,10 +7,6 @@
public interface VersionService {
- List getVersionsFromArtifactDetails(String repoUrl, String groupId, String artifactId);
-
- String buildMavenMetadataUrlFromArtifact(String repoUrl, String groupId, String artifactId);
-
List getArtifactsAndVersionToDisplay(String productId, Boolean isShowDevVersion,
String designerVersion);
diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java
index 556bb8e8c..6866840d7 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/VersionServiceImpl.java
@@ -1,16 +1,15 @@
package com.axonivy.market.service.impl;
import com.axonivy.market.comparator.ArchivedArtifactsComparator;
-import com.axonivy.market.comparator.LatestVersionComparator;
+import com.axonivy.market.comparator.MavenVersionComparator;
import com.axonivy.market.constants.CommonConstants;
-import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.constants.MavenConstants;
+import com.axonivy.market.constants.ProductJsonConstants;
import com.axonivy.market.controller.ProductDetailsController;
import com.axonivy.market.entity.MavenArtifactModel;
import com.axonivy.market.entity.MavenArtifactVersion;
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductJsonContent;
-import com.axonivy.market.enums.NonStandardProduct;
import com.axonivy.market.github.model.ArchivedArtifact;
import com.axonivy.market.github.model.MavenArtifact;
import com.axonivy.market.github.service.GHAxonIvyProductRepoService;
@@ -19,22 +18,23 @@
import com.axonivy.market.model.VersionAndUrlModel;
import com.axonivy.market.repository.MavenArtifactVersionRepository;
import com.axonivy.market.repository.ProductJsonContentRepository;
+import com.axonivy.market.repository.ProductModuleContentRepository;
import com.axonivy.market.repository.ProductRepository;
import com.axonivy.market.service.VersionService;
import com.axonivy.market.util.VersionUtils;
-import com.axonivy.market.util.XmlReaderUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.Getter;
import lombok.extern.log4j.Log4j2;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
-import org.kohsuke.github.GHContent;
import org.springframework.hateoas.Link;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -44,6 +44,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import static com.axonivy.market.constants.ProductJsonConstants.NAME;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
@@ -51,74 +52,56 @@
@Log4j2
@Service
-@Getter
public class VersionServiceImpl implements VersionService {
private final GHAxonIvyProductRepoService gitHubService;
private final MavenArtifactVersionRepository mavenArtifactVersionRepository;
- private final ProductRepository productRepository;
- private final ProductJsonContentRepository productJsonContentRepository;
- @Getter
- private String repoName;
- private Map> archivedArtifactsMap;
- private List artifactsFromMeta;
- private MavenArtifactVersion proceedDataCache;
- private MavenArtifact metaProductArtifact;
- private final LatestVersionComparator latestVersionComparator = new LatestVersionComparator();
- @Getter
- private String productJsonFilePath;
- private String productId;
+ private final ProductRepository productRepo;
+ private final ProductJsonContentRepository productJsonRepo;
+ private final ProductModuleContentRepository productContentRepo;
private final ObjectMapper mapper = new ObjectMapper();
public VersionServiceImpl(GHAxonIvyProductRepoService gitHubService,
- MavenArtifactVersionRepository mavenArtifactVersionRepository, ProductRepository productRepository,
- ProductJsonContentRepository productJsonContentRepository) {
+ MavenArtifactVersionRepository mavenArtifactVersionRepository, ProductRepository productRepo,
+ ProductJsonContentRepository productJsonRepo, ProductModuleContentRepository productContentRepo) {
this.gitHubService = gitHubService;
this.mavenArtifactVersionRepository = mavenArtifactVersionRepository;
- this.productRepository = productRepository;
-
- this.productJsonContentRepository = productJsonContentRepository;
+ this.productRepo = productRepo;
+ this.productJsonRepo = productJsonRepo;
+ this.productContentRepo = productContentRepo;
}
- private void resetData() {
- repoName = null;
- archivedArtifactsMap = new HashMap<>();
- artifactsFromMeta = Collections.emptyList();
- proceedDataCache = null;
- metaProductArtifact = null;
- productJsonFilePath = null;
- productId = null;
+ public static Map> getArchivedArtifactMapFromProduct(
+ List artifactsFromMeta) {
+ Map> result = new HashMap<>();
+ artifactsFromMeta.forEach(artifact -> {
+ List archivedArtifacts = new ArrayList<>(
+ Optional.ofNullable(artifact.getArchivedArtifacts()).orElse(Collections.emptyList()).stream()
+ .sorted(new ArchivedArtifactsComparator()).toList());
+ Collections.reverse(archivedArtifacts);
+ result.put(artifact.getArtifactId(), archivedArtifacts);
+ });
+ return result;
}
public List getArtifactsAndVersionToDisplay(String productId, Boolean isShowDevVersion,
String designerVersion) {
- List results = new ArrayList<>();
- resetData();
-
- this.productId = productId;
- artifactsFromMeta = getProductMetaArtifacts(productId);
- List versionsToDisplay = VersionUtils.getVersionsToDisplay(getVersionsFromMavenArtifacts(),
+ List versionsToDisplay = VersionUtils.getVersionsToDisplay(getPersistedVersions(productId),
isShowDevVersion, designerVersion);
- proceedDataCache = mavenArtifactVersionRepository.findById(productId).orElse(new MavenArtifactVersion(productId));
- metaProductArtifact = artifactsFromMeta.stream()
+ List artifactsFromMeta = getArtifactsFromMeta(productId);
+ MavenArtifact productArtifact = artifactsFromMeta.stream()
.filter(artifact -> artifact.getArtifactId().endsWith(MavenConstants.PRODUCT_ARTIFACT_POSTFIX)).findAny()
.orElse(new MavenArtifact());
-
- sanitizeMetaArtifactBeforeHandle();
-
- boolean isNewVersionDetected = handleArtifactForVersionToDisplay(versionsToDisplay, results);
- if (isNewVersionDetected) {
- mavenArtifactVersionRepository.save(proceedDataCache);
- }
- return results;
+ artifactsFromMeta.remove(productArtifact);
+ Map> archivedArtifactsMap = getArchivedArtifactMapFromProduct(artifactsFromMeta);
+ return handleArtifactForVersionToDisplay(versionsToDisplay, productId, artifactsFromMeta, archivedArtifactsMap);
}
@Override
public Map getProductJsonContentByIdAndVersion(String productId, String version) {
Map result = new HashMap<>();
try {
- ProductJsonContent productJsonContent = productJsonContentRepository.findByProductIdAndVersion(productId,
- version);
+ ProductJsonContent productJsonContent = productJsonRepo.findByProductIdAndVersion(productId, version);
if (ObjectUtils.isEmpty(productJsonContent)) {
return new HashMap<>();
}
@@ -134,7 +117,7 @@ public Map getProductJsonContentByIdAndVersion(String productId,
@Override
public List getVersionsForDesigner(String productId) {
List versionAndUrlList = new ArrayList<>();
- List versions = productRepository.getReleasedVersionsById(productId);
+ List versions = productRepo.getReleasedVersionsById(productId);
for (String version : versions) {
Link link = linkTo(
methodOn(ProductDetailsController.class).findProductJsonContent(productId, version)).withSelfRel();
@@ -144,176 +127,122 @@ public List getVersionsForDesigner(String productId) {
return versionAndUrlList;
}
- public boolean handleArtifactForVersionToDisplay(List versionsToDisplay,
- List result) {
+ /**
+ * This function will combine default artifacts (from product.json) and custom artifacts from (meta.json)
+ * of each version and return it to user.
+ * By default, all artifacts model (from product.json) by version to display will be taken from db.
+ * If new version is detected, new model will be built and save back to db.
+ **/
+ public List handleArtifactForVersionToDisplay(List versionsToDisplay,
+ String productId, List artifactsFromMeta,
+ Map> archivedArtifactsMap) {
boolean isNewVersionDetected = false;
+ List results = new ArrayList<>();
+ MavenArtifactVersion cache = mavenArtifactVersionRepository.findById(productId)
+ .orElse(new MavenArtifactVersion(productId));
for (String version : versionsToDisplay) {
- List artifactsInVersion = convertMavenArtifactsToModels(artifactsFromMeta, version);
- List productArtifactModels = proceedDataCache.getProductArtifactWithVersionReleased()
- .get(version);
+ List artifactsInVersion = convertArtifactsToModels(artifactsFromMeta, version,
+ archivedArtifactsMap);
+ List productArtifactModels = cache.getProductArtifactWithVersionReleased().get(version);
if (productArtifactModels == null) {
isNewVersionDetected = true;
- productArtifactModels = updateArtifactsInVersionWithProductArtifact(version);
+ productArtifactModels = convertArtifactsToModels(getMavenArtifactsFromProductJsonByVersion(version, productId),
+ version, archivedArtifactsMap);
+ cache.getProductArtifactWithVersionReleased().put(version, productArtifactModels);
}
artifactsInVersion.addAll(productArtifactModels);
- result.add(new MavenArtifactVersionModel(version, artifactsInVersion.stream().distinct().toList()));
+ results.add(new MavenArtifactVersionModel(version, artifactsInVersion.stream().distinct().toList()));
}
- return isNewVersionDetected;
- }
-
- public List updateArtifactsInVersionWithProductArtifact(String version) {
- List productArtifactModels = convertMavenArtifactsToModels(getProductJsonByVersion(version),
- version);
- proceedDataCache.getVersions().add(version);
- proceedDataCache.getProductArtifactWithVersionReleased().put(version, productArtifactModels);
- return productArtifactModels;
- }
-
- public List getProductMetaArtifacts(String productId) {
- Product productInfo = productRepository.findById(productId).orElse(new Product());
- String fullRepoName = productInfo.getRepositoryName();
- if (StringUtils.isNotEmpty(fullRepoName)) {
- repoName = getRepoNameFromMarketRepo(fullRepoName);
+ if (isNewVersionDetected) {
+ mavenArtifactVersionRepository.save(cache);
}
- return Optional.ofNullable(productInfo.getArtifacts()).orElse(new ArrayList<>());
+ return results;
}
- public void sanitizeMetaArtifactBeforeHandle() {
- artifactsFromMeta.remove(metaProductArtifact);
- artifactsFromMeta.forEach(artifact -> {
- List archivedArtifacts = new ArrayList<>(
- Optional.ofNullable(artifact.getArchivedArtifacts()).orElse(Collections.emptyList()).stream()
- .sorted(new ArchivedArtifactsComparator()).toList());
- Collections.reverse(archivedArtifacts);
- archivedArtifactsMap.put(artifact.getArtifactId(), archivedArtifacts);
- });
+ public List getArtifactsFromMeta(String productId) {
+ Product productInfo = productRepo.findById(productId).orElse(new Product());
+ return Optional.ofNullable(productInfo.getArtifacts()).orElse(new ArrayList<>());
}
- public List getVersionsFromMavenArtifacts() {
+ public List getPersistedVersions(String productId) {
+ var product = productRepo.findById(productId);
Set versions = new HashSet<>();
- for (MavenArtifact artifact : artifactsFromMeta) {
- versions.addAll(
- getVersionsFromArtifactDetails(artifact.getRepoUrl(), artifact.getGroupId(), artifact.getArtifactId()));
- Optional.ofNullable(artifact.getArchivedArtifacts()).orElse(Collections.emptyList()).forEach(
- archivedArtifact -> versions.addAll(
- getVersionsFromArtifactDetails(artifact.getRepoUrl(), archivedArtifact.getGroupId(),
- archivedArtifact.getArtifactId())));
+ if (product.isPresent()) {
+ versions.addAll(product.get().getReleasedVersions());
}
- List versionList = new ArrayList<>(versions);
- versionList.sort(new LatestVersionComparator());
- return versionList;
- }
-
- @Override
- public List getVersionsFromArtifactDetails(String repoUrl, String groupId, String artifactID) {
- List versions = new ArrayList<>();
- String baseUrl = buildMavenMetadataUrlFromArtifact(repoUrl, groupId, artifactID);
- if (StringUtils.isNotBlank(baseUrl)) {
- versions.addAll(XmlReaderUtils.readXMLFromUrl(baseUrl));
+ if (CollectionUtils.isEmpty(versions)) {
+ versions.addAll(productContentRepo.findTagsByProductId(productId));
+ versions = versions.stream().map(VersionUtils::convertTagToVersion).collect(Collectors.toSet());
}
- return versions;
+ return new ArrayList<>(versions);
}
- @Override
- public String buildMavenMetadataUrlFromArtifact(String repoUrl, String groupId, String artifactID) {
- if (StringUtils.isAnyBlank(groupId, artifactID)) {
- return StringUtils.EMPTY;
+ public List getMavenArtifactsFromProductJsonByVersion(String version, String productId) {
+ ProductJsonContent productJson = productJsonRepo.findByProductIdAndVersion(productId, version);
+ if (Objects.isNull(productJson) || StringUtils.isBlank(productJson.getContent())) {
+ return new ArrayList<>();
}
- repoUrl = Optional.ofNullable(repoUrl).orElse(MavenConstants.DEFAULT_IVY_MAVEN_BASE_URL);
- groupId = groupId.replace(CommonConstants.DOT_SEPARATOR, CommonConstants.SLASH);
- return String.format(MavenConstants.METADATA_URL_FORMAT, repoUrl, groupId, artifactID);
- }
-
- public List getProductJsonByVersion(String version) {
- List result = new ArrayList<>();
- String versionTag = getVersionTag(version);
- productJsonFilePath = buildProductJsonFilePath();
+ InputStream contentStream = IOUtils.toInputStream(productJson.getContent(), StandardCharsets.UTF_8);
try {
- GHContent productJsonContent = gitHubService.getContentFromGHRepoAndTag(repoName, productJsonFilePath,
- versionTag);
- if (Objects.isNull(productJsonContent)) {
- return result;
- }
- result = gitHubService.convertProductJsonToMavenProductInfo(productJsonContent);
+ return gitHubService.extractMavenArtifactsFromContentStream(contentStream);
} catch (IOException e) {
- log.warn("Can not get the product.json from repo {} by path in {} version {}", repoName, productJsonFilePath,
- versionTag);
+ log.error("Can not get maven artifacts from Product.json of {} - version {}:{}", productId, version,
+ e.getMessage());
+ return new ArrayList<>();
}
- return result;
- }
-
- public String getVersionTag(String version) {
- String versionTag = "v" + version;
- if (NonStandardProduct.PORTAL.getId().equals(productId)) {
- versionTag = version;
- }
- return versionTag;
- }
-
- public String buildProductJsonFilePath() {
- String pathToProductFolderFromTagContent = metaProductArtifact.getArtifactId();
- if (NonStandardProduct.DEFAULT != NonStandardProduct.findById(productId)) {
- pathToProductFolderFromTagContent = GitHubUtils.getNonStandardProductFilePath(productId);
- }
- productJsonFilePath = String.format(GitHubConstants.PRODUCT_JSON_FILE_PATH_FORMAT,
- pathToProductFolderFromTagContent);
- return productJsonFilePath;
}
- public MavenArtifactModel convertMavenArtifactToModel(MavenArtifact artifact, String version) {
+ public MavenArtifactModel convertMavenArtifactToModel(MavenArtifact artifact, String version,
+ List archivedArtifacts) {
String artifactName = artifact.getName();
if (StringUtils.isBlank(artifactName)) {
artifactName = GitHubUtils.convertArtifactIdToName(artifact.getArtifactId());
}
- artifact.setType(Optional.ofNullable(artifact.getType()).orElse("iar"));
+ artifact.setType(StringUtils.defaultIfBlank(artifact.getType(), ProductJsonConstants.DEFAULT_PRODUCT_TYPE));
artifactName = String.format(MavenConstants.ARTIFACT_NAME_FORMAT, artifactName, artifact.getType());
- return new MavenArtifactModel(artifactName, buildDownloadUrlFromArtifactAndVersion(artifact, version),
- artifact.getIsProductArtifact());
+ return new MavenArtifactModel(artifactName,
+ buildDownloadUrlFromArtifactAndVersion(artifact, version, archivedArtifacts), artifact.getIsProductArtifact());
}
- public List convertMavenArtifactsToModels(List artifacts, String version) {
+ public List convertArtifactsToModels(List artifacts, String version,
+ Map> archivedArtifactsMap) {
List results = new ArrayList<>();
if (!CollectionUtils.isEmpty(artifacts)) {
for (MavenArtifact artifact : artifacts) {
- MavenArtifactModel mavenArtifactModel = convertMavenArtifactToModel(artifact, version);
+ MavenArtifactModel mavenArtifactModel = convertMavenArtifactToModel(artifact, version,
+ archivedArtifactsMap.get(artifact.getArtifactId()));
results.add(mavenArtifactModel);
}
}
return results;
}
- public String buildDownloadUrlFromArtifactAndVersion(MavenArtifact artifact, String version) {
+ public String buildDownloadUrlFromArtifactAndVersion(MavenArtifact artifact, String version,
+ List archivedArtifacts) {
String groupIdByVersion = artifact.getGroupId();
String artifactIdByVersion = artifact.getArtifactId();
- String repoUrl = Optional.ofNullable(artifact.getRepoUrl()).orElse(MavenConstants.DEFAULT_IVY_MAVEN_BASE_URL);
- ArchivedArtifact archivedArtifactBestMatchVersion = findArchivedArtifactInfoBestMatchWithVersion(
- artifact.getArtifactId(), version);
+ String repoUrl = StringUtils.defaultIfBlank(artifact.getRepoUrl(), MavenConstants.DEFAULT_IVY_MAVEN_BASE_URL);
+ ArchivedArtifact archivedArtifactBestMatchVersion = findArchivedArtifactInfoBestMatchWithVersion(version,
+ archivedArtifacts);
if (Objects.nonNull(archivedArtifactBestMatchVersion)) {
groupIdByVersion = archivedArtifactBestMatchVersion.getGroupId();
artifactIdByVersion = archivedArtifactBestMatchVersion.getArtifactId();
}
groupIdByVersion = groupIdByVersion.replace(CommonConstants.DOT_SEPARATOR, CommonConstants.SLASH);
- return String.format(MavenConstants.ARTIFACT_DOWNLOAD_URL_FORMAT, repoUrl, groupIdByVersion, artifactIdByVersion,
- version, artifactIdByVersion, version, artifact.getType());
+ String artifactFileName = String.format(MavenConstants.ARTIFACT_FILE_NAME_FORMAT, artifactIdByVersion, version,
+ artifact.getType());
+ return String.join(CommonConstants.SLASH, repoUrl, groupIdByVersion, artifactIdByVersion, version,
+ artifactFileName);
}
- public ArchivedArtifact findArchivedArtifactInfoBestMatchWithVersion(String artifactId, String version) {
- List archivedArtifacts = archivedArtifactsMap.get(artifactId);
-
+ public ArchivedArtifact findArchivedArtifactInfoBestMatchWithVersion(String version,
+ List archivedArtifacts) {
if (CollectionUtils.isEmpty(archivedArtifacts)) {
return null;
}
- for (ArchivedArtifact archivedArtifact : archivedArtifacts) {
- if (latestVersionComparator.compare(archivedArtifact.getLastVersion(), version) <= 0) {
- return archivedArtifact;
- }
- }
- return null;
- }
-
- public String getRepoNameFromMarketRepo(String fullRepoName) {
- String[] repoNamePart = fullRepoName.split("/");
- return repoNamePart[repoNamePart.length - 1];
+ return archivedArtifacts.stream()
+ .filter(archivedArtifact -> MavenVersionComparator.compare(archivedArtifact.getLastVersion(), version) >= 0)
+ .findAny().orElse(null);
}
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/util/VersionUtils.java b/marketplace-service/src/main/java/com/axonivy/market/util/VersionUtils.java
index ea4bb7963..6164e2dc1 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/util/VersionUtils.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/util/VersionUtils.java
@@ -1,6 +1,7 @@
package com.axonivy.market.util;
import com.axonivy.market.comparator.LatestVersionComparator;
+import com.axonivy.market.comparator.MavenVersionComparator;
import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.constants.MavenConstants;
@@ -25,7 +26,7 @@ private VersionUtils() {
public static List getVersionsToDisplay(List versions, Boolean isShowDevVersion, String designerVersion) {
Stream versionStream = versions.stream();
if (StringUtils.isNotBlank(designerVersion)) {
- return versionStream.filter(version -> isMatchWithDesignerVersion(version, designerVersion)).toList();
+ return versionStream.filter(version -> isMatchWithDesignerVersion(version, designerVersion)).sorted(new LatestVersionComparator()).toList();
}
if (BooleanUtils.isTrue(isShowDevVersion)) {
return versionStream.filter(version -> isOfficialVersionOrUnReleasedDevVersion(versions, version))
@@ -37,8 +38,7 @@ public static List getVersionsToDisplay(List versions, Boolean i
public static String getBestMatchVersion(List versions, String designerVersion) {
String bestMatchVersion = versions.stream().filter(version -> StringUtils.equals(version, designerVersion)).findAny().orElse(null);
if(StringUtils.isBlank(bestMatchVersion)){
- LatestVersionComparator comparator = new LatestVersionComparator();
- bestMatchVersion = versions.stream().filter(version -> comparator.compare(version, designerVersion) > 0 && isReleasedVersion(version)).findAny().orElse(null);
+ bestMatchVersion = versions.stream().filter(version -> MavenVersionComparator.compare(version, designerVersion) < 0 && isReleasedVersion(version)).findAny().orElse(null);
}
if (StringUtils.isBlank(bestMatchVersion)) {
bestMatchVersion = versions.stream().filter(VersionUtils::isReleasedVersion).findAny().orElse(CollectionUtils.firstElement(versions));
@@ -51,7 +51,9 @@ public static boolean isOfficialVersionOrUnReleasedDevVersion(List versi
return true;
}
String bugfixVersion;
- if (isSnapshotVersion(version)) {
+ if (!isValidFormatReleasedVersion(version)) {
+ return false;
+ } else if (isSnapshotVersion(version)) {
bugfixVersion = getBugfixVersion(version.replace(MavenConstants.SNAPSHOT_RELEASE_POSTFIX, StringUtils.EMPTY));
} else {
bugfixVersion = getBugfixVersion(version.split(MavenConstants.SPRINT_RELEASE_POSTFIX)[0]);
@@ -69,8 +71,12 @@ public static boolean isSprintVersion(String version) {
return version.contains(MavenConstants.SPRINT_RELEASE_POSTFIX);
}
+ public static boolean isValidFormatReleasedVersion(String version) {
+ return StringUtils.isNumeric(version.split(MavenConstants.MAIN_VERSION_REGEX)[0]);
+ }
+
public static boolean isReleasedVersion(String version) {
- return !(isSprintVersion(version) || isSnapshotVersion(version));
+ return !(isSprintVersion(version) || isSnapshotVersion(version)) && isValidFormatReleasedVersion(version);
}
public static boolean isMatchWithDesignerVersion(String version, String designerVersion) {
diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/VersionServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/VersionServiceImplTest.java
index a45e845fa..4efe92693 100644
--- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/VersionServiceImplTest.java
+++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/VersionServiceImplTest.java
@@ -1,5 +1,6 @@
package com.axonivy.market.service.impl;
+import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.MavenConstants;
import com.axonivy.market.entity.MavenArtifactModel;
import com.axonivy.market.entity.MavenArtifactVersion;
@@ -8,26 +9,21 @@
import com.axonivy.market.github.model.ArchivedArtifact;
import com.axonivy.market.github.model.MavenArtifact;
import com.axonivy.market.github.service.GHAxonIvyProductRepoService;
-import com.axonivy.market.model.MavenArtifactVersionModel;
import com.axonivy.market.model.VersionAndUrlModel;
import com.axonivy.market.repository.MavenArtifactVersionRepository;
import com.axonivy.market.repository.ProductJsonContentRepository;
+import com.axonivy.market.repository.ProductModuleContentRepository;
import com.axonivy.market.repository.ProductRepository;
-import com.axonivy.market.util.XmlReaderUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.assertj.core.api.Fail;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.kohsuke.github.GHContent;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.test.util.ReflectionTestUtils;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
@@ -37,15 +33,13 @@
import java.util.Optional;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class VersionServiceImplTest {
- private String repoName;
private Map> archivedArtifactsMap;
private List artifactsFromMeta;
- private MavenArtifactVersion proceedDataCache;
private MavenArtifact metaProductArtifact;
@Spy
@InjectMocks
@@ -63,17 +57,14 @@ class VersionServiceImplTest {
@Mock
private ProductJsonContentRepository productJsonContentRepository;
+ @Mock
+ private ProductModuleContentRepository productModuleContentRepository;
+
@BeforeEach()
void prepareBeforeTest() {
archivedArtifactsMap = new HashMap<>();
artifactsFromMeta = new ArrayList<>();
metaProductArtifact = new MavenArtifact();
- proceedDataCache = new MavenArtifactVersion();
- repoName = StringUtils.EMPTY;
- ReflectionTestUtils.setField(versionService, "archivedArtifactsMap", archivedArtifactsMap);
- ReflectionTestUtils.setField(versionService, "artifactsFromMeta", artifactsFromMeta);
- ReflectionTestUtils.setField(versionService, "proceedDataCache", proceedDataCache);
- ReflectionTestUtils.setField(versionService, "metaProductArtifact", metaProductArtifact);
}
private void setUpArtifactFromMeta() {
@@ -93,13 +84,12 @@ void testGetArtifactsAndVersionToDisplay() {
String productId = "adobe-acrobat-sign-connector";
String targetVersion = "10.0.10";
setUpArtifactFromMeta();
- when(versionService.getProductMetaArtifacts(Mockito.anyString())).thenReturn(artifactsFromMeta);
- when(versionService.getVersionsFromMavenArtifacts()).thenReturn(
- List.of(targetVersion));
+ when(versionService.getArtifactsFromMeta(Mockito.anyString())).thenReturn(artifactsFromMeta);
+ when(productModuleContentRepository.findTagsByProductId(productId)).thenReturn(List.of("v10.0.10"));
when(mavenArtifactVersionRepository.findById(Mockito.anyString())).thenReturn(Optional.empty());
ArrayList artifactsInVersion = new ArrayList<>();
artifactsInVersion.add(new MavenArtifactModel());
- when(versionService.convertMavenArtifactsToModels(Mockito.anyList(), Mockito.anyString())).thenReturn(
+ when(versionService.convertArtifactsToModels(Mockito.anyList(), Mockito.anyString(), Mockito.any())).thenReturn(
artifactsInVersion);
Assertions.assertEquals(1, versionService.getArtifactsAndVersionToDisplay(productId, false, targetVersion).size());
@@ -110,218 +100,58 @@ void testGetArtifactsAndVersionToDisplay() {
}
@Test
- void testHandleArtifactForVersionToDisplay() {
- String newVersionDetected = "10.0.10";
- List result = new ArrayList<>();
- List versionsToDisplay = List.of(newVersionDetected);
- ReflectionTestUtils.setField(versionService, "productId", "adobe-acrobat-connector");
- Assertions.assertTrue(versionService.handleArtifactForVersionToDisplay(versionsToDisplay, result));
- Assertions.assertEquals(1, result.size());
- Assertions.assertEquals(newVersionDetected, result.get(0).getVersion());
- Assertions.assertEquals(0, result.get(0).getArtifactsByVersion().size());
-
- result = new ArrayList<>();
- ArrayList artifactsInVersion = new ArrayList<>();
- artifactsInVersion.add(new MavenArtifactModel());
- when(versionService.convertMavenArtifactsToModels(Mockito.anyList(), Mockito.anyString())).thenReturn(
- artifactsInVersion);
- Assertions.assertFalse(versionService.handleArtifactForVersionToDisplay(versionsToDisplay, result));
- Assertions.assertEquals(1, result.size());
- Assertions.assertEquals(1, result.get(0).getArtifactsByVersion().size());
- }
-
- @Test
- void testGetProductMetaArtifacts() {
+ void testGetArtifactsFromMeta() {
Product product = new Product();
MavenArtifact artifact1 = new MavenArtifact();
MavenArtifact artifact2 = new MavenArtifact();
List artifacts = List.of(artifact1, artifact2);
product.setArtifacts(artifacts);
when(productRepository.findById(Mockito.anyString())).thenReturn(Optional.of(product));
- List result = versionService.getProductMetaArtifacts("portal");
+ List result = versionService.getArtifactsFromMeta("portal");
Assertions.assertEquals(artifacts, result);
- Assertions.assertNull(versionService.getRepoName());
-
- product.setRepositoryName("/market/portal");
- versionService.getProductMetaArtifacts("portal");
- Assertions.assertEquals("portal", versionService.getRepoName());
- }
-
- @Test
- void testUpdateArtifactsInVersionWithProductArtifact() {
- String version = "10.0.10";
- ReflectionTestUtils.setField(versionService, "productId", "adobe-acrobat-connector");
- MavenArtifactModel artifactModel = new MavenArtifactModel();
- List mockMavenArtifactModels = List.of(artifactModel);
- when(versionService.getProductJsonByVersion(Mockito.anyString())).thenReturn(List.of(new MavenArtifact()));
- when(versionService.convertMavenArtifactsToModels(Mockito.anyList(), Mockito.anyString())).thenReturn(
- mockMavenArtifactModels);
- Assertions.assertEquals(mockMavenArtifactModels,
- versionService.updateArtifactsInVersionWithProductArtifact(version));
- Assertions.assertEquals(1, proceedDataCache.getVersions().size());
- Assertions.assertEquals(1, proceedDataCache.getProductArtifactWithVersionReleased().size());
- Assertions.assertEquals(version, proceedDataCache.getVersions().get(0));
- }
-
- @Test
- void testSanitizeMetaArtifactBeforeHandle() {
- setUpArtifactFromMeta();
- String groupId = "com.axonivy.connector.adobe.acrobat.sign";
- String archivedArtifactId1 = "adobe-acrobat-sign-connector";
- String archivedArtifactId2 = "adobe-acrobat-sign-connector";
- ArchivedArtifact archivedArtifact1 = new ArchivedArtifact("10.0.10", groupId, archivedArtifactId1);
- ArchivedArtifact archivedArtifact2 = new ArchivedArtifact("10.0.20", groupId, archivedArtifactId2);
- artifactsFromMeta.get(1).setArchivedArtifacts(List.of(archivedArtifact2, archivedArtifact1));
-
- versionService.sanitizeMetaArtifactBeforeHandle();
- String artifactId = "adobe-acrobat-sign-connector";
-
- Assertions.assertEquals(1, artifactsFromMeta.size());
- Assertions.assertEquals(1, archivedArtifactsMap.size());
- Assertions.assertEquals(2, archivedArtifactsMap.get(artifactId).size());
- Assertions.assertEquals(archivedArtifact1, archivedArtifactsMap.get(artifactId).get(0));
- }
-
-
- @Test
- void getVersionsFromMavenArtifacts() {
- String repoUrl = "https://maven.axonivy.com";
- String groupId = "com.axonivy.connector.adobe.acrobat.sign";
- String artifactId = "adobe-acrobat-sign-connector";
- String archivedArtifactId = "adobe-sign-connector";
- artifactsFromMeta.add(new MavenArtifact(repoUrl, null, groupId, artifactId, null, null, null, null));
- ArrayList versionFromArtifact = new ArrayList<>();
- versionFromArtifact.add("10.0.6");
- versionFromArtifact.add("10.0.5");
- versionFromArtifact.add("10.0.4");
-
- when(versionService.getVersionsFromArtifactDetails(repoUrl, groupId, artifactId)).thenReturn(versionFromArtifact);
- Assertions.assertEquals(versionService.getVersionsFromMavenArtifacts(), versionFromArtifact);
-
- List archivedArtifacts = List.of(new ArchivedArtifact("10.0.9", groupId, archivedArtifactId));
- ArrayList versionFromArchivedArtifact = new ArrayList<>();
- versionFromArchivedArtifact.add("10.0.3");
- versionFromArchivedArtifact.add("10.0.2");
- versionFromArchivedArtifact.add("10.0.1");
- artifactsFromMeta.get(0).setArchivedArtifacts(archivedArtifacts);
- when(versionService.getVersionsFromArtifactDetails(repoUrl, groupId, archivedArtifactId)).thenReturn(
- versionFromArchivedArtifact);
- versionFromArtifact.addAll(versionFromArchivedArtifact);
- Assertions.assertEquals(versionService.getVersionsFromMavenArtifacts(), versionFromArtifact);
}
@Test
- void testGetVersionsFromArtifactDetails() {
+ void testGetMavenArtifactsFromProductJsonByVersion() throws IOException {
+ when(productJsonContentRepository.findByProductIdAndVersion("adobe-acrobat-connector", "10.0.20")).thenReturn(null);
- String repoUrl = "https://maven.axonivy.com";
- String groupId = "com.axonivy.connector.adobe.acrobat.sign";
- String artifactId = "adobe-acrobat-sign-connector";
+ Assertions.assertEquals(0,
+ versionService.getMavenArtifactsFromProductJsonByVersion("10.0.20", "adobe-acrobat-connector").size());
- ArrayList versionFromArtifact = new ArrayList<>();
- versionFromArtifact.add("10.0.16");
- versionFromArtifact.add("10.0.18");
- versionFromArtifact.add("10.0.19");
- versionFromArtifact.add("10.0.20");
- versionFromArtifact.add("10.0.21");
- versionFromArtifact.add("10.0.22");
- versionFromArtifact.add("10.0.23");
- versionFromArtifact.add("10.0.24");
- versionFromArtifact.add("10.0.25");
-
- try (MockedStatic xmlUtils = Mockito.mockStatic(XmlReaderUtils.class)) {
- xmlUtils.when(() -> XmlReaderUtils.readXMLFromUrl(Mockito.anyString())).thenReturn(versionFromArtifact);
- Assertions.assertEquals(versionService.getVersionsFromArtifactDetails(repoUrl, null, null), new ArrayList<>());
- Assertions.assertEquals(versionService.getVersionsFromArtifactDetails(repoUrl, groupId, artifactId),
- versionFromArtifact);
- }
- }
+ String jsonContent = "{ \"installers\": [{ \"id\": \"maven-import\", \"data\": { \"repositories\": [{ \"url\": \"http://repo.url\" }], \"projects\": [], \"dependencies\": [] } }] }";
+ ProductJsonContent productJson = new ProductJsonContent();
+ productJson.setContent(jsonContent);
+ when(productJsonContentRepository.findByProductIdAndVersion("adobe-acrobat-connector", "10.0.20")).thenReturn(
+ productJson);
- @Test
- void testBuildMavenMetadataUrlFromArtifact() {
- String repoUrl = "https://maven.axonivy.com";
- String groupId = "com.axonivy.connector.adobe.acrobat.sign";
- String artifactId = "adobe-acrobat-sign-connector";
- String metadataUrl = "https://maven.axonivy.com/com/axonivy/connector/adobe/acrobat/sign/adobe-acrobat-sign-connector/maven-metadata.xml";
- Assertions.assertEquals(StringUtils.EMPTY,
- versionService.buildMavenMetadataUrlFromArtifact(repoUrl, null, artifactId));
- Assertions.assertEquals(StringUtils.EMPTY, versionService.buildMavenMetadataUrlFromArtifact(repoUrl, groupId, null),
- StringUtils.EMPTY);
- Assertions.assertEquals(metadataUrl,
- versionService.buildMavenMetadataUrlFromArtifact(repoUrl, groupId, artifactId));
- }
+ List expectedArtifacts = new ArrayList<>();
+ when(gitHubService.extractMavenArtifactsFromContentStream(Mockito.any())).thenReturn(expectedArtifacts);
- @Test
- void testGetProductJsonByVersion() {
- String targetArtifactId = "adobe-acrobat-sign-connector";
- String targetGroupId = "com.axonivy.connector.adobe.acrobat";
- GHContent mockContent = mock(GHContent.class);
- repoName = "adobe-acrobat-sign-connector";
- ReflectionTestUtils.setField(versionService, "repoName", repoName);
- ReflectionTestUtils.setField(versionService, "productId", "adobe-acrobat-connector");
- MavenArtifact productArtifact = new MavenArtifact("https://maven.axonivy.com", null, targetGroupId,
- targetArtifactId, "iar", null, true, null);
-
- metaProductArtifact.setRepoUrl("https://maven.axonivy.com");
- metaProductArtifact.setGroupId(targetGroupId);
- metaProductArtifact.setArtifactId(targetArtifactId);
- when(gitHubService.getContentFromGHRepoAndTag(Mockito.anyString(), Mockito.anyString(),
- Mockito.anyString())).thenReturn(null);
- Assertions.assertEquals(0, versionService.getProductJsonByVersion("10.0.20").size());
-
- metaProductArtifact.setGroupId("com.axonivy.connector.adobe.acrobat.connector");
- when(gitHubService.getContentFromGHRepoAndTag(Mockito.anyString(), Mockito.anyString(),
- Mockito.anyString())).thenReturn(mockContent);
-
- try {
- when(gitHubService.convertProductJsonToMavenProductInfo(mockContent)).thenReturn(List.of(productArtifact));
- Assertions.assertEquals(1, versionService.getProductJsonByVersion("10.0.20").size());
-
- when(gitHubService.convertProductJsonToMavenProductInfo(mockContent)).thenThrow(
- new IOException("Mock IO Exception"));
- Assertions.assertEquals(0, versionService.getProductJsonByVersion("10.0.20").size());
- } catch (IOException e) {
- Fail.fail("Mock setup should not throw an exception");
- }
- }
+ List actualArtifacts = versionService.getMavenArtifactsFromProductJsonByVersion("10.0.20",
+ "adobe-acrobat-connector");
- @Test
- void testConvertMavenArtifactToModel() {
- String downloadUrl = "https://maven.axonivy.com/com/axonivy/connector/adobe/acrobat/sign/adobe-acrobat-sign-connector/10.0.21/adobe-acrobat-sign-connector-10.0.21.iar";
- String artifactName = "Adobe Acrobat Sign Connector (iar)";
+ Assertions.assertEquals(expectedArtifacts, actualArtifacts);
+ verify(productJsonContentRepository, Mockito.times(2)).findByProductIdAndVersion("adobe-acrobat-connector",
+ "10.0.20");
+ verify(gitHubService).extractMavenArtifactsFromContentStream(Mockito.any());
- MavenArtifact targetArtifact = new MavenArtifact(null, null, "com.axonivy.connector.adobe.acrobat.sign",
- "adobe-acrobat-sign-connector", null, null, null, null);
-
- // Assert case handle artifact without name
- MavenArtifactModel result = versionService.convertMavenArtifactToModel(targetArtifact, "10.0.21");
- MavenArtifactModel expectedResult = new MavenArtifactModel(artifactName, downloadUrl, null);
- Assertions.assertEquals(expectedResult.getName(), result.getName());
- Assertions.assertEquals(expectedResult.getDownloadUrl(), result.getDownloadUrl());
-
- // Assert case handle artifact with name
- artifactName = "Adobe Connector";
- String expectedArtifactName = "Adobe Connector (iar)";
- targetArtifact.setName(artifactName);
- result = versionService.convertMavenArtifactToModel(targetArtifact, "10.0.21");
- expectedResult = new MavenArtifactModel(artifactName, downloadUrl, null);
- Assertions.assertEquals(expectedArtifactName, result.getName());
- Assertions.assertEquals(expectedResult.getDownloadUrl(), result.getDownloadUrl());
}
@Test
- void testConvertMavenArtifactsToModels() {
+ void testConvertArtifactsToModels() {
// Assert case param is empty
- List result = versionService.convertMavenArtifactsToModels(Collections.emptyList(), "10.0.21");
+ List result = versionService.convertArtifactsToModels(Collections.emptyList(), "10.0.21",
+ new HashMap<>());
Assertions.assertEquals(Collections.emptyList(), result);
// Assert case param is null
- result = versionService.convertMavenArtifactsToModels(null, "10.0.21");
+ result = versionService.convertArtifactsToModels(null, "10.0.21", new HashMap<>());
Assertions.assertEquals(Collections.emptyList(), result);
// Assert case param is a list with existed element
MavenArtifact targetArtifact = new MavenArtifact(null, null, "com.axonivy.connector.adobe.acrobat.sign",
"adobe-acrobat-sign-connector", null, null, null, null);
- result = versionService.convertMavenArtifactsToModels(List.of(targetArtifact), "10.0.21");
+ result = versionService.convertArtifactsToModels(List.of(targetArtifact), "10.0.21", new HashMap<>());
Assertions.assertEquals(1, result.size());
}
@@ -333,12 +163,15 @@ void testBuildDownloadUrlFromArtifactAndVersion() {
MavenArtifact targetArtifact = new MavenArtifact(null, null, targetGroupId, targetArtifactId, "iar", null, null,
null);
String targetVersion = "10.0.10";
+ String artifactFileName = String.format(MavenConstants.ARTIFACT_FILE_NAME_FORMAT, targetArtifactId, targetVersion,
+ "iar");
// Assert case without archived artifact
- String expectedResult = String.format(MavenConstants.ARTIFACT_DOWNLOAD_URL_FORMAT,
+ String expectedResult = String.join(CommonConstants.SLASH,
MavenConstants.DEFAULT_IVY_MAVEN_BASE_URL, "com/axonivy/connector", targetArtifactId, targetVersion,
- targetArtifactId, targetVersion, "iar");
- String result = versionService.buildDownloadUrlFromArtifactAndVersion(targetArtifact, targetVersion);
+ artifactFileName);
+ String result = versionService.buildDownloadUrlFromArtifactAndVersion(targetArtifact, targetVersion,
+ Collections.emptyList());
Assertions.assertEquals(expectedResult, result);
// Assert case with artifact not match & use custom repo
@@ -346,12 +179,15 @@ void testBuildDownloadUrlFromArtifactAndVersion() {
"adobe-connector");
ArchivedArtifact adobeArchivedArtifactVersion8 = new ArchivedArtifact("10.0.8", "com.axonivy.adobe.sign.connector",
"adobe-sign-connector");
- archivedArtifactsMap.put(targetArtifactId, List.of(adobeArchivedArtifactVersion9, adobeArchivedArtifactVersion8));
String customRepoUrl = "https://nexus.axonivy.com";
targetArtifact.setRepoUrl(customRepoUrl);
- result = versionService.buildDownloadUrlFromArtifactAndVersion(targetArtifact, targetVersion);
- expectedResult = String.format(MavenConstants.ARTIFACT_DOWNLOAD_URL_FORMAT, customRepoUrl, "com/axonivy/connector",
- targetArtifactId, targetVersion, targetArtifactId, targetVersion, "iar");
+ result = versionService.buildDownloadUrlFromArtifactAndVersion(targetArtifact, targetVersion,
+ List.of(adobeArchivedArtifactVersion9, adobeArchivedArtifactVersion8));
+ artifactFileName = String.format(MavenConstants.ARTIFACT_FILE_NAME_FORMAT, targetArtifactId, targetVersion,
+ "iar");
+ expectedResult = String.join(CommonConstants.SLASH,
+ customRepoUrl, "com/axonivy/connector", targetArtifactId, targetVersion,
+ artifactFileName);
Assertions.assertEquals(expectedResult, result);
// Assert case with artifact got matching archived artifact & use custom file
@@ -359,9 +195,13 @@ void testBuildDownloadUrlFromArtifactAndVersion() {
String customType = "zip";
targetArtifact.setType(customType);
targetVersion = "10.0.9";
- result = versionService.buildDownloadUrlFromArtifactAndVersion(targetArtifact, "10.0.9");
- expectedResult = String.format(MavenConstants.ARTIFACT_DOWNLOAD_URL_FORMAT, customRepoUrl,
- "com/axonivy/adobe/connector", "adobe-connector", targetVersion, "adobe-connector", targetVersion, customType);
+ result = versionService.buildDownloadUrlFromArtifactAndVersion(targetArtifact, "10.0.9",
+ List.of(adobeArchivedArtifactVersion9, adobeArchivedArtifactVersion8));
+ artifactFileName = String.format(MavenConstants.ARTIFACT_FILE_NAME_FORMAT, "adobe-connector", targetVersion,
+ customType);
+ expectedResult = String.join(CommonConstants.SLASH,
+ customRepoUrl, "com/axonivy/adobe/connector", "adobe-connector", targetVersion,
+ artifactFileName);
Assertions.assertEquals(expectedResult, result);
}
@@ -369,8 +209,8 @@ void testBuildDownloadUrlFromArtifactAndVersion() {
void testFindArchivedArtifactInfoBestMatchWithVersion() {
String targetArtifactId = "adobe-acrobat-sign-connector";
String targetVersion = "10.0.10";
- ArchivedArtifact result = versionService.findArchivedArtifactInfoBestMatchWithVersion(targetArtifactId,
- targetVersion);
+ ArchivedArtifact result = versionService.findArchivedArtifactInfoBestMatchWithVersion(
+ targetVersion, Collections.emptyList());
Assertions.assertNull(result);
// Assert case with target version higher than all of latest version from
@@ -383,12 +223,14 @@ void testFindArchivedArtifactInfoBestMatchWithVersion() {
archivedArtifacts.add(adobeArchivedArtifactVersion8);
archivedArtifacts.add(adobeArchivedArtifactVersion9);
archivedArtifactsMap.put(targetArtifactId, archivedArtifacts);
- result = versionService.findArchivedArtifactInfoBestMatchWithVersion(targetArtifactId, targetVersion);
+ result = versionService.findArchivedArtifactInfoBestMatchWithVersion(targetVersion,
+ archivedArtifacts);
Assertions.assertNull(result);
// Assert case with target version less than all of latest version from archived
// artifact list
- result = versionService.findArchivedArtifactInfoBestMatchWithVersion(targetArtifactId, "10.0.7");
+ result = versionService.findArchivedArtifactInfoBestMatchWithVersion("10.0.7",
+ archivedArtifacts);
Assertions.assertEquals(adobeArchivedArtifactVersion8, result);
// Assert case with target version is in range of archived artifact list
@@ -396,26 +238,11 @@ void testFindArchivedArtifactInfoBestMatchWithVersion() {
"adobe-sign-connector");
archivedArtifactsMap.get(targetArtifactId).add(adobeArchivedArtifactVersion10);
- result = versionService.findArchivedArtifactInfoBestMatchWithVersion(targetArtifactId, targetVersion);
+ result = versionService.findArchivedArtifactInfoBestMatchWithVersion(targetVersion,
+ archivedArtifacts);
Assertions.assertEquals(adobeArchivedArtifactVersion10, result);
}
- @Test
- void testGetRepoNameFromMarketRepo() {
- String defaultRepositoryName = "market/adobe-acrobat-connector";
- String expectedRepoName = "adobe-acrobat-connector";
- String result = versionService.getRepoNameFromMarketRepo(defaultRepositoryName);
- Assertions.assertEquals(expectedRepoName, result);
-
- defaultRepositoryName = "market/utils/adobe-acrobat-connector";
- result = versionService.getRepoNameFromMarketRepo(defaultRepositoryName);
- Assertions.assertEquals(expectedRepoName, result);
-
- defaultRepositoryName = "adobe-acrobat-connector";
- result = versionService.getRepoNameFromMarketRepo(defaultRepositoryName);
- Assertions.assertEquals(expectedRepoName, result);
- }
-
@Test
void testGetVersionsForDesigner() {
Mockito.when(productRepository.getReleasedVersionsById(anyString()))
@@ -425,10 +252,10 @@ void testGetVersionsForDesigner() {
Assertions.assertEquals(result.stream().map(VersionAndUrlModel::getVersion).toList(),
List.of("11.3.0", "11.1.1", "11.1.0", "10.0.2"));
- Assertions.assertEquals("/api/product-details/11.3.0/11.3.0/json", result.get(0).getUrl());
- Assertions.assertEquals("/api/product-details/11.3.0/11.1.1/json", result.get(1).getUrl());
- Assertions.assertEquals("/api/product-details/11.3.0/11.1.0/json", result.get(2).getUrl());
- Assertions.assertEquals("/api/product-details/11.3.0/10.0.2/json", result.get(3).getUrl());
+ Assertions.assertTrue(result.get(0).getUrl().endsWith("/api/product-details/11.3.0/11.3.0/json"));
+ Assertions.assertTrue(result.get(1).getUrl().endsWith("/api/product-details/11.3.0/11.1.1/json"));
+ Assertions.assertTrue(result.get(2).getUrl().endsWith("/api/product-details/11.3.0/11.1.0/json"));
+ Assertions.assertTrue(result.get(3).getUrl().endsWith("/api/product-details/11.3.0/10.0.2/json"));
}
@Test
@@ -475,4 +302,17 @@ void testGetProductJsonContentByIdAndVersion_noResult() {
Assertions.assertEquals(new HashMap<>(), result);
}
+
+ @Test
+ void testgetPersistedVersions() {
+ String mockProductId = "portal";
+ String mockVersion = "10.0.1";
+ Product mocProduct = new Product();
+ mocProduct.setId(mockProductId);
+ mocProduct.setReleasedVersions(List.of(mockVersion));
+ when(productRepository.findById(mockProductId)).thenReturn(Optional.of(mocProduct));
+ Assertions.assertEquals(1, versionService.getPersistedVersions(mockProductId).size());
+ Assertions.assertEquals(mockVersion, versionService.getPersistedVersions(mockProductId).get(0));
+
+ }
}
diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts
index a6a59488a..a791b9730 100644
--- a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts
+++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts
@@ -99,10 +99,8 @@ export class ProductDetailVersionActionComponent implements AfterViewInit {
artifact.label = artifact.name;
}
});
- if (this.artifacts().length !== 0) {
- this.selectedArtifactName = this.artifacts()[0].name ?? '';
- this.selectedArtifact = this.artifacts()[0].downloadUrl ?? '';
- }
+ this.selectedArtifactName = this.artifacts()[0]?.name ?? '';
+ this.selectedArtifact = this.artifacts()[0]?.downloadUrl ?? '';
}
onSelectVersionInDesigner(version: string) {
From a68837da966979d0db6e85cfeb99cf4a7df76a94 Mon Sep 17 00:00:00 2001
From: Hoan Nguyen
Date: Fri, 20 Sep 2024 16:41:32 +0700
Subject: [PATCH 06/20] Introduced editor config
---
marketplace-service/.editorconfig | 687 ++++++++++++++++++++++++++++++
1 file changed, 687 insertions(+)
create mode 100644 marketplace-service/.editorconfig
diff --git a/marketplace-service/.editorconfig b/marketplace-service/.editorconfig
new file mode 100644
index 000000000..9b7bd7afe
--- /dev/null
+++ b/marketplace-service/.editorconfig
@@ -0,0 +1,687 @@
+[*]
+charset = utf-8
+end_of_line = crlf
+indent_size = 4
+indent_style = space
+insert_final_newline = false
+max_line_length = 120
+tab_width = 4
+ij_continuation_indent_size = 8
+ij_formatter_off_tag = @formatter:off
+ij_formatter_on_tag = @formatter:on
+ij_formatter_tags_enabled = true
+ij_smart_tabs = false
+ij_visual_guides =
+ij_wrap_on_typing = true
+
+[*.dcl]
+ij_declarative_keep_indents_on_empty_lines = false
+
+[*.java]
+indent_size = 2
+tab_width = 2
+ij_continuation_indent_size = 4
+ij_java_align_consecutive_assignments = false
+ij_java_align_consecutive_variable_declarations = false
+ij_java_align_group_field_declarations = false
+ij_java_align_multiline_annotation_parameters = false
+ij_java_align_multiline_array_initializer_expression = false
+ij_java_align_multiline_assignment = false
+ij_java_align_multiline_binary_operation = false
+ij_java_align_multiline_chained_methods = false
+ij_java_align_multiline_deconstruction_list_components = true
+ij_java_align_multiline_extends_list = false
+ij_java_align_multiline_for = true
+ij_java_align_multiline_method_parentheses = false
+ij_java_align_multiline_parameters = false
+ij_java_align_multiline_parameters_in_calls = false
+ij_java_align_multiline_parenthesized_expression = false
+ij_java_align_multiline_records = true
+ij_java_align_multiline_resources = true
+ij_java_align_multiline_ternary_operation = false
+ij_java_align_multiline_text_blocks = false
+ij_java_align_multiline_throws_list = false
+ij_java_align_subsequent_simple_methods = false
+ij_java_align_throws_keyword = false
+ij_java_align_types_in_multi_catch = true
+ij_java_annotation_parameter_wrap = off
+ij_java_array_initializer_new_line_after_left_brace = false
+ij_java_array_initializer_right_brace_on_new_line = false
+ij_java_array_initializer_wrap = off
+ij_java_assert_statement_colon_on_next_line = false
+ij_java_assert_statement_wrap = off
+ij_java_assignment_wrap = off
+ij_java_binary_operation_sign_on_next_line = false
+ij_java_binary_operation_wrap = off
+ij_java_blank_lines_after_anonymous_class_header = 0
+ij_java_blank_lines_after_class_header = 0
+ij_java_blank_lines_after_imports = 1
+ij_java_blank_lines_after_package = 1
+ij_java_blank_lines_around_class = 1
+ij_java_blank_lines_around_field = 0
+ij_java_blank_lines_around_field_in_interface = 0
+ij_java_blank_lines_around_initializer = 1
+ij_java_blank_lines_around_method = 1
+ij_java_blank_lines_around_method_in_interface = 1
+ij_java_blank_lines_before_class_end = 0
+ij_java_blank_lines_before_imports = 1
+ij_java_blank_lines_before_method_body = 0
+ij_java_blank_lines_before_package = 0
+ij_java_block_brace_style = end_of_line
+ij_java_block_comment_add_space = false
+ij_java_block_comment_at_first_column = true
+ij_java_builder_methods =
+ij_java_call_parameters_new_line_after_left_paren = false
+ij_java_call_parameters_right_paren_on_new_line = false
+ij_java_call_parameters_wrap = normal
+ij_java_case_statement_on_separate_line = true
+ij_java_catch_on_new_line = false
+ij_java_class_annotation_wrap = split_into_lines
+ij_java_class_brace_style = end_of_line
+ij_java_class_count_to_use_import_on_demand = 5
+ij_java_class_names_in_javadoc = 1
+ij_java_deconstruction_list_wrap = normal
+ij_java_do_not_indent_top_level_class_members = false
+ij_java_do_not_wrap_after_single_annotation = false
+ij_java_do_not_wrap_after_single_annotation_in_parameter = false
+ij_java_do_while_brace_force = never
+ij_java_doc_add_blank_line_after_description = true
+ij_java_doc_add_blank_line_after_param_comments = false
+ij_java_doc_add_blank_line_after_return = false
+ij_java_doc_add_p_tag_on_empty_lines = true
+ij_java_doc_align_exception_comments = true
+ij_java_doc_align_param_comments = true
+ij_java_doc_do_not_wrap_if_one_line = false
+ij_java_doc_enable_formatting = true
+ij_java_doc_enable_leading_asterisks = true
+ij_java_doc_indent_on_continuation = false
+ij_java_doc_keep_empty_lines = true
+ij_java_doc_keep_empty_parameter_tag = true
+ij_java_doc_keep_empty_return_tag = true
+ij_java_doc_keep_empty_throws_tag = true
+ij_java_doc_keep_invalid_tags = true
+ij_java_doc_param_description_on_new_line = false
+ij_java_doc_preserve_line_breaks = false
+ij_java_doc_use_throws_not_exception_tag = true
+ij_java_else_on_new_line = false
+ij_java_enum_constants_wrap = off
+ij_java_enum_field_annotation_wrap = off
+ij_java_extends_keyword_wrap = off
+ij_java_extends_list_wrap = off
+ij_java_field_annotation_wrap = split_into_lines
+ij_java_field_name_prefix =
+ij_java_field_name_suffix =
+ij_java_finally_on_new_line = false
+ij_java_for_brace_force = never
+ij_java_for_statement_new_line_after_left_paren = false
+ij_java_for_statement_right_paren_on_new_line = false
+ij_java_for_statement_wrap = off
+ij_java_generate_final_locals = false
+ij_java_generate_final_parameters = false
+ij_java_generate_use_type_annotation_before_type = true
+ij_java_if_brace_force = never
+ij_java_imports_layout = *,|,javax.**,java.**,|,$*
+ij_java_indent_case_from_switch = true
+ij_java_insert_inner_class_imports = false
+ij_java_insert_override_annotation = true
+ij_java_keep_blank_lines_before_right_brace = 2
+ij_java_keep_blank_lines_between_package_declaration_and_header = 2
+ij_java_keep_blank_lines_in_code = 2
+ij_java_keep_blank_lines_in_declarations = 2
+ij_java_keep_builder_methods_indents = false
+ij_java_keep_control_statement_in_one_line = true
+ij_java_keep_first_column_comment = true
+ij_java_keep_indents_on_empty_lines = false
+ij_java_keep_line_breaks = true
+ij_java_keep_multiple_expressions_in_one_line = false
+ij_java_keep_simple_blocks_in_one_line = true
+ij_java_keep_simple_classes_in_one_line = false
+ij_java_keep_simple_lambdas_in_one_line = false
+ij_java_keep_simple_methods_in_one_line = true
+ij_java_label_indent_absolute = false
+ij_java_label_indent_size = 0
+ij_java_lambda_brace_style = end_of_line
+ij_java_layout_static_imports_separately = true
+ij_java_line_comment_add_space = false
+ij_java_line_comment_add_space_on_reformat = false
+ij_java_line_comment_at_first_column = true
+ij_java_local_variable_name_prefix =
+ij_java_local_variable_name_suffix =
+ij_java_method_annotation_wrap = split_into_lines
+ij_java_method_brace_style = end_of_line
+ij_java_method_call_chain_wrap = off
+ij_java_method_parameters_new_line_after_left_paren = false
+ij_java_method_parameters_right_paren_on_new_line = false
+ij_java_method_parameters_wrap = normal
+ij_java_modifier_list_wrap = false
+ij_java_multi_catch_types_wrap = normal
+ij_java_names_count_to_use_import_on_demand = 3
+ij_java_new_line_after_lparen_in_annotation = false
+ij_java_new_line_after_lparen_in_deconstruction_pattern = true
+ij_java_new_line_after_lparen_in_record_header = false
+ij_java_new_line_when_body_is_presented = false
+ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
+ij_java_parameter_annotation_wrap = off
+ij_java_parameter_name_prefix =
+ij_java_parameter_name_suffix =
+ij_java_parentheses_expression_new_line_after_left_paren = false
+ij_java_parentheses_expression_right_paren_on_new_line = false
+ij_java_place_assignment_sign_on_next_line = false
+ij_java_prefer_longer_names = true
+ij_java_prefer_parameters_wrap = false
+ij_java_record_components_wrap = normal
+ij_java_repeat_annotations =
+ij_java_repeat_synchronized = true
+ij_java_replace_instanceof_and_cast = false
+ij_java_replace_null_check = true
+ij_java_replace_sum_lambda_with_method_ref = true
+ij_java_resource_list_new_line_after_left_paren = false
+ij_java_resource_list_right_paren_on_new_line = false
+ij_java_resource_list_wrap = off
+ij_java_rparen_on_new_line_in_annotation = false
+ij_java_rparen_on_new_line_in_deconstruction_pattern = true
+ij_java_rparen_on_new_line_in_record_header = false
+ij_java_space_after_closing_angle_bracket_in_type_argument = false
+ij_java_space_after_colon = true
+ij_java_space_after_comma = true
+ij_java_space_after_comma_in_type_arguments = true
+ij_java_space_after_for_semicolon = true
+ij_java_space_after_quest = true
+ij_java_space_after_type_cast = true
+ij_java_space_before_annotation_array_initializer_left_brace = false
+ij_java_space_before_annotation_parameter_list = false
+ij_java_space_before_array_initializer_left_brace = false
+ij_java_space_before_catch_keyword = true
+ij_java_space_before_catch_left_brace = true
+ij_java_space_before_catch_parentheses = true
+ij_java_space_before_class_left_brace = true
+ij_java_space_before_colon = true
+ij_java_space_before_colon_in_foreach = true
+ij_java_space_before_comma = false
+ij_java_space_before_deconstruction_list = false
+ij_java_space_before_do_left_brace = true
+ij_java_space_before_else_keyword = true
+ij_java_space_before_else_left_brace = true
+ij_java_space_before_finally_keyword = true
+ij_java_space_before_finally_left_brace = true
+ij_java_space_before_for_left_brace = true
+ij_java_space_before_for_parentheses = true
+ij_java_space_before_for_semicolon = false
+ij_java_space_before_if_left_brace = true
+ij_java_space_before_if_parentheses = true
+ij_java_space_before_method_call_parentheses = false
+ij_java_space_before_method_left_brace = true
+ij_java_space_before_method_parentheses = false
+ij_java_space_before_opening_angle_bracket_in_type_parameter = false
+ij_java_space_before_quest = true
+ij_java_space_before_switch_left_brace = true
+ij_java_space_before_switch_parentheses = true
+ij_java_space_before_synchronized_left_brace = true
+ij_java_space_before_synchronized_parentheses = true
+ij_java_space_before_try_left_brace = true
+ij_java_space_before_try_parentheses = true
+ij_java_space_before_type_parameter_list = false
+ij_java_space_before_while_keyword = true
+ij_java_space_before_while_left_brace = true
+ij_java_space_before_while_parentheses = true
+ij_java_space_inside_one_line_enum_braces = false
+ij_java_space_within_empty_array_initializer_braces = false
+ij_java_space_within_empty_method_call_parentheses = false
+ij_java_space_within_empty_method_parentheses = false
+ij_java_spaces_around_additive_operators = true
+ij_java_spaces_around_annotation_eq = true
+ij_java_spaces_around_assignment_operators = true
+ij_java_spaces_around_bitwise_operators = true
+ij_java_spaces_around_equality_operators = true
+ij_java_spaces_around_lambda_arrow = true
+ij_java_spaces_around_logical_operators = true
+ij_java_spaces_around_method_ref_dbl_colon = false
+ij_java_spaces_around_multiplicative_operators = true
+ij_java_spaces_around_relational_operators = true
+ij_java_spaces_around_shift_operators = true
+ij_java_spaces_around_type_bounds_in_type_parameters = true
+ij_java_spaces_around_unary_operator = false
+ij_java_spaces_inside_block_braces_when_body_is_present = false
+ij_java_spaces_within_angle_brackets = false
+ij_java_spaces_within_annotation_parentheses = false
+ij_java_spaces_within_array_initializer_braces = false
+ij_java_spaces_within_braces = false
+ij_java_spaces_within_brackets = false
+ij_java_spaces_within_cast_parentheses = false
+ij_java_spaces_within_catch_parentheses = false
+ij_java_spaces_within_deconstruction_list = false
+ij_java_spaces_within_for_parentheses = false
+ij_java_spaces_within_if_parentheses = false
+ij_java_spaces_within_method_call_parentheses = false
+ij_java_spaces_within_method_parentheses = false
+ij_java_spaces_within_parentheses = false
+ij_java_spaces_within_record_header = false
+ij_java_spaces_within_switch_parentheses = false
+ij_java_spaces_within_synchronized_parentheses = false
+ij_java_spaces_within_try_parentheses = false
+ij_java_spaces_within_while_parentheses = false
+ij_java_special_else_if_treatment = true
+ij_java_static_field_name_prefix =
+ij_java_static_field_name_suffix =
+ij_java_subclass_name_prefix =
+ij_java_subclass_name_suffix = Impl
+ij_java_switch_expressions_wrap = normal
+ij_java_ternary_operation_signs_on_next_line = false
+ij_java_ternary_operation_wrap = off
+ij_java_test_name_prefix =
+ij_java_test_name_suffix = Test
+ij_java_throws_keyword_wrap = off
+ij_java_throws_list_wrap = off
+ij_java_use_external_annotations = false
+ij_java_use_fq_class_names = false
+ij_java_use_relative_indents = false
+ij_java_use_single_class_imports = true
+ij_java_variable_annotation_wrap = off
+ij_java_visibility = public
+ij_java_while_brace_force = never
+ij_java_while_on_new_line = false
+ij_java_wrap_comments = false
+ij_java_wrap_first_method_in_call_chain = false
+ij_java_wrap_long_lines = true
+ij_java_wrap_semicolon_after_call_chain = false
+
+[*.properties]
+ij_properties_align_group_field_declarations = false
+ij_properties_keep_blank_lines = false
+ij_properties_key_value_delimiter = equals
+ij_properties_spaces_around_key_value_delimiter = false
+
+[.editorconfig]
+ij_editorconfig_align_group_field_declarations = false
+ij_editorconfig_space_after_colon = false
+ij_editorconfig_space_after_comma = true
+ij_editorconfig_space_before_colon = false
+ij_editorconfig_space_before_comma = false
+ij_editorconfig_spaces_around_assignment_operators = true
+
+[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.jspx,*.pom,*.rng,*.tagx,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = normal
+ij_xml_block_comment_add_space = false
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 2
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = false
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = false
+ij_xml_text_wrap = normal
+
+[{*.bash,*.sh,*.zsh}]
+indent_size = 2
+tab_width = 2
+ij_shell_binary_ops_start_line = false
+ij_shell_keep_column_alignment_padding = false
+ij_shell_minify_program = false
+ij_shell_redirect_followed_by_space = false
+ij_shell_switch_cases_indented = false
+ij_shell_use_unix_line_separator = true
+
+[{*.gant,*.groovy,*.gy}]
+ij_groovy_align_group_field_declarations = false
+ij_groovy_align_multiline_array_initializer_expression = false
+ij_groovy_align_multiline_assignment = false
+ij_groovy_align_multiline_binary_operation = false
+ij_groovy_align_multiline_chained_methods = false
+ij_groovy_align_multiline_extends_list = false
+ij_groovy_align_multiline_for = true
+ij_groovy_align_multiline_list_or_map = true
+ij_groovy_align_multiline_method_parentheses = false
+ij_groovy_align_multiline_parameters = true
+ij_groovy_align_multiline_parameters_in_calls = false
+ij_groovy_align_multiline_resources = true
+ij_groovy_align_multiline_ternary_operation = false
+ij_groovy_align_multiline_throws_list = false
+ij_groovy_align_named_args_in_map = true
+ij_groovy_align_throws_keyword = false
+ij_groovy_array_initializer_new_line_after_left_brace = false
+ij_groovy_array_initializer_right_brace_on_new_line = false
+ij_groovy_array_initializer_wrap = off
+ij_groovy_assert_statement_wrap = off
+ij_groovy_assignment_wrap = off
+ij_groovy_binary_operation_wrap = off
+ij_groovy_blank_lines_after_class_header = 0
+ij_groovy_blank_lines_after_imports = 1
+ij_groovy_blank_lines_after_package = 1
+ij_groovy_blank_lines_around_class = 1
+ij_groovy_blank_lines_around_field = 0
+ij_groovy_blank_lines_around_field_in_interface = 0
+ij_groovy_blank_lines_around_method = 1
+ij_groovy_blank_lines_around_method_in_interface = 1
+ij_groovy_blank_lines_before_imports = 1
+ij_groovy_blank_lines_before_method_body = 0
+ij_groovy_blank_lines_before_package = 0
+ij_groovy_block_brace_style = end_of_line
+ij_groovy_block_comment_add_space = false
+ij_groovy_block_comment_at_first_column = true
+ij_groovy_call_parameters_new_line_after_left_paren = false
+ij_groovy_call_parameters_right_paren_on_new_line = false
+ij_groovy_call_parameters_wrap = off
+ij_groovy_catch_on_new_line = false
+ij_groovy_class_annotation_wrap = split_into_lines
+ij_groovy_class_brace_style = end_of_line
+ij_groovy_class_count_to_use_import_on_demand = 5
+ij_groovy_do_while_brace_force = never
+ij_groovy_else_on_new_line = false
+ij_groovy_enable_groovydoc_formatting = true
+ij_groovy_enum_constants_wrap = off
+ij_groovy_extends_keyword_wrap = off
+ij_groovy_extends_list_wrap = off
+ij_groovy_field_annotation_wrap = split_into_lines
+ij_groovy_finally_on_new_line = false
+ij_groovy_for_brace_force = never
+ij_groovy_for_statement_new_line_after_left_paren = false
+ij_groovy_for_statement_right_paren_on_new_line = false
+ij_groovy_for_statement_wrap = off
+ij_groovy_ginq_general_clause_wrap_policy = 2
+ij_groovy_ginq_having_wrap_policy = 1
+ij_groovy_ginq_indent_having_clause = true
+ij_groovy_ginq_indent_on_clause = true
+ij_groovy_ginq_on_wrap_policy = 1
+ij_groovy_ginq_space_after_keyword = true
+ij_groovy_if_brace_force = never
+ij_groovy_import_annotation_wrap = 2
+ij_groovy_imports_layout = *,|,javax.**,java.**,|,$*
+ij_groovy_indent_case_from_switch = true
+ij_groovy_indent_label_blocks = true
+ij_groovy_insert_inner_class_imports = false
+ij_groovy_keep_blank_lines_before_right_brace = 2
+ij_groovy_keep_blank_lines_in_code = 2
+ij_groovy_keep_blank_lines_in_declarations = 2
+ij_groovy_keep_control_statement_in_one_line = true
+ij_groovy_keep_first_column_comment = true
+ij_groovy_keep_indents_on_empty_lines = false
+ij_groovy_keep_line_breaks = true
+ij_groovy_keep_multiple_expressions_in_one_line = false
+ij_groovy_keep_simple_blocks_in_one_line = false
+ij_groovy_keep_simple_classes_in_one_line = true
+ij_groovy_keep_simple_lambdas_in_one_line = true
+ij_groovy_keep_simple_methods_in_one_line = true
+ij_groovy_label_indent_absolute = false
+ij_groovy_label_indent_size = 0
+ij_groovy_lambda_brace_style = end_of_line
+ij_groovy_layout_static_imports_separately = true
+ij_groovy_line_comment_add_space = false
+ij_groovy_line_comment_add_space_on_reformat = false
+ij_groovy_line_comment_at_first_column = true
+ij_groovy_method_annotation_wrap = split_into_lines
+ij_groovy_method_brace_style = end_of_line
+ij_groovy_method_call_chain_wrap = off
+ij_groovy_method_parameters_new_line_after_left_paren = false
+ij_groovy_method_parameters_right_paren_on_new_line = false
+ij_groovy_method_parameters_wrap = off
+ij_groovy_modifier_list_wrap = false
+ij_groovy_names_count_to_use_import_on_demand = 3
+ij_groovy_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
+ij_groovy_parameter_annotation_wrap = off
+ij_groovy_parentheses_expression_new_line_after_left_paren = false
+ij_groovy_parentheses_expression_right_paren_on_new_line = false
+ij_groovy_prefer_parameters_wrap = false
+ij_groovy_resource_list_new_line_after_left_paren = false
+ij_groovy_resource_list_right_paren_on_new_line = false
+ij_groovy_resource_list_wrap = off
+ij_groovy_space_after_assert_separator = true
+ij_groovy_space_after_colon = true
+ij_groovy_space_after_comma = true
+ij_groovy_space_after_comma_in_type_arguments = true
+ij_groovy_space_after_for_semicolon = true
+ij_groovy_space_after_quest = true
+ij_groovy_space_after_type_cast = true
+ij_groovy_space_before_annotation_parameter_list = false
+ij_groovy_space_before_array_initializer_left_brace = false
+ij_groovy_space_before_assert_separator = false
+ij_groovy_space_before_catch_keyword = true
+ij_groovy_space_before_catch_left_brace = true
+ij_groovy_space_before_catch_parentheses = true
+ij_groovy_space_before_class_left_brace = true
+ij_groovy_space_before_closure_left_brace = true
+ij_groovy_space_before_colon = true
+ij_groovy_space_before_comma = false
+ij_groovy_space_before_do_left_brace = true
+ij_groovy_space_before_else_keyword = true
+ij_groovy_space_before_else_left_brace = true
+ij_groovy_space_before_finally_keyword = true
+ij_groovy_space_before_finally_left_brace = true
+ij_groovy_space_before_for_left_brace = true
+ij_groovy_space_before_for_parentheses = true
+ij_groovy_space_before_for_semicolon = false
+ij_groovy_space_before_if_left_brace = true
+ij_groovy_space_before_if_parentheses = true
+ij_groovy_space_before_method_call_parentheses = false
+ij_groovy_space_before_method_left_brace = true
+ij_groovy_space_before_method_parentheses = false
+ij_groovy_space_before_quest = true
+ij_groovy_space_before_record_parentheses = false
+ij_groovy_space_before_switch_left_brace = true
+ij_groovy_space_before_switch_parentheses = true
+ij_groovy_space_before_synchronized_left_brace = true
+ij_groovy_space_before_synchronized_parentheses = true
+ij_groovy_space_before_try_left_brace = true
+ij_groovy_space_before_try_parentheses = true
+ij_groovy_space_before_while_keyword = true
+ij_groovy_space_before_while_left_brace = true
+ij_groovy_space_before_while_parentheses = true
+ij_groovy_space_in_named_argument = true
+ij_groovy_space_in_named_argument_before_colon = false
+ij_groovy_space_within_empty_array_initializer_braces = false
+ij_groovy_space_within_empty_method_call_parentheses = false
+ij_groovy_spaces_around_additive_operators = true
+ij_groovy_spaces_around_assignment_operators = true
+ij_groovy_spaces_around_bitwise_operators = true
+ij_groovy_spaces_around_equality_operators = true
+ij_groovy_spaces_around_lambda_arrow = true
+ij_groovy_spaces_around_logical_operators = true
+ij_groovy_spaces_around_multiplicative_operators = true
+ij_groovy_spaces_around_regex_operators = true
+ij_groovy_spaces_around_relational_operators = true
+ij_groovy_spaces_around_shift_operators = true
+ij_groovy_spaces_within_annotation_parentheses = false
+ij_groovy_spaces_within_array_initializer_braces = false
+ij_groovy_spaces_within_braces = true
+ij_groovy_spaces_within_brackets = false
+ij_groovy_spaces_within_cast_parentheses = false
+ij_groovy_spaces_within_catch_parentheses = false
+ij_groovy_spaces_within_for_parentheses = false
+ij_groovy_spaces_within_gstring_injection_braces = false
+ij_groovy_spaces_within_if_parentheses = false
+ij_groovy_spaces_within_list_or_map = false
+ij_groovy_spaces_within_method_call_parentheses = false
+ij_groovy_spaces_within_method_parentheses = false
+ij_groovy_spaces_within_parentheses = false
+ij_groovy_spaces_within_switch_parentheses = false
+ij_groovy_spaces_within_synchronized_parentheses = false
+ij_groovy_spaces_within_try_parentheses = false
+ij_groovy_spaces_within_tuple_expression = false
+ij_groovy_spaces_within_while_parentheses = false
+ij_groovy_special_else_if_treatment = true
+ij_groovy_ternary_operation_wrap = off
+ij_groovy_throws_keyword_wrap = off
+ij_groovy_throws_list_wrap = off
+ij_groovy_use_flying_geese_braces = false
+ij_groovy_use_fq_class_names = false
+ij_groovy_use_fq_class_names_in_javadoc = true
+ij_groovy_use_relative_indents = false
+ij_groovy_use_single_class_imports = true
+ij_groovy_variable_annotation_wrap = off
+ij_groovy_while_brace_force = never
+ij_groovy_while_on_new_line = false
+ij_groovy_wrap_chain_calls_after_dot = false
+ij_groovy_wrap_long_lines = false
+
+[{*.har,*.json,*.jsonc}]
+indent_size = 2
+ij_json_array_wrapping = split_into_lines
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_keep_trailing_comma = false
+ij_json_object_wrapping = split_into_lines
+ij_json_property_alignment = do_not_align
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = false
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = false
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
+
+[{*.htm,*.html,*.sht,*.shtm,*.shtml}]
+ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
+ij_html_align_attributes = true
+ij_html_align_text = false
+ij_html_attribute_wrap = normal
+ij_html_block_comment_add_space = false
+ij_html_block_comment_at_first_column = true
+ij_html_do_not_align_children_of_min_lines = 0
+ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
+ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
+ij_html_enforce_quotes = false
+ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var
+ij_html_keep_blank_lines = 2
+ij_html_keep_indents_on_empty_lines = false
+ij_html_keep_line_breaks = true
+ij_html_keep_line_breaks_in_text = true
+ij_html_keep_whitespaces = false
+ij_html_keep_whitespaces_inside = span,pre,textarea
+ij_html_line_comment_at_first_column = true
+ij_html_new_line_after_last_attribute = never
+ij_html_new_line_before_first_attribute = never
+ij_html_quote_style = double
+ij_html_remove_new_line_before_tags = br
+ij_html_space_after_tag_name = false
+ij_html_space_around_equality_in_attribute = false
+ij_html_space_inside_empty_tag = false
+ij_html_text_wrap = normal
+
+[{*.kt,*.kts}]
+ij_kotlin_align_in_columns_case_branch = false
+ij_kotlin_align_multiline_binary_operation = false
+ij_kotlin_align_multiline_extends_list = false
+ij_kotlin_align_multiline_method_parentheses = false
+ij_kotlin_align_multiline_parameters = true
+ij_kotlin_align_multiline_parameters_in_calls = false
+ij_kotlin_allow_trailing_comma = false
+ij_kotlin_allow_trailing_comma_on_call_site = false
+ij_kotlin_assignment_wrap = normal
+ij_kotlin_blank_lines_after_class_header = 0
+ij_kotlin_blank_lines_around_block_when_branches = 0
+ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
+ij_kotlin_block_comment_add_space = false
+ij_kotlin_block_comment_at_first_column = true
+ij_kotlin_call_parameters_new_line_after_left_paren = true
+ij_kotlin_call_parameters_right_paren_on_new_line = true
+ij_kotlin_call_parameters_wrap = on_every_item
+ij_kotlin_catch_on_new_line = false
+ij_kotlin_class_annotation_wrap = split_into_lines
+ij_kotlin_continuation_indent_for_chained_calls = false
+ij_kotlin_continuation_indent_for_expression_bodies = false
+ij_kotlin_continuation_indent_in_argument_lists = false
+ij_kotlin_continuation_indent_in_elvis = false
+ij_kotlin_continuation_indent_in_if_conditions = false
+ij_kotlin_continuation_indent_in_parameter_lists = false
+ij_kotlin_continuation_indent_in_supertype_lists = false
+ij_kotlin_else_on_new_line = false
+ij_kotlin_enum_constants_wrap = off
+ij_kotlin_extends_list_wrap = normal
+ij_kotlin_field_annotation_wrap = split_into_lines
+ij_kotlin_finally_on_new_line = false
+ij_kotlin_if_rparen_on_new_line = true
+ij_kotlin_import_nested_classes = false
+ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
+ij_kotlin_indent_before_arrow_on_new_line = true
+ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
+ij_kotlin_keep_blank_lines_before_right_brace = 2
+ij_kotlin_keep_blank_lines_in_code = 2
+ij_kotlin_keep_blank_lines_in_declarations = 2
+ij_kotlin_keep_first_column_comment = true
+ij_kotlin_keep_indents_on_empty_lines = false
+ij_kotlin_keep_line_breaks = true
+ij_kotlin_lbrace_on_next_line = false
+ij_kotlin_line_break_after_multiline_when_entry = true
+ij_kotlin_line_comment_add_space = false
+ij_kotlin_line_comment_add_space_on_reformat = false
+ij_kotlin_line_comment_at_first_column = true
+ij_kotlin_method_annotation_wrap = split_into_lines
+ij_kotlin_method_call_chain_wrap = normal
+ij_kotlin_method_parameters_new_line_after_left_paren = true
+ij_kotlin_method_parameters_right_paren_on_new_line = true
+ij_kotlin_method_parameters_wrap = on_every_item
+ij_kotlin_name_count_to_use_star_import = 5
+ij_kotlin_name_count_to_use_star_import_for_members = 3
+ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.**
+ij_kotlin_parameter_annotation_wrap = off
+ij_kotlin_space_after_comma = true
+ij_kotlin_space_after_extend_colon = true
+ij_kotlin_space_after_type_colon = true
+ij_kotlin_space_before_catch_parentheses = true
+ij_kotlin_space_before_comma = false
+ij_kotlin_space_before_extend_colon = true
+ij_kotlin_space_before_for_parentheses = true
+ij_kotlin_space_before_if_parentheses = true
+ij_kotlin_space_before_lambda_arrow = true
+ij_kotlin_space_before_type_colon = false
+ij_kotlin_space_before_when_parentheses = true
+ij_kotlin_space_before_while_parentheses = true
+ij_kotlin_spaces_around_additive_operators = true
+ij_kotlin_spaces_around_assignment_operators = true
+ij_kotlin_spaces_around_equality_operators = true
+ij_kotlin_spaces_around_function_type_arrow = true
+ij_kotlin_spaces_around_logical_operators = true
+ij_kotlin_spaces_around_multiplicative_operators = true
+ij_kotlin_spaces_around_range = false
+ij_kotlin_spaces_around_relational_operators = true
+ij_kotlin_spaces_around_unary_operator = false
+ij_kotlin_spaces_around_when_arrow = true
+ij_kotlin_variable_annotation_wrap = off
+ij_kotlin_while_on_new_line = false
+ij_kotlin_wrap_elvis_expressions = 1
+ij_kotlin_wrap_expression_body_functions = 1
+ij_kotlin_wrap_first_method_in_call_chain = false
+
+[{*.markdown,*.md}]
+ij_markdown_force_one_space_after_blockquote_symbol = true
+ij_markdown_force_one_space_after_header_symbol = true
+ij_markdown_force_one_space_after_list_bullet = true
+ij_markdown_force_one_space_between_words = true
+ij_markdown_format_tables = true
+ij_markdown_insert_quote_arrows_on_wrap = true
+ij_markdown_keep_indents_on_empty_lines = false
+ij_markdown_keep_line_breaks_inside_text_blocks = true
+ij_markdown_max_lines_around_block_elements = 1
+ij_markdown_max_lines_around_header = 1
+ij_markdown_max_lines_between_paragraphs = 1
+ij_markdown_min_lines_around_block_elements = 1
+ij_markdown_min_lines_around_header = 1
+ij_markdown_min_lines_between_paragraphs = 1
+ij_markdown_wrap_text_if_long = true
+ij_markdown_wrap_text_inside_blockquotes = true
+
+[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}]
+ij_toml_keep_indents_on_empty_lines = false
+
+[{*.yaml,*.yml}]
+indent_size = 2
+ij_yaml_align_values_properties = do_not_align
+ij_yaml_autoinsert_sequence_marker = true
+ij_yaml_block_mapping_on_new_line = false
+ij_yaml_indent_sequence_value = true
+ij_yaml_keep_indents_on_empty_lines = false
+ij_yaml_keep_line_breaks = true
+ij_yaml_line_comment_add_space = false
+ij_yaml_line_comment_add_space_on_reformat = false
+ij_yaml_line_comment_at_first_column = true
+ij_yaml_sequence_on_new_line = false
+ij_yaml_space_before_colon = false
+ij_yaml_spaces_within_braces = true
+ij_yaml_spaces_within_brackets = true
From 2a902f056783cc79b834cd90ad7f5b6eeddb0811 Mon Sep 17 00:00:00 2001
From: Hoan Nguyen <83745591+nqhoan-axonivy@users.noreply.github.com>
Date: Fri, 20 Sep 2024 16:57:48 +0700
Subject: [PATCH 07/20] Format code (#166)
---
marketplace-service/.editorconfig | 2 +-
.../ProductDetailModelAssembler.java | 21 +-
.../comparator/MavenVersionComparator.java | 172 ++++-----
.../axonivy/market/config/AsyncConfig.java | 22 +-
.../config/MarketApiDocumentConfig.java | 9 +-
.../config/MarketHeaderInterceptor.java | 4 +-
.../axonivy/market/config/MongoConfig.java | 9 +-
.../market/config/SchedulingConfig.java | 18 +-
.../com/axonivy/market/config/WebConfig.java | 10 +-
.../market/constants/MavenConstants.java | 6 +-
.../market/constants/MongoDBConstants.java | 18 +-
.../constants/RequestMappingConstants.java | 4 +-
.../market/controller/FeedbackController.java | 59 ++--
.../market/controller/ImageController.java | 9 +-
.../market/controller/OAuth2Controller.java | 36 +-
.../market/controller/ProductController.java | 62 ++--
...ProductDesignerInstallationController.java | 26 +-
.../controller/ProductDetailsController.java | 78 +++--
.../criteria/ProductSearchCriteria.java | 11 +-
.../java/com/axonivy/market/entity/Image.java | 6 +-
.../market/entity/MavenArtifactModel.java | 4 +-
.../com/axonivy/market/entity/Product.java | 3 +-
.../entity/ProductDesignerInstallation.java | 40 ++-
.../market/entity/ProductModuleContent.java | 7 +-
.../com/axonivy/market/enums/ErrorCode.java | 3 +-
.../market/enums/NonStandardProduct.java | 33 +-
.../market/exceptions/ExceptionHandlers.java | 1 +
.../market/factory/ProductFactory.java | 13 +-
.../market/github/model/GitHubProperty.java | 5 +-
.../service/GHAxonIvyProductRepoService.java | 5 +-
.../market/github/service/GitHubService.java | 17 +-
.../impl/GHAxonIvyMarketRepoServiceImpl.java | 3 +-
.../impl/GHAxonIvyProductRepoServiceImpl.java | 39 ++-
.../market/model/ProductDetailModel.java | 6 +-
.../axonivy/market/model/ProductModel.java | 10 +-
...ProductDesignerInstallationRepository.java | 2 +-
.../ProductJsonContentRepository.java | 2 +-
.../ProductModuleContentRepository.java | 3 +-
.../market/repository/ProductRepository.java | 6 +-
.../repository/ProductSearchRepository.java | 1 -
.../impl/CustomProductRepositoryImpl.java | 13 +-
.../impl/ProductSearchRepositoryImpl.java | 26 +-
.../axonivy/market/service/ImageService.java | 5 +-
.../market/service/VersionService.java | 3 +-
.../service/impl/FeedbackServiceImpl.java | 3 +-
.../market/service/impl/ImageServiceImpl.java | 2 +-
...roductDesignerInstallationServiceImpl.java | 31 +-
.../service/impl/ProductServiceImpl.java | 79 ++---
.../com/axonivy/market/util/ImageUtils.java | 16 +-
.../com/axonivy/market/util/VersionUtils.java | 203 +++++------
.../java/com/axonivy/market/BaseSetup.java | 15 +-
.../ProductDetailModelAssemblerTest.java | 9 +-
.../controller/ProductControllerTest.java | 13 +-
...uctDesignerInstallationControllerTest.java | 34 +-
.../ProductDetailsControllerTest.java | 85 ++---
.../market/factory/ProductFactoryTest.java | 12 +-
.../impl/CustomProductRepositoryImplTest.java | 37 +-
.../impl/ProductSearchRepositoryImplTest.java | 26 +-
.../service/impl/FeedbackServiceImplTest.java | 12 +-
.../GHAxonIvyProductRepoServiceImplTest.java | 296 ++++++++--------
.../service/impl/GitHubServiceImplTest.java | 4 +-
.../service/impl/ImageServiceImplTest.java | 41 +--
.../service/impl/JwtServiceImplTest.java | 5 +-
...ctDesignerInstallationServiceImplTest.java | 5 +-
.../service/impl/ProductServiceImplTest.java | 141 +++-----
.../service/impl/SchedulingTasksTest.java | 9 +-
.../service/impl/UserServiceImplTest.java | 9 +-
.../service/impl/VersionServiceImplTest.java | 3 +-
.../axonivy/market/util/ImageUtilsTest.java | 11 +-
.../axonivy/market/util/VersionUtilsTest.java | 325 +++++++++---------
70 files changed, 1134 insertions(+), 1124 deletions(-)
diff --git a/marketplace-service/.editorconfig b/marketplace-service/.editorconfig
index 9b7bd7afe..bded54b66 100644
--- a/marketplace-service/.editorconfig
+++ b/marketplace-service/.editorconfig
@@ -78,7 +78,7 @@ ij_java_case_statement_on_separate_line = true
ij_java_catch_on_new_line = false
ij_java_class_annotation_wrap = split_into_lines
ij_java_class_brace_style = end_of_line
-ij_java_class_count_to_use_import_on_demand = 5
+ij_java_class_count_to_use_import_on_demand = 10
ij_java_class_names_in_javadoc = 1
ij_java_deconstruction_list_wrap = normal
ij_java_do_not_indent_top_level_class_members = false
diff --git a/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductDetailModelAssembler.java b/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductDetailModelAssembler.java
index 9acbe6fc5..8a8a2a632 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductDetailModelAssembler.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/assembler/ProductDetailModelAssembler.java
@@ -1,22 +1,21 @@
package com.axonivy.market.assembler;
-import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
-import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
-
-import java.util.Optional;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.hateoas.Link;
-import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-
import com.axonivy.market.constants.RequestMappingConstants;
import com.axonivy.market.controller.ProductDetailsController;
import com.axonivy.market.entity.Product;
import com.axonivy.market.model.ProductDetailModel;
import com.axonivy.market.util.ImageUtils;
import com.axonivy.market.util.VersionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.hateoas.Link;
+import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class ProductDetailModelAssembler extends RepresentationModelAssemblerSupport {
diff --git a/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java b/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java
index 2c49ebf23..b707019a7 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/comparator/MavenVersionComparator.java
@@ -17,106 +17,106 @@
public class MavenVersionComparator {
- private static final int GREATER_THAN = 1;
- private static final int EQUAL = 0;
- private static final int LESS_THAN = -1;
+ private static final int GREATER_THAN = 1;
+ private static final int EQUAL = 0;
+ private static final int LESS_THAN = -1;
- private MavenVersionComparator() {
- }
+ private MavenVersionComparator() {
+ }
- public static GHTag findHighestTag(List ghTags) {
- if (CollectionUtils.isEmpty(ghTags)) {
- return null;
- }
- String highestVersion = findHighestMavenVersion(ghTags.stream().map(GHTag::getName).toList());
- return ghTags.stream().filter(tag -> tag.getName().equals(highestVersion)).findAny().orElse(null);
+ public static GHTag findHighestTag(List ghTags) {
+ if (CollectionUtils.isEmpty(ghTags)) {
+ return null;
}
+ String highestVersion = findHighestMavenVersion(ghTags.stream().map(GHTag::getName).toList());
+ return ghTags.stream().filter(tag -> tag.getName().equals(highestVersion)).findAny().orElse(null);
+ }
- public static String findHighestMavenVersion(List versions) {
- if (CollectionUtils.isEmpty(versions)) {
- return null;
- }
-
- String highestVersion = versions.get(0);
- for (var version : versions) {
- if (compare(version, highestVersion) > EQUAL) {
- highestVersion = version;
- }
- }
- return highestVersion;
+ public static String findHighestMavenVersion(List versions) {
+ if (CollectionUtils.isEmpty(versions)) {
+ return null;
}
- public static int compare(String version, String otherVersion) {
- version = stripLeadingChars(version);
- otherVersion = stripLeadingChars(otherVersion);
- String[] versionParts = createMainAndQualifierArray(version);
- String[] otherVersionParts = createMainAndQualifierArray(otherVersion);
-
- // Compare main version parts
- int mainComparison = compareMainVersion(versionParts[0], otherVersionParts[0]);
- if (mainComparison != EQUAL) {
- return mainComparison;
- }
-
- // Compare qualifiers
- String qualifier1 = getQualifierPart(versionParts);
- String qualifier2 = getQualifierPart(otherVersionParts);
- // Consider versions without a qualifier higher than those with qualifiers
- if (qualifier1.isEmpty() && !qualifier2.isEmpty()) {
- return GREATER_THAN;
- }
- if (!qualifier1.isEmpty() && qualifier2.isEmpty()) {
- return LESS_THAN;
- }
- return compareQualifier(qualifier1, qualifier2);
+ String highestVersion = versions.get(0);
+ for (var version : versions) {
+ if (compare(version, highestVersion) > EQUAL) {
+ highestVersion = version;
+ }
}
-
- private static String stripLeadingChars(String version) {
- Pattern pattern = Pattern.compile(CommonConstants.DIGIT_REGEX);
- Matcher matcher = pattern.matcher(version);
- if (matcher.find()) {
- return matcher.group(1);
- }
- return version;
+ return highestVersion;
+ }
+
+ public static int compare(String version, String otherVersion) {
+ version = stripLeadingChars(version);
+ otherVersion = stripLeadingChars(otherVersion);
+ String[] versionParts = createMainAndQualifierArray(version);
+ String[] otherVersionParts = createMainAndQualifierArray(otherVersion);
+
+ // Compare main version parts
+ int mainComparison = compareMainVersion(versionParts[0], otherVersionParts[0]);
+ if (mainComparison != EQUAL) {
+ return mainComparison;
}
- private static int compareMainVersion(String mainVersion, String otherMainVersion) {
- String[] parts1 = mainVersion.split(MAIN_VERSION_REGEX);
- String[] parts2 = otherMainVersion.split(MAIN_VERSION_REGEX);
-
- int length = Math.max(parts1.length, parts2.length);
- for (int i = 0; i < length; i++) {
- int num1 = parseToNumber(parts1, i);
- int num2 = parseToNumber(parts2, i);
- if (num1 != num2) {
- return num1 - num2;
- }
- }
- return EQUAL;
+ // Compare qualifiers
+ String qualifier1 = getQualifierPart(versionParts);
+ String qualifier2 = getQualifierPart(otherVersionParts);
+ // Consider versions without a qualifier higher than those with qualifiers
+ if (qualifier1.isEmpty() && !qualifier2.isEmpty()) {
+ return GREATER_THAN;
}
-
- private static String getQualifierPart(String[] versionParts) {
- return versionParts.length > 1 ? versionParts[1] : EMPTY;
+ if (!qualifier1.isEmpty() && qualifier2.isEmpty()) {
+ return LESS_THAN;
}
-
- private static String[] createMainAndQualifierArray(String version) {
- return StringUtils.defaultIfBlank(version, EMPTY).split(DASH_SEPARATOR, 2);
+ return compareQualifier(qualifier1, qualifier2);
+ }
+
+ private static String stripLeadingChars(String version) {
+ Pattern pattern = Pattern.compile(CommonConstants.DIGIT_REGEX);
+ Matcher matcher = pattern.matcher(version);
+ if (matcher.find()) {
+ return matcher.group(1);
}
+ return version;
+ }
+
+ private static int compareMainVersion(String mainVersion, String otherMainVersion) {
+ String[] parts1 = mainVersion.split(MAIN_VERSION_REGEX);
+ String[] parts2 = otherMainVersion.split(MAIN_VERSION_REGEX);
+
+ int length = Math.max(parts1.length, parts2.length);
+ for (int i = 0; i < length; i++) {
+ int num1 = parseToNumber(parts1, i);
+ int num2 = parseToNumber(parts2, i);
+ if (num1 != num2) {
+ return num1 - num2;
+ }
+ }
+ return EQUAL;
+ }
+
+ private static String getQualifierPart(String[] versionParts) {
+ return versionParts.length > 1 ? versionParts[1] : EMPTY;
+ }
- private static int parseToNumber(String[] versionParts, int index) {
- if (index < versionParts.length && NumberUtils.isDigits(versionParts[index])) {
- return NumberUtils.toInt(versionParts[index]);
- }
- return 0;
+ private static String[] createMainAndQualifierArray(String version) {
+ return StringUtils.defaultIfBlank(version, EMPTY).split(DASH_SEPARATOR, 2);
+ }
+
+ private static int parseToNumber(String[] versionParts, int index) {
+ if (index < versionParts.length && NumberUtils.isDigits(versionParts[index])) {
+ return NumberUtils.toInt(versionParts[index]);
}
+ return 0;
+ }
- private static int compareQualifier(String qualifier1, String qualifier2) {
- if (SNAPSHOT_VERSION.equals(qualifier1) && !SNAPSHOT_VERSION.equals(qualifier2)) {
- return LESS_THAN;
- }
- if (!SNAPSHOT_VERSION.equals(qualifier1) && SNAPSHOT_VERSION.equals(qualifier2)) {
- return GREATER_THAN;
- }
- return qualifier1.compareTo(qualifier2);
+ private static int compareQualifier(String qualifier1, String qualifier2) {
+ if (SNAPSHOT_VERSION.equals(qualifier1) && !SNAPSHOT_VERSION.equals(qualifier2)) {
+ return LESS_THAN;
+ }
+ if (!SNAPSHOT_VERSION.equals(qualifier1) && SNAPSHOT_VERSION.equals(qualifier2)) {
+ return GREATER_THAN;
}
+ return qualifier1.compareTo(qualifier2);
+ }
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/AsyncConfig.java b/marketplace-service/src/main/java/com/axonivy/market/config/AsyncConfig.java
index 43dcfcdd0..298cb3047 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/config/AsyncConfig.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/config/AsyncConfig.java
@@ -9,16 +9,16 @@
@Configuration
public class AsyncConfig implements AsyncConfigurer {
- private static final String THREAD_NAME_PREFIX = "AC-Thread-";
+ private static final String THREAD_NAME_PREFIX = "AC-Thread-";
- @Override
- public Executor getAsyncExecutor() {
- ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
- executor.setCorePoolSize(5);
- executor.setMaxPoolSize(10);
- executor.setQueueCapacity(25);
- executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
- executor.initialize();
- return executor;
- }
+ @Override
+ public Executor getAsyncExecutor() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(5);
+ executor.setMaxPoolSize(10);
+ executor.setQueueCapacity(25);
+ executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
+ executor.initialize();
+ return executor;
+ }
}
\ No newline at end of file
diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/MarketApiDocumentConfig.java b/marketplace-service/src/main/java/com/axonivy/market/config/MarketApiDocumentConfig.java
index 67e0dfbed..f9134cc1b 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/config/MarketApiDocumentConfig.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/config/MarketApiDocumentConfig.java
@@ -24,17 +24,18 @@ public class MarketApiDocumentConfig {
@Bean
public GroupedOpenApi buildMarketCustomHeader() {
return GroupedOpenApi.builder().group(DEFAULT_DOC_GROUP)
- .addOpenApiCustomizer(customMarketHeaders())
- .pathsToMatch(PATH_PATTERN).build();
+ .addOpenApiCustomizer(customMarketHeaders())
+ .pathsToMatch(PATH_PATTERN).build();
}
private OpenApiCustomizer customMarketHeaders() {
return openApi -> openApi.getPaths().values().forEach((PathItem pathItem) -> {
- List operations = Arrays.asList(pathItem.getPut(), pathItem.getPost(), pathItem.getPatch(), pathItem.getDelete());
+ List operations = Arrays.asList(pathItem.getPut(), pathItem.getPost(), pathItem.getPatch(),
+ pathItem.getDelete());
for (Operation operation : operations) {
if (operation != null) {
Parameter headerParameter = new Parameter().in(HEADER_PARAM).schema(new StringSchema())
- .name(REQUESTED_BY).description(DEFAULT_PARAM).required(true);
+ .name(REQUESTED_BY).description(DEFAULT_PARAM).required(true);
operation.addParametersItem(headerParameter);
}
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/MarketHeaderInterceptor.java b/marketplace-service/src/main/java/com/axonivy/market/config/MarketHeaderInterceptor.java
index f47d860da..9afeff698 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/config/MarketHeaderInterceptor.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/config/MarketHeaderInterceptor.java
@@ -14,12 +14,12 @@ public class MarketHeaderInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
+ throws Exception {
if (HttpMethod.OPTIONS.name().equalsIgnoreCase(request.getMethod())) {
return true;
}
if (!HttpMethod.GET.name().equalsIgnoreCase(request.getMethod())
- && StringUtils.isBlank(request.getHeader(CommonConstants.REQUESTED_BY))) {
+ && StringUtils.isBlank(request.getHeader(CommonConstants.REQUESTED_BY))) {
throw new MissingHeaderException();
}
return true;
diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java b/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java
index 71df8b67b..becc7dafb 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java
@@ -1,5 +1,9 @@
package com.axonivy.market.config;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -13,11 +17,6 @@
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
-import com.mongodb.ConnectionString;
-import com.mongodb.MongoClientSettings;
-import com.mongodb.client.MongoClient;
-import com.mongodb.client.MongoClients;
-
@Configuration
@EnableMongoRepositories(basePackages = "com.axonivy.market.repository")
@EnableMongoAuditing
diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/SchedulingConfig.java b/marketplace-service/src/main/java/com/axonivy/market/config/SchedulingConfig.java
index 275717f54..c9006737b 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/config/SchedulingConfig.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/config/SchedulingConfig.java
@@ -7,14 +7,14 @@
@Configuration
public class SchedulingConfig {
- private static final String THREAD_NAME_PREFIX = "SC-Thread-";
+ private static final String THREAD_NAME_PREFIX = "SC-Thread-";
- @Bean
- public ThreadPoolTaskScheduler taskScheduler() {
- ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
- taskScheduler.setPoolSize(10);
- taskScheduler.setThreadNamePrefix(THREAD_NAME_PREFIX);
- taskScheduler.initialize();
- return taskScheduler;
- }
+ @Bean
+ public ThreadPoolTaskScheduler taskScheduler() {
+ ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
+ taskScheduler.setPoolSize(10);
+ taskScheduler.setThreadNamePrefix(THREAD_NAME_PREFIX);
+ taskScheduler.initialize();
+ return taskScheduler;
+ }
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java b/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java
index d50fe342c..619dd7225 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java
@@ -10,11 +10,11 @@
public class WebConfig implements WebMvcConfigurer {
private static final String ALL_MAPPINGS = "/**";
- private static final String[] EXCLUDE_PATHS = { "/", "/swagger-ui/**", "/api-docs/**", "/api/product-details/**/json",
- "/api/image/**" };
- private static final String[] ALLOWED_HEADERS = { "Accept-Language", "Content-Type", "Authorization",
- "X-Requested-By", "x-requested-with", "X-Forwarded-Host", "x-xsrf-token", "x-authorization" };
- private static final String[] ALLOWED_METHODS = { "GET", "POST", "PUT", "DELETE", "OPTIONS" };
+ private static final String[] EXCLUDE_PATHS = {"/", "/swagger-ui/**", "/api-docs/**", "/api/product-details/**/json",
+ "/api/image/**"};
+ private static final String[] ALLOWED_HEADERS = {"Accept-Language", "Content-Type", "Authorization",
+ "X-Requested-By", "x-requested-with", "X-Forwarded-Host", "x-xsrf-token", "x-authorization"};
+ private static final String[] ALLOWED_METHODS = {"GET", "POST", "PUT", "DELETE", "OPTIONS"};
private final MarketHeaderInterceptor headerInterceptor;
diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java
index 0c99d0118..2690892ce 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/constants/MavenConstants.java
@@ -1,9 +1,6 @@
package com.axonivy.market.constants;
public class MavenConstants {
- private MavenConstants() {
- }
-
public static final String SNAPSHOT_VERSION = "SNAPSHOT";
public static final String SNAPSHOT_RELEASE_POSTFIX = "-" + SNAPSHOT_VERSION;
public static final String SPRINT_RELEASE_POSTFIX = "-m";
@@ -13,4 +10,7 @@ private MavenConstants() {
public static final String ARTIFACT_NAME_FORMAT = "%s (%s)";
public static final String VERSION_EXTRACT_FORMAT_FROM_METADATA_FILE = "//versions/version/text()";
public static final String MAIN_VERSION_REGEX = "\\.";
+
+ private MavenConstants() {
+ }
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java
index 917709dd9..784984d32 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java
@@ -2,15 +2,15 @@
public class MongoDBConstants {
- private MongoDBConstants() {
- }
+ public static final String ID = "_id";
+ public static final String PRODUCT_COLLECTION = "Product";
+ public static final String INSTALLATION_COUNT = "InstallationCount";
+ public static final String SYNCHRONIZED_INSTALLATION_COUNT = "SynchronizedInstallationCount";
+ public static final String PRODUCT_ID = "productId";
+ public static final String DESIGNER_VERSION = "designerVersion";
+ public static final String TAG = "tag";
- public static final String ID ="_id";
- public static final String PRODUCT_COLLECTION ="Product";
- public static final String INSTALLATION_COUNT = "InstallationCount";
- public static final String SYNCHRONIZED_INSTALLATION_COUNT ="SynchronizedInstallationCount";
- public static final String PRODUCT_ID = "productId";
- public static final String DESIGNER_VERSION = "designerVersion";
- public static final String TAG = "tag";
+ private MongoDBConstants() {
+ }
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java
index 95105083e..c828f55d3 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java
@@ -7,11 +7,12 @@
public class RequestMappingConstants {
public static final String ROOT = "/";
public static final String API = ROOT + "api";
- public static final String SYNC = "sync";
public static final String PRODUCT = API + "/product";
public static final String PRODUCT_DETAILS = API + "/product-details";
public static final String PRODUCT_DESIGNER_INSTALLATION = API + "/product-designer-installation";
public static final String FEEDBACK = API + "/feedback";
+ public static final String IMAGE = API + "/image";
+ public static final String SYNC = "sync";
public static final String SWAGGER_URL = "/swagger-ui/index.html";
public static final String GIT_HUB_LOGIN = "/github/login";
public static final String AUTH = "/auth";
@@ -26,5 +27,4 @@ public class RequestMappingConstants {
public static final String VERSIONS_IN_DESIGNER = "/{id}/designerversions";
public static final String DESIGNER_INSTALLATION_BY_ID = "/installation/{id}/designer";
public static final String CUSTOM_SORT = "custom-sort";
- public static final String IMAGE = API + "/image";
}
\ No newline at end of file
diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/FeedbackController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/FeedbackController.java
index 79668a021..baa642b83 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/controller/FeedbackController.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/controller/FeedbackController.java
@@ -40,13 +40,8 @@
import java.net.URI;
import java.util.List;
-import static com.axonivy.market.constants.RequestMappingConstants.BY_ID;
-import static com.axonivy.market.constants.RequestMappingConstants.FEEDBACK;
-import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_BY_ID;
-import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_RATING_BY_ID;
-import static com.axonivy.market.constants.RequestParamConstants.ID;
-import static com.axonivy.market.constants.RequestParamConstants.USER_ID;
-import static com.axonivy.market.constants.RequestParamConstants.X_AUTHORIZATION;
+import static com.axonivy.market.constants.RequestMappingConstants.*;
+import static com.axonivy.market.constants.RequestParamConstants.*;
@RestController
@RequestMapping(FEEDBACK)
@@ -68,12 +63,18 @@ public FeedbackController(FeedbackService feedbackService, JwtService jwtService
}
@GetMapping(PRODUCT_BY_ID)
- @Operation(summary = "Find feedbacks by product id with lazy loading", description = "Get all user feedback by product id (from meta.json) with lazy loading", parameters = {
- @Parameter(name = "page", description = "Page number to retrieve", in = ParameterIn.QUERY, example = "0", required = true),
- @Parameter(name = "size", description = "Number of items per page", in = ParameterIn.QUERY, example = "20", required = true),
- @Parameter(name = "sort", description = "Sorting criteria in the format: Sorting criteria(popularity|alphabetically|recent), Sorting order(asc|desc)", in = ParameterIn.QUERY, example = "[\"popularity\",\"asc\"]", required = true) })
+ @Operation(summary = "Find feedbacks by product id with lazy loading", description = "Get all user feedback by " +
+ "product id (from meta.json) with lazy loading", parameters = {
+ @Parameter(name = "page", description = "Page number to retrieve", in = ParameterIn.QUERY, example = "0",
+ required = true),
+ @Parameter(name = "size", description = "Number of items per page", in = ParameterIn.QUERY, example = "20",
+ required = true),
+ @Parameter(name = "sort", description = "Sorting criteria in the format: Sorting criteria" +
+ "(popularity|alphabetically|recent), Sorting order(asc|desc)", in = ParameterIn.QUERY, example =
+ "[\"popularity\",\"asc\"]", required = true)})
public ResponseEntity> findFeedbacks(
- @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "portal", in = ParameterIn.PATH) String productId,
+ @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "portal", in =
+ ParameterIn.PATH) String productId,
@ParameterObject Pageable pageable) {
Page results = feedbackService.findFeedbacks(productId, pageable);
if (results.isEmpty()) {
@@ -85,29 +86,37 @@ public ResponseEntity> findFeedbacks(
}
@GetMapping(BY_ID)
- @Operation(summary = "Find all feedbacks by product id", description = "Get all feedbacks by product id(from meta.json) which is used in mobile viewport.")
+ @Operation(summary = "Find all feedbacks by product id", description = "Get all feedbacks by product id(from meta" +
+ ".json) which is used in mobile viewport.")
public ResponseEntity findFeedback(
- @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "portal", in = ParameterIn.PATH) String id) {
+ @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "portal", in =
+ ParameterIn.PATH) String id) {
Feedback feedback = feedbackService.findFeedback(id);
return ResponseEntity.ok(feedbackModelAssembler.toModel(feedback));
}
@GetMapping()
- @Operation(summary = "Find all feedbacks by user id and product id", description = "Get current user feedback on target product.")
+ @Operation(summary = "Find all feedbacks by user id and product id", description = "Get current user feedback on " +
+ "target product.")
public ResponseEntity findFeedbackByUserIdAndProductId(
- @RequestParam(USER_ID) @Parameter(description = "Id of current user from DB", example = "1234", in = ParameterIn.QUERY) String userId,
- @RequestParam("productId") @Parameter(description = "Product id (from meta.json)", example = "portal", in = ParameterIn.QUERY) String productId) {
+ @RequestParam(USER_ID) @Parameter(description = "Id of current user from DB", example = "1234", in =
+ ParameterIn.QUERY) String userId,
+ @RequestParam("productId") @Parameter(description = "Product id (from meta.json)", example = "portal", in =
+ ParameterIn.QUERY) String productId) {
Feedback feedback = feedbackService.findFeedbackByUserIdAndProductId(userId, productId);
return ResponseEntity.ok(feedbackModelAssembler.toModel(feedback));
}
@PostMapping
- @Operation(summary = "Create user feedback", description = "Save user feedback of product with their token from Github account.")
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Example request body for feedback", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = FeedbackModelRequest.class)))
- @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "Successfully created user feedback"),
- @ApiResponse(responseCode = "401", description = "Unauthorized request") })
+ @Operation(summary = "Create user feedback", description = "Save user feedback of product with their token from " +
+ "Github account.")
+ @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Example request body for feedback", content =
+ @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = FeedbackModelRequest.class)))
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Successfully created user feedback"),
+ @ApiResponse(responseCode = "401", description = "Unauthorized request")})
public ResponseEntity createFeedback(@RequestBody @Valid FeedbackModelRequest feedbackRequest,
- @RequestHeader(value = X_AUTHORIZATION) @Parameter(description = "JWT Bearer token", example = "Bearer 123456", in = ParameterIn.HEADER) String bearerToken) {
+ @RequestHeader(value = X_AUTHORIZATION) @Parameter(description = "JWT Bearer token", example = "Bearer 123456",
+ in = ParameterIn.HEADER) String bearerToken) {
String token = null;
if (bearerToken != null && bearerToken.startsWith(CommonConstants.BEARER)) {
token = bearerToken.substring(CommonConstants.BEARER.length()).trim(); // Remove "Bearer " prefix
@@ -127,10 +136,12 @@ public ResponseEntity createFeedback(@RequestBody @Valid FeedbackModelRequ
return ResponseEntity.created(location).build();
}
- @Operation(summary = "Find rating information of product by its id.", description = "Get overall rating of product by its id.")
+ @Operation(summary = "Find rating information of product by its id.", description = "Get overall rating of product " +
+ "by its id.")
@GetMapping(PRODUCT_RATING_BY_ID)
public ResponseEntity> getProductRating(
- @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "portal", in = ParameterIn.PATH) String productId) {
+ @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "portal", in =
+ ParameterIn.PATH) String productId) {
return ResponseEntity.ok(feedbackService.getProductRatingById(productId));
}
diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ImageController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ImageController.java
index 5264d7e40..73444c5fe 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/controller/ImageController.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ImageController.java
@@ -33,12 +33,15 @@ public ImageController(ImageService imageService) {
}
@GetMapping(BY_ID)
- @Operation(summary = "Get the image content by id", description = "Collect the byte[] of image with contentType in header is PNG")
- @ApiResponse(responseCode = "200", description = "Image found and returned", content = @Content(mediaType = MediaType.IMAGE_PNG_VALUE, schema = @Schema(implementation = Image.class)))
+ @Operation(summary = "Get the image content by id", description = "Collect the byte[] of image with contentType in " +
+ "header is PNG")
+ @ApiResponse(responseCode = "200", description = "Image found and returned", content = @Content(mediaType =
+ MediaType.IMAGE_PNG_VALUE, schema = @Schema(implementation = Image.class)))
@ApiResponse(responseCode = "404", description = "Image not found")
@ApiResponse(responseCode = "204", description = "No content (image empty)")
public ResponseEntity findImageById(
- @PathVariable(ID) @Parameter(description = "The image id", example = "66e7efc8a24f36158df06fc7", in = ParameterIn.PATH) String id) {
+ @PathVariable(ID) @Parameter(description = "The image id", example = "66e7efc8a24f36158df06fc7", in =
+ ParameterIn.PATH) String id) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
byte[] imageData = imageService.readImage(id);
diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/OAuth2Controller.java b/marketplace-service/src/main/java/com/axonivy/market/controller/OAuth2Controller.java
index afc4aba6d..ed9b515ac 100644
--- a/marketplace-service/src/main/java/com/axonivy/market/controller/OAuth2Controller.java
+++ b/marketplace-service/src/main/java/com/axonivy/market/controller/OAuth2Controller.java
@@ -1,14 +1,14 @@
package com.axonivy.market.controller;
-import static com.axonivy.market.constants.RequestMappingConstants.AUTH;
-import static com.axonivy.market.constants.RequestMappingConstants.GIT_HUB_LOGIN;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
import com.axonivy.market.constants.CommonConstants;
+import com.axonivy.market.constants.GitHubConstants;
+import com.axonivy.market.entity.User;
import com.axonivy.market.exceptions.model.Oauth2ExchangeCodeException;
+import com.axonivy.market.github.model.GitHubAccessTokenResponse;
+import com.axonivy.market.github.model.GitHubProperty;
+import com.axonivy.market.github.service.GitHubService;
+import com.axonivy.market.model.Oauth2AuthorizationCode;
+import com.axonivy.market.service.JwtService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -22,13 +22,12 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import com.axonivy.market.constants.GitHubConstants;
-import com.axonivy.market.entity.User;
-import com.axonivy.market.github.model.GitHubAccessTokenResponse;
-import com.axonivy.market.github.model.GitHubProperty;
-import com.axonivy.market.github.service.GitHubService;
-import com.axonivy.market.model.Oauth2AuthorizationCode;
-import com.axonivy.market.service.JwtService;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.axonivy.market.constants.RequestMappingConstants.AUTH;
+import static com.axonivy.market.constants.RequestMappingConstants.GIT_HUB_LOGIN;
@RestController
@RequestMapping(AUTH)
@@ -49,13 +48,16 @@ public OAuth2Controller(GitHubService gitHubService, JwtService jwtService, GitH
@PostMapping(GIT_HUB_LOGIN)
@Operation(description = "Get rating authentication token")
@ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Successfully login to GitHub provider", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Map.class))),
+ @ApiResponse(responseCode = "200", description = "Successfully login to GitHub provider", content =
+ @Content(mediaType = "application/json", schema = @Schema(implementation = Map.class))),
@ApiResponse(responseCode = "400", description = "Bad Request")})
- @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = Oauth2AuthorizationCode.class)))
+ @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(mediaType =
+ MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = Oauth2AuthorizationCode.class)))
public ResponseEntity