From ed0f7c24715ce9521ed1a765a44d1737963c19db Mon Sep 17 00:00:00 2001 From: Marco Galluzzi Date: Wed, 12 Mar 2025 18:45:57 +0000 Subject: [PATCH 01/13] LPD-49536 auto build language --- .../src/main/resources/content/Language_gl.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/apps/portal-language/portal-language-lang/src/main/resources/content/Language_gl.properties b/modules/apps/portal-language/portal-language-lang/src/main/resources/content/Language_gl.properties index fd3737b7ec6c94..ad18643b74bbbc 100644 --- a/modules/apps/portal-language/portal-language-lang/src/main/resources/content/Language_gl.properties +++ b/modules/apps/portal-language/portal-language-lang/src/main/resources/content/Language_gl.properties @@ -3180,7 +3180,7 @@ category.batch-planner=Planificador por lotes category.bi=Intelixencia empresarial e informes category.blogs=Blogs category.breadcrumbs=Camiños de navegación -category.captcha=Captcha +category.captcha=CAPTCHA category.catalog=Catálogo category.channel=Canle category.chat=Conversa From 6e7d886e589ed943a10daec4d3a97de962b50ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Wed, 12 Mar 2025 20:30:30 +0100 Subject: [PATCH 02/13] LPD-49536 Implement methods (Most of them are based in previous logic) --- .../headless-asset-library-impl/build.gradle | 1 + .../converter/AssetLibraryDTOConverter.java | 179 +++++++++ .../v1_0/AssetLibraryResourceImpl.java | 361 ++++++++++++++++++ .../AssetLibraryOrderByComparator.java | 124 ++++++ 4 files changed, 665 insertions(+) create mode 100644 modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/AssetLibraryDTOConverter.java create mode 100644 modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/util/comparator/AssetLibraryOrderByComparator.java diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/build.gradle b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/build.gradle index 9fd42721b499e8..ad2c362e00f35e 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/build.gradle +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/build.gradle @@ -18,5 +18,6 @@ dependencies { compileOnly project(":apps:portal-vulcan:portal-vulcan-api") compileOnly project(":core:petra:petra-function") compileOnly project(":core:petra:petra-lang") + compileOnly project(":core:petra:petra-sql-dsl-api") compileOnly project(":core:petra:petra-string") } \ No newline at end of file diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/AssetLibraryDTOConverter.java b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/AssetLibraryDTOConverter.java new file mode 100644 index 00000000000000..a09801c202c6aa --- /dev/null +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/AssetLibraryDTOConverter.java @@ -0,0 +1,179 @@ +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ + +package com.liferay.headless.asset.library.internal.dto.v1_0.converter; + +import com.liferay.depot.model.DepotEntry; +import com.liferay.depot.service.DepotEntryLocalService; +import com.liferay.headless.asset.library.dto.v1_0.AssetLibrary; +import com.liferay.headless.asset.library.dto.v1_0.MimeTypeLimit; +import com.liferay.headless.asset.library.dto.v1_0.Settings; +import com.liferay.headless.asset.library.internal.resource.v1_0.BaseAssetLibraryResourceImpl; +import com.liferay.portal.kernel.model.Group; +import com.liferay.portal.kernel.service.UserGroupLocalService; +import com.liferay.portal.kernel.service.UserLocalService; +import com.liferay.portal.kernel.util.UnicodeProperties; +import com.liferay.portal.vulcan.dto.converter.DTOConverter; +import com.liferay.portal.vulcan.dto.converter.DTOConverterContext; +import com.liferay.portal.vulcan.util.JaxRsLinkUtil; +import com.liferay.portal.vulcan.util.LocalizedMapUtil; + +import java.util.Map; + +import javax.ws.rs.core.UriInfo; + +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * @author Roberto Díaz + */ +@Component( + property = "dto.class.name=com.liferay.depot.model.DepotEntry", + service = DTOConverter.class +) +public class AssetLibraryDTOConverter + implements DTOConverter { + + @Override + public String getContentType() { + return AssetLibrary.class.getSimpleName(); + } + + @Override + public String getJaxRsLink(long classPK, UriInfo uriInfo) { + return JaxRsLinkUtil.getJaxRsLink( + "headless-delivery", BaseAssetLibraryResourceImpl.class, + "getAssetLibrary", uriInfo, classPK); + } + + @Override + public AssetLibrary toDTO(DTOConverterContext dtoConverterContext) + throws Exception { + + return toDTO( + dtoConverterContext, + _depotEntryLocalService.getGroupDepotEntry( + (Long)dtoConverterContext.getId())); + } + + @Override + public AssetLibrary toDTO( + DTOConverterContext dtoConverterContext, DepotEntry depotEntry) + throws Exception { + + Group group = depotEntry.getGroup(); + + return new AssetLibrary() { + { + setDateCreated(depotEntry::getCreateDate); + setDateModified(depotEntry::getModifiedDate); + setDescription( + () -> group.getDescription( + dtoConverterContext.getLocale())); + setDescription_i18n( + () -> LocalizedMapUtil.getI18nMap( + dtoConverterContext.isAcceptAllLanguages(), + group.getDescriptionMap())); + setExternalReferenceCode(group::getExternalReferenceCode); + setId(group::getGroupId); + setName(() -> group.getName(dtoConverterContext.getLocale())); + setName_i18n( + () -> LocalizedMapUtil.getI18nMap( + dtoConverterContext.isAcceptAllLanguages(), + group.getNameMap())); + setNumberOfUserAccounts( + () -> _userLocalService.getGroupUsersCount( + group.getGroupId())); + setNumberOfUserGroups( + () -> _userGroupLocalService.getGroupUserGroupsCount( + group.getGroupId())); + setSettings(() -> _toSettings(group)); + } + }; + } + + private Settings _toSettings(Group group) { + UnicodeProperties unicodeProperties = group.getTypeSettingsProperties(); + + return new Settings() { + { + setAutoTaggingEnabled( + () -> { + for (Map.Entry entry : + unicodeProperties.entrySet()) { + + String key = entry.getKey(); + + if (key.equals("autoTaggingEnabled")) { + return true; + } + } + + return false; + }); + setAvailableLanguageIds(group::getAvailableLanguageIds); + setDefaultLanguageId(group::getDefaultLanguageId); + setLogoColor( + () -> { + for (Map.Entry entry : + unicodeProperties.entrySet()) { + + String key = entry.getKey(); + + if (key.equals("logoColor")) { + return entry.getKey(); + } + } + + // see https://liferay.atlassian.net/browse/LPD-39975 + + return "color-0"; + }); + setMimeTypeLimits( + () -> new MimeTypeLimit[0] // TODO + ); + setSharingEnabled( + () -> { + for (Map.Entry entry : + unicodeProperties.entrySet()) { + + String key = entry.getKey(); + + if (key.equals("sharingEnabled")) { + return true; + } + } + + return false; + }); + setUseCustomLanguages( + () -> { + for (Map.Entry entry : + unicodeProperties.entrySet()) { + + String key = entry.getKey(); + + if (key.equals("useCustomLanguages")) { + return true; + } + } + + return false; + }); + } + }; + } + + @Reference + private DepotEntryLocalService _depotEntryLocalService; + + @Reference + private UserGroupLocalService _userGroupLocalService; + + @Reference + private UserLocalService _userLocalService; + +} \ No newline at end of file diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/AssetLibraryResourceImpl.java b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/AssetLibraryResourceImpl.java index e0cd4e97469dad..3235d579ccaf59 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/AssetLibraryResourceImpl.java +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/AssetLibraryResourceImpl.java @@ -5,9 +5,42 @@ package com.liferay.headless.asset.library.internal.resource.v1_0; +import com.liferay.depot.constants.DepotActionKeys; +import com.liferay.depot.model.DepotAppCustomization; +import com.liferay.depot.model.DepotEntry; +import com.liferay.depot.service.DepotAppCustomizationLocalService; +import com.liferay.depot.service.DepotEntryService; +import com.liferay.headless.asset.library.dto.v1_0.AssetLibrary; +import com.liferay.headless.asset.library.internal.util.comparator.AssetLibraryOrderByComparator; import com.liferay.headless.asset.library.resource.v1_0.AssetLibraryResource; +import com.liferay.portal.kernel.feature.flag.FeatureFlagManagerUtil; +import com.liferay.portal.kernel.model.Group; +import com.liferay.portal.kernel.search.Sort; +import com.liferay.portal.kernel.search.filter.Filter; +import com.liferay.portal.kernel.security.permission.ActionKeys; +import com.liferay.portal.kernel.service.GroupLocalService; +import com.liferay.portal.kernel.service.GroupService; +import com.liferay.portal.kernel.service.ServiceContext; +import com.liferay.portal.kernel.service.ServiceContextFactory; +import com.liferay.portal.kernel.util.HashMapBuilder; +import com.liferay.portal.kernel.util.LinkedHashMapBuilder; +import com.liferay.portal.kernel.util.OrderByComparator; +import com.liferay.portal.kernel.util.Portal; +import com.liferay.portal.kernel.util.UnicodeProperties; +import com.liferay.portal.vulcan.dto.converter.DTOConverter; +import com.liferay.portal.vulcan.dto.converter.DTOConverterRegistry; +import com.liferay.portal.vulcan.dto.converter.DefaultDTOConverterContext; +import com.liferay.portal.vulcan.pagination.Page; +import com.liferay.portal.vulcan.pagination.Pagination; +import com.liferay.portal.vulcan.util.LocalizedMapUtil; + +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.ServiceScope; /** @@ -18,4 +51,332 @@ scope = ServiceScope.PROTOTYPE, service = AssetLibraryResource.class ) public class AssetLibraryResourceImpl extends BaseAssetLibraryResourceImpl { + + @Override + public void deleteAssetLibrary(Long assetLibraryId) throws Exception { + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + DepotEntry depotEntry = _depotEntryService.getGroupDepotEntry( + assetLibraryId); + + _depotEntryService.deleteDepotEntry(depotEntry.getDepotEntryId()); + } + + @Override + public void deleteAssetLibraryByExternalReferenceCode( + String externalReferenceCode) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + deleteAssetLibrary( + _getGroupIdByExternalReferenceCode(externalReferenceCode)); + } + + @Override + public Page getAssetLibrariesPage( + String keywords, String search, Filter filter, + Pagination pagination, Sort[] sorts) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + OrderByComparator assetLibraryOrderByComparator = null; + + if (sorts != null) { + assetLibraryOrderByComparator = new AssetLibraryOrderByComparator<>( + contextAcceptLanguage.getPreferredLocale(), sorts); + } + + return Page.of( + transform( + _groupService.search( + contextCompany.getCompanyId(), + new long[] { + _portal.getClassNameId(DepotEntry.class.getName()) + }, + keywords, _getParams(), pagination.getStartPosition(), + pagination.getEndPosition(), assetLibraryOrderByComparator), + group -> _assetLibraryDTOConverter.toDTO( + new DefaultDTOConverterContext( + contextAcceptLanguage.isAcceptAllLanguages(), + new HashMap<>(), _dtoConverterRegistry, + group.getGroupId(), + contextAcceptLanguage.getPreferredLocale(), + contextUriInfo, contextUser), + _depotEntryService.getGroupDepotEntry(group.getGroupId()))), + pagination, + _groupService.searchCount( + contextCompany.getCompanyId(), + new long[] {_portal.getClassNameId(DepotEntry.class.getName())}, + keywords, _getParams())); + } + + @Override + public AssetLibrary getAssetLibrary(Long assetLibraryId) throws Exception { + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + return _toAssetLibrary( + _depotEntryService.getGroupDepotEntry(assetLibraryId)); + } + + @Override + public AssetLibrary getAssetLibraryByExternalReferenceCode( + String externalReferenceCode) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + return _toAssetLibrary( + _depotEntryService.getGroupDepotEntry( + _getGroupIdByExternalReferenceCode(externalReferenceCode))); + } + + @Override + public AssetLibrary patchAssetLibrary( + Long assetLibraryId, AssetLibrary assetLibrary) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + DepotEntry depotEntry = _depotEntryService.getGroupDepotEntry( + assetLibraryId); + + String name = assetLibrary.getName(); + + Group group = depotEntry.getGroup(); + + if (name == null) { + name = group.getName(contextAcceptLanguage.getPreferredLocale()); + } + + Map nameMap = assetLibrary.getName_i18n(); + + if (nameMap == null) { + nameMap = LocalizedMapUtil.getI18nMap(group.getNameMap()); + } + + String description = assetLibrary.getDescription(); + + if (description == null) { + description = group.getDescription( + contextAcceptLanguage.getPreferredLocale()); + } + + Map descriptionMap = assetLibrary.getDescription_i18n(); + + if (descriptionMap == null) { + descriptionMap = LocalizedMapUtil.getI18nMap( + group.getDescriptionMap()); + } + + // TODO transform the assetLibrary::settings in unicodeProperties where + // needed + + return _toAssetLibrary( + _depotEntryService.updateDepotEntry( + depotEntry.getDepotEntryId(), + LocalizedMapUtil.getLocalizedMap( + contextAcceptLanguage.getPreferredLocale(), name, nameMap), + LocalizedMapUtil.getLocalizedMap( + contextAcceptLanguage.getPreferredLocale(), description, + descriptionMap), + _getDepotCustomizationMap(group.getExternalReferenceCode()), + _getUnicodeProperties(group.getExternalReferenceCode()), + _getServiceContext())); + } + + @Override + public AssetLibrary patchAssetLibraryByExternalReferenceCode( + String externalReferenceCode, AssetLibrary assetLibrary) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + return patchAssetLibrary( + _getGroupIdByExternalReferenceCode(externalReferenceCode), + assetLibrary); + } + + @Override + public AssetLibrary postAssetLibrary(AssetLibrary assetLibrary) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + return _toAssetLibrary( + _depotEntryService.addDepotEntry( + LocalizedMapUtil.getLocalizedMap( + contextAcceptLanguage.getPreferredLocale(), + assetLibrary.getName(), assetLibrary.getName_i18n()), + LocalizedMapUtil.getLocalizedMap( + contextAcceptLanguage.getPreferredLocale(), + assetLibrary.getDescription(), + assetLibrary.getDescription_i18n()), + _getServiceContext())); + } + + @Override + public AssetLibrary putAssetLibraryByExternalReferenceCode( + String externalReferenceCode, AssetLibrary assetLibrary) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + return _toAssetLibrary( + _depotEntryService.addOrUpdateDepotEntry( + externalReferenceCode, + LocalizedMapUtil.getLocalizedMap( + contextAcceptLanguage.getPreferredLocale(), + assetLibrary.getName(), assetLibrary.getName_i18n()), + LocalizedMapUtil.getLocalizedMap( + contextAcceptLanguage.getPreferredLocale(), + assetLibrary.getDescription(), + assetLibrary.getDescription_i18n()), + _getDepotCustomizationMap(externalReferenceCode), + _getUnicodeProperties(externalReferenceCode), + _getServiceContext())); + } + + private Map _getDepotCustomizationMap( + String externalReferenceCode) + throws Exception { + + Map depotAppCustomizationMap = new HashMap<>(); + + Group group = _groupLocalService.fetchGroupByExternalReferenceCode( + externalReferenceCode, contextCompany.getCompanyId()); + + if (group != null) { + DepotEntry depotEntry = _depotEntryService.getGroupDepotEntry( + group.getGroupId()); + + for (DepotAppCustomization depotAppCustomization : + _depotAppCustomizationLocalService. + getDepotAppCustomizations( + depotEntry.getDepotEntryId())) { + + depotAppCustomizationMap.put( + depotAppCustomization.getPortletId(), + depotAppCustomization.isEnabled()); + } + } + + return depotAppCustomizationMap; + } + + private long _getGroupIdByExternalReferenceCode( + String externalReferenceCode) + throws Exception { + + Group group = _groupLocalService.getGroupByExternalReferenceCode( + externalReferenceCode, contextCompany.getCompanyId()); + + return group.getGroupId(); + } + + private LinkedHashMap _getParams() { + return LinkedHashMapBuilder.put( + "actionId", ActionKeys.VIEW + ).put( + "active", Boolean.TRUE + ).put( + "site", Boolean.FALSE + ).build(); + } + + private ServiceContext _getServiceContext() throws Exception { + ServiceContext serviceContext = ServiceContextFactory.getInstance( + DepotEntry.class.getName(), contextHttpServletRequest); + + serviceContext.setModifiedDate(new Date()); + + return serviceContext; + } + + private UnicodeProperties _getUnicodeProperties( + String externalReferenceCode) { + + UnicodeProperties unicodeProperties = new UnicodeProperties(true); + + Group group = _groupLocalService.fetchGroupByExternalReferenceCode( + externalReferenceCode, contextCompany.getCompanyId()); + + if (group != null) { + unicodeProperties = group.getTypeSettingsProperties(); + } + + return unicodeProperties; + } + + private AssetLibrary _toAssetLibrary(DepotEntry depotEntry) + throws Exception { + + return _assetLibraryDTOConverter.toDTO( + new DefaultDTOConverterContext( + contextAcceptLanguage.isAcceptAllLanguages(), + HashMapBuilder.put( + "create", + addAction( + DepotActionKeys.ADD_DEPOT_ENTRY, depotEntry, + "postAssetLibrary") + ).put( + "delete", + addAction( + ActionKeys.DELETE, depotEntry, "deleteAssetLibrary") + ).put( + "get", + addAction(ActionKeys.VIEW, depotEntry, "getAssetLibrary") + ).put( + "update", + addAction( + ActionKeys.UPDATE, depotEntry, "patchAssetLibrary") + ).build(), + _dtoConverterRegistry, depotEntry.getGroupId(), + contextAcceptLanguage.getPreferredLocale(), contextUriInfo, + contextUser)); + } + + @Reference( + target = "(component.name=com.liferay.headless.asset.library.internal.dto.v1_0.converter.AssetLibraryDTOConverter)" + ) + private DTOConverter _assetLibraryDTOConverter; + + @Reference + private DepotAppCustomizationLocalService + _depotAppCustomizationLocalService; + + @Reference + private DepotEntryService _depotEntryService; + + @Reference + private DTOConverterRegistry _dtoConverterRegistry; + + @Reference + private GroupLocalService _groupLocalService; + + @Reference + private GroupService _groupService; + + @Reference + private Portal _portal; + } \ No newline at end of file diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/util/comparator/AssetLibraryOrderByComparator.java b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/util/comparator/AssetLibraryOrderByComparator.java new file mode 100644 index 00000000000000..ec98511f06243d --- /dev/null +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/util/comparator/AssetLibraryOrderByComparator.java @@ -0,0 +1,124 @@ +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ + +package com.liferay.headless.asset.library.internal.util.comparator; + +import com.liferay.portal.kernel.bean.BeanPropertiesUtil; +import com.liferay.portal.kernel.search.Sort; +import com.liferay.portal.kernel.util.CollatorUtil; +import com.liferay.portal.kernel.util.LocalizationUtil; +import com.liferay.portal.kernel.util.OrderByComparator; +import com.liferay.portal.kernel.util.StringUtil; +import com.liferay.portal.kernel.util.Validator; + +import java.text.Collator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Objects; + +/** + * @author Alicia García + */ +public class AssetLibraryOrderByComparator extends OrderByComparator { + + public AssetLibraryOrderByComparator(Locale locale, Sort[] sorts) { + List columns = new ArrayList<>(); + + for (Sort sort : sorts) { + columns.add(sort.getFieldName()); + columns.add(!sort.isReverse()); + } + + if (columns.isEmpty() || ((columns.size() % 2) != 0)) { + throw new IllegalArgumentException( + "Columns length is not an even number"); + } + + _locale = locale; + + _columns = columns; + } + + @Override + public int compare(T object1, T object2) { + for (int i = 0; i < _columns.size(); i += 2) { + String columnName = String.valueOf(_columns.get(i)); + + if (Objects.equals(columnName, "assetLibraryKey")) { + columnName = "groupKey"; + } + + if (Objects.equals(columnName, "id") || + Objects.equals(columnName, "siteId")) { + + columnName = "groupId"; + } + + Object columnValue1 = BeanPropertiesUtil.getObjectSilent( + object1, columnName); + Object columnValue2 = BeanPropertiesUtil.getObjectSilent( + object2, columnName); + + int value = 0; + + if ((columnValue1 instanceof String) && + (columnValue2 instanceof String)) { + + String columnValue1String = (String)columnValue1; + String columnValue2String = (String)columnValue2; + + if (Validator.isXml(columnValue1String)) { + columnValue1String = LocalizationUtil.getLocalization( + columnValue1String, _locale.getLanguage()); + columnValue2String = LocalizationUtil.getLocalization( + columnValue2String, _locale.getLanguage()); + + Collator collator = CollatorUtil.getInstance(_locale); + + value = collator.compare( + StringUtil.toLowerCase(columnValue1String), + StringUtil.toLowerCase(columnValue2String)); + } + else { + value = columnValue1String.compareToIgnoreCase( + columnValue2String); + } + } + else { + Comparable columnValueComparable1 = + (Comparable)columnValue1; + + if (columnValueComparable1 != null) { + Comparable columnValueComparable2 = + (Comparable)columnValue2; + + value = columnValueComparable1.compareTo( + columnValueComparable2); + } + } + + if (value == 0) { + continue; + } + + boolean columnAscending = Boolean.valueOf( + String.valueOf(_columns.get(i + 1))); + + if (columnAscending) { + return value; + } + + return -value; + } + + return 0; + } + + private final List _columns; + private final Locale _locale; + +} \ No newline at end of file From 0f361b1a9d63f8a50e0cff952c75dcc2f0fe4476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Thu, 13 Mar 2025 00:30:41 +0100 Subject: [PATCH 03/13] LPD-49536 Add new methods in depot service in order to allow add or update based in external reference code --- .../impl/DepotEntryLocalServiceImpl.java | 35 +++++++++++++++++ .../service/impl/DepotEntryServiceImpl.java | 39 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryLocalServiceImpl.java b/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryLocalServiceImpl.java index ff7327512e124e..cc24e86bcea47c 100644 --- a/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryLocalServiceImpl.java +++ b/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryLocalServiceImpl.java @@ -142,6 +142,41 @@ public DepotEntry addDepotEntry( return depotEntry; } + @Override + public DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, Map nameMap, + Map descriptionMap, + Map depotAppCustomizationMap, + UnicodeProperties typeSettingsUnicodeProperties, + ServiceContext serviceContext) + throws PortalException { + + DepotEntry depotEntry = null; + + Group group = _groupLocalService.fetchGroupByExternalReferenceCode( + externalReferenceCode, serviceContext.getCompanyId()); + + if (group != null) { + depotEntry = getGroupDepotEntry(group.getGroupId()); + + depotEntry = updateDepotEntry( + depotEntry.getDepotEntryId(), nameMap, descriptionMap, + depotAppCustomizationMap, typeSettingsUnicodeProperties, + serviceContext); + } + else { + depotEntry = addDepotEntry(nameMap, descriptionMap, serviceContext); + } + + group = depotEntry.getGroup(); + + group.setExternalReferenceCode(externalReferenceCode); + + _groupLocalService.updateGroup(group); + + return getDepotEntry(depotEntry.getDepotEntryId()); + } + @Override public DepotEntry deleteDepotEntry(DepotEntry depotEntry) throws PortalException { diff --git a/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryServiceImpl.java b/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryServiceImpl.java index 48df6eca2bcdd3..45aa1c0ec5701a 100644 --- a/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryServiceImpl.java +++ b/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/impl/DepotEntryServiceImpl.java @@ -12,10 +12,12 @@ import com.liferay.portal.aop.AopService; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.model.Group; +import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.security.permission.ActionKeys; import com.liferay.portal.kernel.security.permission.PermissionChecker; import com.liferay.portal.kernel.security.permission.resource.ModelResourcePermission; import com.liferay.portal.kernel.security.permission.resource.PortletResourcePermission; +import com.liferay.portal.kernel.service.GroupLocalService; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.service.permission.GroupPermissionUtil; import com.liferay.portal.kernel.util.UnicodeProperties; @@ -57,6 +59,40 @@ public DepotEntry addDepotEntry( nameMap, descriptionMap, serviceContext); } + @Override + public DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, Map nameMap, + Map descriptionMap, + Map depotAppCustomizationMap, + UnicodeProperties typeSettingsUnicodeProperties, + ServiceContext serviceContext) + throws PortalException { + + User user = getUser(); + + Group group = _groupLocalService.fetchGroupByExternalReferenceCode( + externalReferenceCode, user.getCompanyId()); + + if (group != null) { + DepotEntry depotEntry = depotEntryLocalService.getGroupDepotEntry( + group.getGroupId()); + + _depotEntryModelResourcePermission.check( + getPermissionChecker(), depotEntry.getDepotEntryId(), + ActionKeys.UPDATE); + } + else { + _portletResourcePermission.check( + getPermissionChecker(), serviceContext.getScopeGroupId(), + DepotActionKeys.ADD_DEPOT_ENTRY); + } + + return depotEntryLocalService.addOrUpdateDepotEntry( + externalReferenceCode, nameMap, descriptionMap, + depotAppCustomizationMap, typeSettingsUnicodeProperties, + serviceContext); + } + @Override public DepotEntry deleteDepotEntry(long depotEntryId) throws PortalException { @@ -198,6 +234,9 @@ public DepotEntry updateDepotEntry( private volatile ModelResourcePermission _depotEntryModelResourcePermission; + @Reference + private GroupLocalService _groupLocalService; + @Reference( policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, From 2612b014cd71b4ce045779698f0625776cfec194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Thu, 13 Mar 2025 20:22:38 +0100 Subject: [PATCH 04/13] LPD-49536 Build service --- modules/apps/depot/depot-api/bnd.bnd | 2 +- .../depot/service/DepotEntryLocalService.java | 8 ++ .../service/DepotEntryLocalServiceUtil.java | 15 ++++ .../DepotEntryLocalServiceWrapper.java | 17 ++++ .../depot/service/DepotEntryService.java | 8 ++ .../depot/service/DepotEntryServiceUtil.java | 15 ++++ .../service/DepotEntryServiceWrapper.java | 17 ++++ .../com/liferay/depot/service/packageinfo | 2 +- .../service/http/DepotEntryServiceHttp.java | 87 +++++++++++++++---- 9 files changed, 153 insertions(+), 18 deletions(-) diff --git a/modules/apps/depot/depot-api/bnd.bnd b/modules/apps/depot/depot-api/bnd.bnd index ba25e86b6b53dd..94c7df672b2e74 100644 --- a/modules/apps/depot/depot-api/bnd.bnd +++ b/modules/apps/depot/depot-api/bnd.bnd @@ -1,6 +1,6 @@ Bundle-Name: Liferay Depot API Bundle-SymbolicName: com.liferay.depot.api -Bundle-Version: 7.1.1 +Bundle-Version: 7.2.0 Export-Package:\ com.liferay.depot.application,\ com.liferay.depot.configuration,\ diff --git a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalService.java b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalService.java index 4ea894bac0bf88..a85154c6466f1d 100644 --- a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalService.java +++ b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalService.java @@ -87,6 +87,14 @@ public DepotEntry addDepotEntry( ServiceContext serviceContext) throws PortalException; + public DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, Map nameMap, + Map descriptionMap, + Map depotAppCustomizationMap, + UnicodeProperties typeSettingsUnicodeProperties, + ServiceContext serviceContext) + throws PortalException; + /** * Creates a new depot entry with the primary key. Does not add the depot entry to the database. * diff --git a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceUtil.java b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceUtil.java index f9f1f948631a0a..a731463a23052f 100644 --- a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceUtil.java +++ b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceUtil.java @@ -70,6 +70,21 @@ public static DepotEntry addDepotEntry( nameMap, descriptionMap, serviceContext); } + public static DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, Map nameMap, + Map descriptionMap, + Map depotAppCustomizationMap, + com.liferay.portal.kernel.util.UnicodeProperties + typeSettingsUnicodeProperties, + com.liferay.portal.kernel.service.ServiceContext serviceContext) + throws PortalException { + + return getService().addOrUpdateDepotEntry( + externalReferenceCode, nameMap, descriptionMap, + depotAppCustomizationMap, typeSettingsUnicodeProperties, + serviceContext); + } + /** * Creates a new depot entry with the primary key. Does not add the depot entry to the database. * diff --git a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceWrapper.java b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceWrapper.java index 1a762614dfa06d..d034549aa5b394 100644 --- a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceWrapper.java +++ b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryLocalServiceWrapper.java @@ -66,6 +66,23 @@ public DepotEntry addDepotEntry( nameMap, descriptionMap, serviceContext); } + @Override + public DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, + java.util.Map nameMap, + java.util.Map descriptionMap, + java.util.Map depotAppCustomizationMap, + com.liferay.portal.kernel.util.UnicodeProperties + typeSettingsUnicodeProperties, + com.liferay.portal.kernel.service.ServiceContext serviceContext) + throws com.liferay.portal.kernel.exception.PortalException { + + return _depotEntryLocalService.addOrUpdateDepotEntry( + externalReferenceCode, nameMap, descriptionMap, + depotAppCustomizationMap, typeSettingsUnicodeProperties, + serviceContext); + } + /** * Creates a new depot entry with the primary key. Does not add the depot entry to the database. * diff --git a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryService.java b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryService.java index b1022110a56aea..417dbfffe52140 100644 --- a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryService.java +++ b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryService.java @@ -53,6 +53,14 @@ public DepotEntry addDepotEntry( ServiceContext serviceContext) throws PortalException; + public DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, Map nameMap, + Map descriptionMap, + Map depotAppCustomizationMap, + UnicodeProperties typeSettingsUnicodeProperties, + ServiceContext serviceContext) + throws PortalException; + public DepotEntry deleteDepotEntry(long depotEntryId) throws PortalException; diff --git a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceUtil.java b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceUtil.java index f6d0762357d7ea..9c955dce6a2c84 100644 --- a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceUtil.java +++ b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceUtil.java @@ -41,6 +41,21 @@ public static DepotEntry addDepotEntry( nameMap, descriptionMap, serviceContext); } + public static DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, Map nameMap, + Map descriptionMap, + Map depotAppCustomizationMap, + com.liferay.portal.kernel.util.UnicodeProperties + typeSettingsUnicodeProperties, + com.liferay.portal.kernel.service.ServiceContext serviceContext) + throws PortalException { + + return getService().addOrUpdateDepotEntry( + externalReferenceCode, nameMap, descriptionMap, + depotAppCustomizationMap, typeSettingsUnicodeProperties, + serviceContext); + } + public static DepotEntry deleteDepotEntry(long depotEntryId) throws PortalException { diff --git a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceWrapper.java b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceWrapper.java index 4c04cb71fe62d6..b765f9eeb27437 100644 --- a/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceWrapper.java +++ b/modules/apps/depot/depot-api/src/main/java/com/liferay/depot/service/DepotEntryServiceWrapper.java @@ -37,6 +37,23 @@ public DepotEntry addDepotEntry( nameMap, descriptionMap, serviceContext); } + @Override + public DepotEntry addOrUpdateDepotEntry( + String externalReferenceCode, + java.util.Map nameMap, + java.util.Map descriptionMap, + java.util.Map depotAppCustomizationMap, + com.liferay.portal.kernel.util.UnicodeProperties + typeSettingsUnicodeProperties, + com.liferay.portal.kernel.service.ServiceContext serviceContext) + throws com.liferay.portal.kernel.exception.PortalException { + + return _depotEntryService.addOrUpdateDepotEntry( + externalReferenceCode, nameMap, descriptionMap, + depotAppCustomizationMap, typeSettingsUnicodeProperties, + serviceContext); + } + @Override public DepotEntry deleteDepotEntry(long depotEntryId) throws com.liferay.portal.kernel.exception.PortalException { diff --git a/modules/apps/depot/depot-api/src/main/resources/com/liferay/depot/service/packageinfo b/modules/apps/depot/depot-api/src/main/resources/com/liferay/depot/service/packageinfo index 2c9afe82e39e46..bbcbfe4fb3b987 100644 --- a/modules/apps/depot/depot-api/src/main/resources/com/liferay/depot/service/packageinfo +++ b/modules/apps/depot/depot-api/src/main/resources/com/liferay/depot/service/packageinfo @@ -1 +1 @@ -version 2.1.0 \ No newline at end of file +version 2.2.0 \ No newline at end of file diff --git a/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/http/DepotEntryServiceHttp.java b/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/http/DepotEntryServiceHttp.java index 293942592c160d..269009abb848aa 100644 --- a/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/http/DepotEntryServiceHttp.java +++ b/modules/apps/depot/depot-service/src/main/java/com/liferay/depot/service/http/DepotEntryServiceHttp.java @@ -84,6 +84,54 @@ public static com.liferay.depot.model.DepotEntry addDepotEntry( } } + public static com.liferay.depot.model.DepotEntry addOrUpdateDepotEntry( + HttpPrincipal httpPrincipal, String externalReferenceCode, + java.util.Map nameMap, + java.util.Map descriptionMap, + java.util.Map depotAppCustomizationMap, + com.liferay.portal.kernel.util.UnicodeProperties + typeSettingsUnicodeProperties, + com.liferay.portal.kernel.service.ServiceContext serviceContext) + throws com.liferay.portal.kernel.exception.PortalException { + + try { + MethodKey methodKey = new MethodKey( + DepotEntryServiceUtil.class, "addOrUpdateDepotEntry", + _addOrUpdateDepotEntryParameterTypes1); + + MethodHandler methodHandler = new MethodHandler( + methodKey, externalReferenceCode, nameMap, descriptionMap, + depotAppCustomizationMap, typeSettingsUnicodeProperties, + serviceContext); + + Object returnObj = null; + + try { + returnObj = TunnelUtil.invoke(httpPrincipal, methodHandler); + } + catch (Exception exception) { + if (exception instanceof + com.liferay.portal.kernel.exception.PortalException) { + + throw (com.liferay.portal.kernel.exception.PortalException) + exception; + } + + throw new com.liferay.portal.kernel.exception.SystemException( + exception); + } + + return (com.liferay.depot.model.DepotEntry)returnObj; + } + catch (com.liferay.portal.kernel.exception.SystemException + systemException) { + + _log.error(systemException, systemException); + + throw systemException; + } + } + public static com.liferay.depot.model.DepotEntry deleteDepotEntry( HttpPrincipal httpPrincipal, long depotEntryId) throws com.liferay.portal.kernel.exception.PortalException { @@ -91,7 +139,7 @@ public static com.liferay.depot.model.DepotEntry deleteDepotEntry( try { MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "deleteDepotEntry", - _deleteDepotEntryParameterTypes1); + _deleteDepotEntryParameterTypes2); MethodHandler methodHandler = new MethodHandler( methodKey, depotEntryId); @@ -133,7 +181,7 @@ public static com.liferay.depot.model.DepotEntry deleteDepotEntry( MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "getCurrentAndGroupConnectedDepotEntries", - _getCurrentAndGroupConnectedDepotEntriesParameterTypes2); + _getCurrentAndGroupConnectedDepotEntriesParameterTypes3); MethodHandler methodHandler = new MethodHandler( methodKey, groupId, start, end); @@ -174,7 +222,7 @@ public static com.liferay.depot.model.DepotEntry getDepotEntry( try { MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "getDepotEntry", - _getDepotEntryParameterTypes3); + _getDepotEntryParameterTypes4); MethodHandler methodHandler = new MethodHandler( methodKey, depotEntryId); @@ -216,7 +264,7 @@ public static com.liferay.depot.model.DepotEntry getDepotEntry( try { MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "getGroupConnectedDepotEntries", - _getGroupConnectedDepotEntriesParameterTypes4); + _getGroupConnectedDepotEntriesParameterTypes5); MethodHandler methodHandler = new MethodHandler( methodKey, groupId, ddmStructuresAvailable, start, end); @@ -258,7 +306,7 @@ public static com.liferay.depot.model.DepotEntry getDepotEntry( try { MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "getGroupConnectedDepotEntries", - _getGroupConnectedDepotEntriesParameterTypes5); + _getGroupConnectedDepotEntriesParameterTypes6); MethodHandler methodHandler = new MethodHandler( methodKey, groupId, start, end); @@ -300,7 +348,7 @@ public static int getGroupConnectedDepotEntriesCount( MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "getGroupConnectedDepotEntriesCount", - _getGroupConnectedDepotEntriesCountParameterTypes6); + _getGroupConnectedDepotEntriesCountParameterTypes7); MethodHandler methodHandler = new MethodHandler(methodKey, groupId); @@ -339,7 +387,7 @@ public static com.liferay.depot.model.DepotEntry getGroupDepotEntry( try { MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "getGroupDepotEntry", - _getGroupDepotEntryParameterTypes7); + _getGroupDepotEntryParameterTypes8); MethodHandler methodHandler = new MethodHandler(methodKey, groupId); @@ -384,7 +432,7 @@ public static com.liferay.depot.model.DepotEntry updateDepotEntry( try { MethodKey methodKey = new MethodKey( DepotEntryServiceUtil.class, "updateDepotEntry", - _updateDepotEntryParameterTypes8); + _updateDepotEntryParameterTypes9); MethodHandler methodHandler = new MethodHandler( methodKey, depotEntryId, nameMap, descriptionMap, @@ -427,29 +475,36 @@ public static com.liferay.depot.model.DepotEntry updateDepotEntry( java.util.Map.class, java.util.Map.class, com.liferay.portal.kernel.service.ServiceContext.class }; - private static final Class[] _deleteDepotEntryParameterTypes1 = + private static final Class[] _addOrUpdateDepotEntryParameterTypes1 = + new Class[] { + String.class, java.util.Map.class, java.util.Map.class, + java.util.Map.class, + com.liferay.portal.kernel.util.UnicodeProperties.class, + com.liferay.portal.kernel.service.ServiceContext.class + }; + private static final Class[] _deleteDepotEntryParameterTypes2 = new Class[] {long.class}; private static final Class[] - _getCurrentAndGroupConnectedDepotEntriesParameterTypes2 = new Class[] { + _getCurrentAndGroupConnectedDepotEntriesParameterTypes3 = new Class[] { long.class, int.class, int.class }; - private static final Class[] _getDepotEntryParameterTypes3 = + private static final Class[] _getDepotEntryParameterTypes4 = new Class[] {long.class}; private static final Class[] - _getGroupConnectedDepotEntriesParameterTypes4 = new Class[] { + _getGroupConnectedDepotEntriesParameterTypes5 = new Class[] { long.class, boolean.class, int.class, int.class }; private static final Class[] - _getGroupConnectedDepotEntriesParameterTypes5 = new Class[] { + _getGroupConnectedDepotEntriesParameterTypes6 = new Class[] { long.class, int.class, int.class }; private static final Class[] - _getGroupConnectedDepotEntriesCountParameterTypes6 = new Class[] { + _getGroupConnectedDepotEntriesCountParameterTypes7 = new Class[] { long.class }; - private static final Class[] _getGroupDepotEntryParameterTypes7 = + private static final Class[] _getGroupDepotEntryParameterTypes8 = new Class[] {long.class}; - private static final Class[] _updateDepotEntryParameterTypes8 = + private static final Class[] _updateDepotEntryParameterTypes9 = new Class[] { long.class, java.util.Map.class, java.util.Map.class, java.util.Map.class, From a07d926b726e05055e6f52088b8fc53d72aaf46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Thu, 13 Mar 2025 10:56:03 +0100 Subject: [PATCH 05/13] LPD-49536 Tests --- .../v1_0/test/AssetLibraryResourceTest.java | 158 +++++++++++++++++- 1 file changed, 156 insertions(+), 2 deletions(-) diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/AssetLibraryResourceTest.java b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/AssetLibraryResourceTest.java index 6b6d070dc0019b..3fb41b6cc20a9d 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/AssetLibraryResourceTest.java +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/AssetLibraryResourceTest.java @@ -6,14 +6,168 @@ package com.liferay.headless.asset.library.resource.v1_0.test; import com.liferay.arquillian.extension.junit.bridge.junit.Arquillian; +import com.liferay.depot.model.DepotEntry; +import com.liferay.depot.service.DepotEntryGroupRelLocalService; +import com.liferay.depot.service.DepotEntryLocalService; +import com.liferay.headless.asset.library.client.dto.v1_0.AssetLibrary; +import com.liferay.headless.asset.library.client.problem.Problem; +import com.liferay.portal.kernel.model.Group; +import com.liferay.portal.kernel.service.UserGroupLocalService; +import com.liferay.portal.kernel.service.UserLocalService; +import com.liferay.portal.kernel.test.util.RandomTestUtil; +import com.liferay.portal.odata.entity.EntityField; +import com.liferay.portal.test.rule.FeatureFlags; +import com.liferay.portal.test.rule.Inject; -import org.junit.Ignore; +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Assert; +import org.junit.Test; import org.junit.runner.RunWith; /** * @author Roberto Díaz */ -@Ignore +@FeatureFlags("LPD-17564") @RunWith(Arquillian.class) public class AssetLibraryResourceTest extends BaseAssetLibraryResourceTestCase { + + @Override + @Test + public void testDeleteAssetLibrary() throws Exception { + super.testDeleteAssetLibrary(); + + // Nonexistent asset library ID + + long assetLibraryId = RandomTestUtil.randomLong(); + + try { + assetLibraryResource.deleteAssetLibrary(assetLibraryId); + + Assert.fail(); + } + catch (Problem.ProblemException problemException) { + Problem problem = problemException.getProblem(); + + Assert.assertEquals("NOT_FOUND", problem.getStatus()); + Assert.assertNull(problem.getTitle()); + } + } + + @Override + protected void assertValid(AssetLibrary assetLibrary) throws Exception { + DepotEntry originalTestDepotEntry = testDepotEntry; + Group originalTestGroup = testGroup; + + DepotEntry depotEntry = _depotEntryLocalService.getGroupDepotEntry( + assetLibrary.getId()); + + testDepotEntry = depotEntry; + testGroup = depotEntry.getGroup(); + + super.assertValid(assetLibrary); + + testDepotEntry = originalTestDepotEntry; + testGroup = originalTestGroup; + } + + @Override + protected Collection getEntityFields() throws Exception { + return new ArrayList<>(); + } + + @Override + protected AssetLibrary randomPatchAssetLibrary() throws Exception { + AssetLibrary assetLibrary = randomAssetLibrary(); + + assetLibrary.setName(RandomTestUtil.randomString()); + + return assetLibrary; + } + + @Override + protected AssetLibrary testDeleteAssetLibrary_addAssetLibrary() + throws Exception { + + return _addAssetLibrary(); + } + + protected AssetLibrary + testDeleteAssetLibraryByExternalReferenceCode_addAssetLibrary() + throws Exception { + + return _addAssetLibrary(); + } + + @Override + protected AssetLibrary testGetAssetLibrariesPage_addAssetLibrary( + AssetLibrary assetLibrary) + throws Exception { + + return assetLibraryResource.postAssetLibrary(assetLibrary); + } + + @Override + protected AssetLibrary testGetAssetLibrary_addAssetLibrary() + throws Exception { + + return _addAssetLibrary(); + } + + @Override + protected AssetLibrary + testGetAssetLibraryByExternalReferenceCode_addAssetLibrary() + throws Exception { + + return _addAssetLibrary(); + } + + @Override + protected AssetLibrary testPatchAssetLibrary_addAssetLibrary() + throws Exception { + + return _addAssetLibrary(); + } + + @Override + protected AssetLibrary + testPatchAssetLibraryByExternalReferenceCode_addAssetLibrary() + throws Exception { + + return _addAssetLibrary(); + } + + @Override + protected AssetLibrary testPostAssetLibrary_addAssetLibrary( + AssetLibrary assetLibrary) + throws Exception { + + return assetLibraryResource.postAssetLibrary(assetLibrary); + } + + @Override + protected AssetLibrary + testPutAssetLibraryByExternalReferenceCode_addAssetLibrary() + throws Exception { + + return _addAssetLibrary(); + } + + private AssetLibrary _addAssetLibrary() throws Exception { + return assetLibraryResource.postAssetLibrary(randomAssetLibrary()); + } + + @Inject + private DepotEntryGroupRelLocalService _depotEntryGroupRelLocalService; + + @Inject + private DepotEntryLocalService _depotEntryLocalService; + + @Inject + private UserGroupLocalService _userGroupLocalService; + + @Inject + private UserLocalService _userLocalService; + } \ No newline at end of file From 3b663f920166ce73a03831e1ab4163ae34a64150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Tue, 18 Mar 2025 07:40:19 +0100 Subject: [PATCH 06/13] LPD-49536 Fix template errors --- .../rest/builder/dependencies/base_resource_test_case.ftl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/util/portal-tools-rest-builder/src/main/resources/com/liferay/portal/tools/rest/builder/dependencies/base_resource_test_case.ftl b/modules/util/portal-tools-rest-builder/src/main/resources/com/liferay/portal/tools/rest/builder/dependencies/base_resource_test_case.ftl index f83772cd91a498..e38e753d54d28d 100644 --- a/modules/util/portal-tools-rest-builder/src/main/resources/com/liferay/portal/tools/rest/builder/dependencies/base_resource_test_case.ftl +++ b/modules/util/portal-tools-rest-builder/src/main/resources/com/liferay/portal/tools/rest/builder/dependencies/base_resource_test_case.ftl @@ -570,7 +570,9 @@ public abstract class Base${schemaName}ResourceTestCase { , - <#if stringUtil.equals(javaMethodParameter.parameterName, "pagination")> + <#if stringUtil.equals(javaMethodParameter.parameterName, "keywords")> + null + <#elseif stringUtil.equals(javaMethodParameter.parameterName, "pagination")> Pagination.of(1, 10) <#elseif stringUtil.equals(javaMethodParameter.parameterName, "search")> null @@ -1274,7 +1276,7 @@ public abstract class Base${schemaName}ResourceTestCase { <#list javaMethodSignature.pathJavaMethodParameters as javaMethodParameter> protected ${javaMethodParameter.parameterType} test${javaMethodSignature.methodName?cap_first}_get${javaMethodParameter.parameterName?cap_first}() throws Exception { - <#if stringUtil.equals(javaMethodParameter.parameterName, "assetLibraryId")> + <#if generateDepotEntry && stringUtil.equals(javaMethodParameter.parameterName, "assetLibraryId")> return testDepotEntry.getDepotEntryId(); <#elseif stringUtil.equals(javaMethodParameter.parameterName, "siteId")> return testGroup.getGroupId(); From 0b7de075735228429126ccd066bfedd162c64eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Tue, 18 Mar 2025 07:45:22 +0100 Subject: [PATCH 07/13] LPD-49536 Allow pass the groupId as "assetLibraryId" --- .../liferay/portal/vulcan/util/GroupUtil.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/modules/apps/portal-vulcan/portal-vulcan-api/src/main/java/com/liferay/portal/vulcan/util/GroupUtil.java b/modules/apps/portal-vulcan/portal-vulcan-api/src/main/java/com/liferay/portal/vulcan/util/GroupUtil.java index aaa5fdb21cb14e..1b77baf367ab4e 100644 --- a/modules/apps/portal-vulcan/portal-vulcan-api/src/main/java/com/liferay/portal/vulcan/util/GroupUtil.java +++ b/modules/apps/portal-vulcan/portal-vulcan-api/src/main/java/com/liferay/portal/vulcan/util/GroupUtil.java @@ -32,25 +32,31 @@ public static Long getDepotGroupId( DepotEntryLocalService depotEntryLocalService, GroupLocalService groupLocalService) { - Group group = groupLocalService.fetchGroup(companyId, assetLibraryKey); + Group group = groupLocalService.fetchGroup( + Long.valueOf(assetLibraryKey)); if (group == null) { - try { - DepotEntry depotEntry = depotEntryLocalService.fetchDepotEntry( - GetterUtil.getLong(assetLibraryKey)); + group = groupLocalService.fetchGroup(companyId, assetLibraryKey); - if (depotEntry == null) { - return null; - } + if (group == null) { + try { + DepotEntry depotEntry = + depotEntryLocalService.fetchDepotEntry( + GetterUtil.getLong(assetLibraryKey)); - group = depotEntry.getGroup(); - } - catch (PortalException portalException) { - if (_log.isDebugEnabled()) { - _log.debug(portalException); + if (depotEntry == null) { + return null; + } + + group = depotEntry.getGroup(); } + catch (PortalException portalException) { + if (_log.isDebugEnabled()) { + _log.debug(portalException); + } - return null; + return null; + } } } From 2845deddaa31a86f09db1f18820cabeb77561b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Tue, 18 Mar 2025 07:46:22 +0100 Subject: [PATCH 08/13] LPD-49536 Regen AssetLibrary module --- .../v1_0/test/BaseAssetLibraryResourceTestCase.java | 3 +-- .../resource/v1_0/test/BaseSiteResourceTestCase.java | 7 +++---- .../v1_0/test/BaseUserAccountResourceTestCase.java | 7 +++---- .../resource/v1_0/test/BaseUserGroupResourceTestCase.java | 7 +++---- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseAssetLibraryResourceTestCase.java b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseAssetLibraryResourceTestCase.java index 85de8a7464fe65..1a2faed459d0a6 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseAssetLibraryResourceTestCase.java +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseAssetLibraryResourceTestCase.java @@ -203,8 +203,7 @@ public void testEscapeRegexInStringFields() throws Exception { @Test public void testGetAssetLibrariesPage() throws Exception { Page page = assetLibraryResource.getAssetLibrariesPage( - RandomTestUtil.randomString(), null, null, Pagination.of(1, 10), - null); + null, null, null, Pagination.of(1, 10), null); long totalCount = page.getTotalCount(); diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseSiteResourceTestCase.java b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseSiteResourceTestCase.java index 940562941b3b56..8473ad512a3ecf 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseSiteResourceTestCase.java +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseSiteResourceTestCase.java @@ -280,8 +280,8 @@ public void testGetAssetLibraryByExternalReferenceCodeSitesPage() Page page = siteResource.getAssetLibraryByExternalReferenceCodeSitesPage( - externalReferenceCode, RandomTestUtil.randomString(), null, - null, Pagination.of(1, 10), null); + externalReferenceCode, null, null, null, Pagination.of(1, 10), + null); long totalCount = page.getTotalCount(); @@ -701,8 +701,7 @@ public void testGetAssetLibrarySitesPage() throws Exception { testGetAssetLibrarySitesPage_getIrrelevantAssetLibraryId(); Page page = siteResource.getAssetLibrarySitesPage( - assetLibraryId, RandomTestUtil.randomString(), null, null, - Pagination.of(1, 10), null); + assetLibraryId, null, null, null, Pagination.of(1, 10), null); long totalCount = page.getTotalCount(); diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserAccountResourceTestCase.java b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserAccountResourceTestCase.java index dfcb6645052137..b6efd26a7b445e 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserAccountResourceTestCase.java +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserAccountResourceTestCase.java @@ -281,8 +281,8 @@ public void testGetAssetLibraryByExternalReferenceCodeUserAccountsPage() Page page = userAccountResource. getAssetLibraryByExternalReferenceCodeUserAccountsPage( - externalReferenceCode, RandomTestUtil.randomString(), null, - null, Pagination.of(1, 10), null); + externalReferenceCode, null, null, null, + Pagination.of(1, 10), null); long totalCount = page.getTotalCount(); @@ -739,8 +739,7 @@ public void testGetAssetLibraryUserAccountsPage() throws Exception { Page page = userAccountResource.getAssetLibraryUserAccountsPage( - assetLibraryId, RandomTestUtil.randomString(), null, null, - Pagination.of(1, 10), null); + assetLibraryId, null, null, null, Pagination.of(1, 10), null); long totalCount = page.getTotalCount(); diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserGroupResourceTestCase.java b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserGroupResourceTestCase.java index 58fcfac7d6f288..5bfbd8ae2471d2 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserGroupResourceTestCase.java +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-test/src/testIntegration/java/com/liferay/headless/asset/library/resource/v1_0/test/BaseUserGroupResourceTestCase.java @@ -279,8 +279,8 @@ public void testGetAssetLibraryByExternalReferenceCodeUserGroupsPage() Page page = userGroupResource. getAssetLibraryByExternalReferenceCodeUserGroupsPage( - externalReferenceCode, RandomTestUtil.randomString(), null, - null, Pagination.of(1, 10), null); + externalReferenceCode, null, null, null, + Pagination.of(1, 10), null); long totalCount = page.getTotalCount(); @@ -728,8 +728,7 @@ public void testGetAssetLibraryUserGroupsPage() throws Exception { testGetAssetLibraryUserGroupsPage_getIrrelevantAssetLibraryId(); Page page = userGroupResource.getAssetLibraryUserGroupsPage( - assetLibraryId, RandomTestUtil.randomString(), null, null, - Pagination.of(1, 10), null); + assetLibraryId, null, null, null, Pagination.of(1, 10), null); long totalCount = page.getTotalCount(); From 7fc3e261d82eb40adf65878a671c92c89a90e2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Tue, 18 Mar 2025 11:54:08 +0100 Subject: [PATCH 09/13] LPD-49536 Main Build Rest (to reflect the template changes) --- .../v1_0/test/BaseAccountRoleResourceTestCase.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/BaseAccountRoleResourceTestCase.java b/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/BaseAccountRoleResourceTestCase.java index a7333da2632cd0..b2b6501222d772 100644 --- a/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/BaseAccountRoleResourceTestCase.java +++ b/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/BaseAccountRoleResourceTestCase.java @@ -454,8 +454,8 @@ public void testGetAccountAccountRolesByExternalReferenceCodePage() Page page = accountRoleResource. getAccountAccountRolesByExternalReferenceCodePage( - externalReferenceCode, RandomTestUtil.randomString(), null, - Pagination.of(1, 10), null); + externalReferenceCode, null, null, Pagination.of(1, 10), + null); long totalCount = page.getTotalCount(); @@ -1201,8 +1201,7 @@ public void testGetAccountAccountRolesPage() throws Exception { testGetAccountAccountRolesPage_getIrrelevantAccountId(); Page page = accountRoleResource.getAccountAccountRolesPage( - accountId, RandomTestUtil.randomString(), null, - Pagination.of(1, 10), null); + accountId, null, null, Pagination.of(1, 10), null); long totalCount = page.getTotalCount(); From 1d974ad06f1e838f0a0000577dbc47a98ef3ce07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Tue, 18 Mar 2025 13:29:00 +0100 Subject: [PATCH 10/13] LPD-49536 Implement UserGroupResourceImpl --- .../resource/v1_0/UserGroupResourceImpl.java | 239 +++++++++++++++++- 1 file changed, 237 insertions(+), 2 deletions(-) diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/UserGroupResourceImpl.java b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/UserGroupResourceImpl.java index 1dd1ae9843477f..a87eb46860a814 100644 --- a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/UserGroupResourceImpl.java +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/resource/v1_0/UserGroupResourceImpl.java @@ -5,17 +5,252 @@ package com.liferay.headless.asset.library.internal.resource.v1_0; +import com.liferay.headless.asset.library.dto.v1_0.AssetLibrary; +import com.liferay.headless.asset.library.dto.v1_0.UserGroup; import com.liferay.headless.asset.library.resource.v1_0.UserGroupResource; +import com.liferay.portal.kernel.feature.flag.FeatureFlagManagerUtil; +import com.liferay.portal.kernel.model.Group; +import com.liferay.portal.kernel.search.Field; +import com.liferay.portal.kernel.search.Sort; +import com.liferay.portal.kernel.search.filter.Filter; +import com.liferay.portal.kernel.security.permission.ActionKeys; +import com.liferay.portal.kernel.security.permission.PermissionThreadLocal; +import com.liferay.portal.kernel.security.permission.resource.ModelResourcePermission; +import com.liferay.portal.kernel.service.GroupLocalService; +import com.liferay.portal.kernel.service.UserGroupService; +import com.liferay.portal.kernel.util.GetterUtil; +import com.liferay.portal.kernel.util.HashMapBuilder; +import com.liferay.portal.kernel.util.Validator; +import com.liferay.portal.vulcan.dto.converter.DTOConverter; +import com.liferay.portal.vulcan.dto.converter.DTOConverterContext; +import com.liferay.portal.vulcan.dto.converter.DefaultDTOConverterContext; +import com.liferay.portal.vulcan.fields.NestedField; +import com.liferay.portal.vulcan.fields.NestedFieldId; +import com.liferay.portal.vulcan.pagination.Page; +import com.liferay.portal.vulcan.pagination.Pagination; +import com.liferay.portal.vulcan.util.SearchUtil; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.ServiceScope; /** * @author Roberto Díaz */ @Component( - properties = "OSGI-INF/liferay/rest/v1_0/user-group.properties", - scope = ServiceScope.PROTOTYPE, service = UserGroupResource.class + properties = "OSGI-INF/liferay/rest/v1_0_0/user-group.properties", + property = "nested.field.support=true", scope = ServiceScope.PROTOTYPE, + service = UserGroupResource.class ) public class UserGroupResourceImpl extends BaseUserGroupResourceImpl { + + @Override + public void + deleteAssetLibraryByExternalReferenceCodeAssetLibraryExternalReferenceCodeUserGroupByExternalReferenceCodeUserGroupExternalReferenceCode( + String assetLibraryExternalReferenceCode, + String userGroupExternalReferenceCode) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + Group group = _getGroupByExternalReferenceCode( + assetLibraryExternalReferenceCode); + + if (group == null) { + return; + } + + _userGroupService.unsetGroupUserGroups( + group.getGroupId(), + new long[] { + _getUserGroupIdByExternalReferenceCode( + userGroupExternalReferenceCode) + }); + } + + @Override + public void deleteAssetLibraryUserGroup( + Long assetLibraryId, Long userGroupId) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + _userGroupService.unsetGroupUserGroups( + assetLibraryId, new long[] {userGroupId}); + } + + @Override + public Page getAssetLibraryByExternalReferenceCodeUserGroupsPage( + String externalReferenceCode, String keywords, String search, + Filter filter, Pagination pagination, Sort[] sorts) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + Group group = _getGroupByExternalReferenceCode(externalReferenceCode); + + if (group == null) { + return null; + } + + return getAssetLibraryUserGroupsPage( + group.getGroupId(), keywords, search, filter, pagination, sorts); + } + + @NestedField(parentClass = AssetLibrary.class, value = "userGroups") + @Override + public Page getAssetLibraryUserGroupsPage( + @NestedFieldId("id") Long assetLibraryId, String keywords, + String search, Filter filter, Pagination pagination, Sort[] sorts) + throws Exception { + + return SearchUtil.search( + HashMapBuilder.put( + "get", + addAction( + ActionKeys.VIEW, 0L, "getAssetLibraryUserGroupsPage", + _userGroupModelResourcePermission) + ).build(), + booleanQuery -> { + }, + filter, com.liferay.portal.kernel.model.UserGroup.class.getName(), + search, pagination, + queryConfig -> { + }, + searchContext -> { + searchContext.setCompanyId(contextCompany.getCompanyId()); + + if (Validator.isNotNull(search)) { + searchContext.setKeywords(search); + } + }, + sorts, + document -> _toUserGroup( + _userGroupService.getUserGroup( + GetterUtil.getLong(document.get(Field.ENTRY_CLASS_PK))))); + } + + @Override + public void + postAssetLibraryByExternalReferenceCodeAssetLibraryExternalReferenceCodeUserGroupByExternalReferenceCodeUserGroupExternalReferenceCode( + String assetLibraryExternalReferenceCode, + String userGroupExternalReferenceCode) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + Group group = _getGroupByExternalReferenceCode( + assetLibraryExternalReferenceCode); + + if (group == null) { + return; + } + + _userGroupService.addGroupUserGroups( + group.getGroupId(), + new long[] { + _getUserGroupIdByExternalReferenceCode( + userGroupExternalReferenceCode) + }); + } + + @Override + public void postAssetLibraryUserGroup(Long assetLibraryId, Long userGroupId) + throws Exception { + + if (!FeatureFlagManagerUtil.isEnabled("LPD-17564")) { + throw new UnsupportedOperationException(); + } + + _userGroupService.addGroupUserGroups( + assetLibraryId, new long[] {userGroupId}); + } + + private DTOConverterContext _getDTOConverterContext(long userGroupId) { + return new DefaultDTOConverterContext( + contextAcceptLanguage.isAcceptAllLanguages(), + HashMapBuilder.put( + "delete-asset-library-user-group", + addAction( + ActionKeys.ASSIGN_MEMBERS, userGroupId, + "deleteAssetLibraryUserGroup", + _userGroupModelResourcePermission) + ).put( + "post-asset-library-user-group", + addAction( + ActionKeys.ASSIGN_MEMBERS, userGroupId, + "postAssetLibraryUserGroup", + _userGroupModelResourcePermission) + ).build(), + null, contextHttpServletRequest, userGroupId, + contextAcceptLanguage.getPreferredLocale(), contextUriInfo, + contextUser); + } + + private Group _getGroupByExternalReferenceCode(String externalReferenceCode) + throws Exception { + + Group group = _groupLocalService.fetchGroupByExternalReferenceCode( + externalReferenceCode, contextCompany.getCompanyId()); + + if (_groupModelResourcePermission.contains( + PermissionThreadLocal.getPermissionChecker(), + group.getGroupId(), ActionKeys.VIEW)) { + + return group; + } + + return null; + } + + private long _getUserGroupIdByExternalReferenceCode( + String externalReferenceCode) + throws Exception { + + com.liferay.portal.kernel.model.UserGroup userGroup = + _userGroupService.getUserGroupByExternalReferenceCode( + externalReferenceCode, contextCompany.getCompanyId()); + + return userGroup.getUserGroupId(); + } + + private UserGroup _toUserGroup( + com.liferay.portal.kernel.model.UserGroup userGroup) + throws Exception { + + return _userGroupDTOConverter.toDTO( + _getDTOConverterContext(userGroup.getUserGroupId()), userGroup); + } + + @Reference + private GroupLocalService _groupLocalService; + + @Reference( + target = "(model.class.name=com.liferay.portal.kernel.model.Group)" + ) + private ModelResourcePermission _groupModelResourcePermission; + + @Reference( + target = "(component.name=com.liferay.headless.asset.library.internal.dto.v1_0.converter.UserGroupDTOConverter)" + ) + private DTOConverter + _userGroupDTOConverter; + + @Reference( + target = "(model.class.name=com.liferay.portal.kernel.model.UserGroup)" + ) + private ModelResourcePermission + _userGroupModelResourcePermission; + + @Reference + private UserGroupService _userGroupService; + } \ No newline at end of file From d1acf11b1873986aaeeffa61da58e236d05c719a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Tue, 18 Mar 2025 13:29:26 +0100 Subject: [PATCH 11/13] LPD-49536 Create UserGroupDTOConverter --- .../v1_0/converter/UserGroupDTOConverter.java | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/UserGroupDTOConverter.java diff --git a/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/UserGroupDTOConverter.java b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/UserGroupDTOConverter.java new file mode 100644 index 00000000000000..c6b208230ebc87 --- /dev/null +++ b/modules/apps/headless/headless-asset-library/headless-asset-library-impl/src/main/java/com/liferay/headless/asset/library/internal/dto/v1_0/converter/UserGroupDTOConverter.java @@ -0,0 +1,105 @@ +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ + +package com.liferay.headless.asset.library.internal.dto.v1_0.converter; + +import com.liferay.headless.asset.library.dto.v1_0.Role; +import com.liferay.headless.asset.library.dto.v1_0.UserGroup; +import com.liferay.petra.function.transform.TransformUtil; +import com.liferay.portal.kernel.model.Group; +import com.liferay.portal.kernel.service.RoleService; +import com.liferay.portal.vulcan.dto.converter.DTOConverter; +import com.liferay.portal.vulcan.dto.converter.DTOConverterContext; +import com.liferay.portal.vulcan.fields.NestedFieldsSupplier; +import com.liferay.portal.vulcan.util.LocalizedMapUtil; + +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * @author Roberto Díaz + */ +@Component( + property = "dto.class.name=com.liferay.portal.kernel.model.UserGroup", + service = DTOConverter.class +) +public class UserGroupDTOConverter + implements DTOConverter + { + + @Override + public String getContentType() { + return UserGroup.class.getSimpleName(); + } + + @Override + public UserGroup toDTO( + DTOConverterContext dtoConverterContext, + com.liferay.portal.kernel.model.UserGroup userGroup) + throws Exception { + + return new UserGroup() { + { + setExternalReferenceCode(userGroup::getExternalReferenceCode); + setId(userGroup::getUserGroupId); + setName(userGroup::getName); + setName_i18n( + () -> { + if (dtoConverterContext == null) { + return null; + } + + Group group = userGroup.getGroup(); + + return LocalizedMapUtil.getI18nMap( + dtoConverterContext.isAcceptAllLanguages(), + group.getNameMap()); + }); + setRoles( + () -> NestedFieldsSupplier.supply( + "roles", + fieldName -> TransformUtil.transformToArray( + _roleService.getGroupRoles(userGroup.getGroupId()), + role -> _toRole(dtoConverterContext, role), + Role.class))); + } + }; + } + + private Role _toRole( + DTOConverterContext dtoConverterContext, + com.liferay.portal.kernel.model.Role role) { + + return new Role() { + { + setExternalReferenceCode(role::getExternalReferenceCode); + setId(role::getRoleId); + setName( + () -> { + if (dtoConverterContext == null) { + return role.getName(); + } + + return role.getTitle(dtoConverterContext.getLocale()); + }); + setName_i18n( + () -> { + if (dtoConverterContext == null) { + return null; + } + + return LocalizedMapUtil.getI18nMap( + dtoConverterContext.isAcceptAllLanguages(), + role.getTitleMap()); + }); + setRoleType(role::getType); + } + }; + } + + @Reference + private RoleService _roleService; + +} \ No newline at end of file From c573376f6dd4d2ab68f5e0edc2545128403c8867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Mon, 3 Mar 2025 12:51:55 +0100 Subject: [PATCH 12/13] LPD-49536 Index the UserGroups groups --- .../user-groups-admin-impl/build.gradle | 1 + .../UserGroupModelDocumentContributor.java | 11 +++++++++++ .../service/impl/GroupLocalServiceImpl.java | 18 ++++++++++++++++++ .../impl/UserGroupLocalServiceImpl.java | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/modules/apps/user-groups-admin/user-groups-admin-impl/build.gradle b/modules/apps/user-groups-admin/user-groups-admin-impl/build.gradle index 8b595086b15897..6ebedf9468b710 100644 --- a/modules/apps/user-groups-admin/user-groups-admin-impl/build.gradle +++ b/modules/apps/user-groups-admin/user-groups-admin-impl/build.gradle @@ -11,4 +11,5 @@ dependencies { compileOnly project(":apps:portlet-display-template:portlet-display-template-api") compileOnly project(":apps:user-groups-admin:user-groups-admin-api") compileOnly project(":apps:xstream:xstream-configurator-api") + compileOnly project(":core:petra:petra-function") } \ No newline at end of file diff --git a/modules/apps/user-groups-admin/user-groups-admin-impl/src/main/java/com/liferay/user/groups/admin/internal/search/spi/model/index/contributor/UserGroupModelDocumentContributor.java b/modules/apps/user-groups-admin/user-groups-admin-impl/src/main/java/com/liferay/user/groups/admin/internal/search/spi/model/index/contributor/UserGroupModelDocumentContributor.java index 189684f990b825..689344ce85204a 100644 --- a/modules/apps/user-groups-admin/user-groups-admin-impl/src/main/java/com/liferay/user/groups/admin/internal/search/spi/model/index/contributor/UserGroupModelDocumentContributor.java +++ b/modules/apps/user-groups-admin/user-groups-admin-impl/src/main/java/com/liferay/user/groups/admin/internal/search/spi/model/index/contributor/UserGroupModelDocumentContributor.java @@ -5,9 +5,11 @@ package com.liferay.user.groups.admin.internal.search.spi.model.index.contributor; +import com.liferay.petra.function.transform.TransformUtil; import com.liferay.portal.kernel.model.UserGroup; import com.liferay.portal.kernel.search.Document; import com.liferay.portal.kernel.search.Field; +import com.liferay.portal.kernel.service.GroupLocalService; import com.liferay.portal.kernel.service.UserGroupLocalService; import com.liferay.portal.search.spi.model.index.contributor.ModelDocumentContributor; @@ -28,6 +30,12 @@ public class UserGroupModelDocumentContributor public void contribute(Document document, UserGroup userGroup) { document.addKeyword(Field.COMPANY_ID, userGroup.getCompanyId()); document.addText(Field.DESCRIPTION, userGroup.getDescription()); + document.addKeyword( + "groupIds", + TransformUtil.transformToLongArray( + _groupLocalService.getUserGroupGroups( + userGroup.getUserGroupId()), + group -> group.getGroupId())); document.addText(Field.NAME, userGroup.getName()); document.addKeyword(Field.USER_GROUP_ID, userGroup.getUserGroupId()); document.addKeyword( @@ -36,6 +44,9 @@ public void contribute(Document document, UserGroup userGroup) { userGroup.getUserGroupId())); } + @Reference + private GroupLocalService _groupLocalService; + @Reference private UserGroupLocalService _userGroupLocalService; diff --git a/portal-impl/src/com/liferay/portal/service/impl/GroupLocalServiceImpl.java b/portal-impl/src/com/liferay/portal/service/impl/GroupLocalServiceImpl.java index bf7f3a49584019..e2e2e236365fd4 100644 --- a/portal-impl/src/com/liferay/portal/service/impl/GroupLocalServiceImpl.java +++ b/portal-impl/src/com/liferay/portal/service/impl/GroupLocalServiceImpl.java @@ -90,6 +90,8 @@ import com.liferay.portal.kernel.module.util.SystemBundleUtil; import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil; import com.liferay.portal.kernel.scheduler.StorageType; +import com.liferay.portal.kernel.search.Indexer; +import com.liferay.portal.kernel.search.IndexerRegistryUtil; import com.liferay.portal.kernel.search.reindexer.ReindexerBridge; import com.liferay.portal.kernel.security.auth.HttpPrincipal; import com.liferay.portal.kernel.security.auth.PrincipalException; @@ -1229,6 +1231,14 @@ public Group deleteGroup(Group group) throws PortalException { }); } + List groupUserGroups = + _userGroupLocalService.getGroupUserGroups( + group.getGroupId()); + + for (UserGroup groupUserGroup : groupUserGroups) { + reindexUserGroup(groupUserGroup.getUserGroupId()); + } + groupPersistence.remove(group); } @@ -4822,6 +4832,13 @@ protected void reindex(long companyId, long[] userIds) reindexerBridge.reindex(companyId, User.class.getName(), userIds); } + protected void reindexUserGroup(long userGroupId) throws PortalException { + Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer( + UserGroup.class); + + indexer.reindex(_userGroupLocalService.getUserGroup(userGroupId)); + } + protected void reindexUsersInOrganization(long organizationId) throws PortalException { @@ -4857,6 +4874,7 @@ protected void reindexUsersInUserGroup(long userGroupId) TransactionCommitCallbackUtil.registerCallback( () -> { reindex(companyId, userIds); + reindexUserGroup(userGroupId); return null; }); diff --git a/portal-impl/src/com/liferay/portal/service/impl/UserGroupLocalServiceImpl.java b/portal-impl/src/com/liferay/portal/service/impl/UserGroupLocalServiceImpl.java index 1d7b3f4f4a0545..d4e08d94ce11a5 100644 --- a/portal-impl/src/com/liferay/portal/service/impl/UserGroupLocalServiceImpl.java +++ b/portal-impl/src/com/liferay/portal/service/impl/UserGroupLocalServiceImpl.java @@ -112,6 +112,7 @@ public boolean addGroupUserGroup(long groupId, long userGroupId) { try { reindexUsers(userGroupId); + reindexUserGroup(getUserGroup(userGroupId)); } catch (PortalException portalException) { throw new SystemException(portalException); @@ -136,6 +137,7 @@ public boolean addGroupUserGroup(long groupId, UserGroup userGroup) { try { reindexUsers(userGroup); + reindexUserGroup(userGroup); } catch (PortalException portalException) { throw new SystemException(portalException); @@ -163,6 +165,10 @@ public boolean addGroupUserGroups( try { reindexUsers(userGroups); + + for (UserGroup userGroup : userGroups) { + reindexUserGroup(userGroup); + } } catch (PortalException portalException) { throw new SystemException(portalException); @@ -188,6 +194,10 @@ public boolean addGroupUserGroups(long groupId, long[] userGroupIds) { try { reindexUsers(userGroupIds); + + for (long userGroupId : userGroupIds) { + reindexUserGroup(getUserGroup(userGroupId)); + } } catch (PortalException portalException) { throw new SystemException(portalException); @@ -968,6 +978,10 @@ public void setUserUserGroups(long userId, long[] userGroupIds) User.class); indexer.reindex(_userLocalService.fetchUser(userId)); + + for (long userGroupId : userGroupIds) { + reindexUserGroup(getUserGroup(userGroupId)); + } } /** @@ -991,6 +1005,10 @@ public void unsetGroupUserGroups(long groupId, long[] userGroupIds) { try { reindexUsers(userGroupIds); + + for (long userGroupId : userGroupIds) { + reindexUserGroup(getUserGroup(userGroupId)); + } } catch (PortalException portalException) { throw new SystemException(portalException); From 0020ca40527e5e3ed9dcb0ca0c054e5ee68650b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20D=C3=ADaz?= Date: Mon, 3 Mar 2025 13:22:06 +0100 Subject: [PATCH 13/13] LPD-49536 Implement test methods --- .../v1_0/test/UserGroupResourceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/UserGroupResourceTest.java b/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/UserGroupResourceTest.java index 294d7e5c330dd5..32ba0a85ede2a6 100644 --- a/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/UserGroupResourceTest.java +++ b/modules/apps/headless/headless-admin-user/headless-admin-user-test/src/testIntegration/java/com/liferay/headless/admin/user/resource/v1_0/test/UserGroupResourceTest.java @@ -6,6 +6,8 @@ package com.liferay.headless.admin.user.resource.v1_0.test; import com.liferay.arquillian.extension.junit.bridge.junit.Arquillian; +import com.liferay.depot.model.DepotEntry; +import com.liferay.depot.service.DepotEntryLocalService; import com.liferay.headless.admin.user.client.dto.v1_0.Creator; import com.liferay.headless.admin.user.client.dto.v1_0.UserGroup; import com.liferay.headless.admin.user.client.pagination.Page; @@ -219,6 +221,22 @@ protected UserGroup testDeleteUserGroupUsers_addUserGroup() return _postUserGroup(); } + @Override + protected UserGroup testGetAssetLibraryUserGroupsPage_addUserGroup( + Long assetLibraryId, UserGroup userGroup) + throws Exception { + + userGroup = _postUserGroup(userGroup); + + DepotEntry depotEntry = _depotEntryLocalService.getDepotEntry( + assetLibraryId); + + _userGroupLocalService.addGroupUserGroups( + depotEntry.getGroupId(), new long[] {userGroup.getId()}); + + return userGroup; + } + @Override protected UserGroup testGetUserGroup_addUserGroup() throws Exception { return _postUserGroup(); @@ -442,6 +460,9 @@ private void _testGetUserGroupWithNestedFields() throws Exception { userAccountBrief.getId() == user3.getUserId())); } + @Inject + private DepotEntryLocalService _depotEntryLocalService; + @Inject private ResourcePermissionLocalService _resourcePermissionLocalService;