From fb30b31514df3e1f06706681577898c2c8f53d8b Mon Sep 17 00:00:00 2001 From: rymsha Date: Mon, 13 Oct 2025 16:04:05 +0200 Subject: [PATCH 1/8] wip --- .../enonic/xp/audit/LogAuditLogParams.java | 14 +- .../xp/content/ActiveContentVersionEntry.java | 33 -- .../ApplyContentPermissionsParams.java | 12 +- .../content/ApplyContentPermissionsScope.java | 6 + .../com/enonic/xp/content/CompareStatus.java | 24 +- .../xp/content/ContentAccessException.java | 28 +- .../enonic/xp/content/ContentConstants.java | 4 +- .../com/enonic/xp/content/ContentService.java | 2 - .../com/enonic/xp/content/ContentVersion.java | 226 ++++++++------ .../content/ContentVersionDateComparator.java | 41 --- .../xp/content/ContentVersionPublishInfo.java | 138 --------- .../enonic/xp/content/ContentVersions.java | 11 +- .../GetActiveContentVersionsParams.java | 64 ---- .../GetActiveContentVersionsResult.java | 57 ---- .../xp/content/PublishContentResult.java | 62 +++- .../enonic/xp/content/PushContentParams.java | 31 +- .../java/com/enonic/xp/data/PropertySet.java | 2 + .../java/com/enonic/xp/data/PropertyTree.java | 6 +- .../xp/node/ApplyNodePermissionsParams.java | 16 + .../java/com/enonic/xp/node/Attributes.java | 103 +++++++ .../com/enonic/xp/node/CommitNodeParams.java | 57 ++++ .../com/enonic/xp/node/CreateNodeParams.java | 16 + .../com/enonic/xp/node/DeleteNodeResult.java | 25 +- .../enonic/xp/node/DuplicateNodeParams.java | 16 + .../enonic/xp}/node/DuplicateNodeResult.java | 13 +- .../com/enonic/xp/node/ImportNodeParams.java | 16 + .../com/enonic/xp/node/LoadNodeParams.java | 16 + .../com/enonic/xp/node/MoveNodeParams.java | 16 + .../com/enonic/xp/node/NodeCompareStatus.java | 9 + .../com/enonic/xp/node/NodeComparison.java | 6 +- .../com/enonic/xp/node/NodeComparisons.java | 11 - .../java/com/enonic/xp/node/NodeService.java | 11 +- .../enonic/xp/node/NodeVersionMetadata.java | 83 ++--- .../com/enonic/xp/node/PatchNodeParams.java | 19 +- .../com/enonic/xp/node/PushNodeParams.java | 93 ++++++ .../com/enonic/xp/node/PushNodeResult.java | 4 +- .../enonic/xp/node/RoutableNodeVersionId.java | 1 + .../xp/node/RoutableNodeVersionIds.java | 3 +- .../com/enonic/xp/node/SortNodeParams.java | 26 +- .../xp/node/SyncWorkResolverParams.java | 8 +- .../com/enonic/xp/node/UpdateNodeParams.java | 17 +- .../java/com/enonic/xp/util/GenericValue.java | 286 ++++++++++++++++++ .../enonic/xp/audit/AuditLogParamsTest.java | 3 +- .../ApplyContentPermissionsParamsTest.java | 5 +- .../ContentVersionDateComparatorTest.java | 53 ---- .../enonic/xp/content/ContentVersionTest.java | 48 +-- .../xp/content/ContentVersionsTest.java | 8 +- .../GetActiveContentVersionsParamsTest.java | 32 -- .../GetActiveContentVersionsResultTest.java | 98 ------ .../com/enonic/xp/data/PropertyTreeTest.java | 4 +- .../impl/app/ApplicationServiceImplTest.java | 5 +- .../audit/serializer/AuditLogSerializer.java | 10 +- .../impl/audit/AuditLogServiceImplTest.java | 10 +- .../impl/content/AbstractContentCommand.java | 9 +- ...tractCreatingOrUpdatingContentCommand.java | 8 - .../ApplyContentPermissionsCommand.java | 30 +- .../impl/content/ArchiveContentCommand.java | 29 +- .../impl/content/CompareContentsCommand.java | 5 +- .../impl/content/CompareResultTranslator.java | 4 +- .../impl/content/ContentAttributesHelper.java | 108 +++++++ .../content/ContentAuditLogSupportImpl.java | 13 +- .../core/impl/content/ContentNodeHelper.java | 7 + .../core/impl/content/ContentServiceImpl.java | 88 ++---- .../impl/content/ContentVersionFactory.java | 141 --------- .../impl/content/CreateContentCommand.java | 10 +- .../impl/content/CreateNodeParamsFactory.java | 7 +- .../impl/content/DeleteContentCommand.java | 7 +- .../impl/content/DuplicateContentCommand.java | 22 +- .../content/FindContentVersionsCommand.java | 112 ++++++- .../GetActiveContentVersionsCommand.java | 85 ------ .../impl/content/ImportContentCommand.java | 1 + .../core/impl/content/MoveContentCommand.java | 9 +- .../impl/content/PatchContentCommand.java | 4 +- .../impl/content/PatchNodeParamsFactory.java | 13 + .../impl/content/PublishContentCommand.java | 243 +++++++-------- .../impl/content/RenameContentCommand.java | 5 +- .../ResolveContentsToBePublishedCommand.java | 4 +- .../ResolveRequiredDependenciesCommand.java | 38 +-- .../impl/content/RestoreContentCommand.java | 27 +- .../core/impl/content/SortContentCommand.java | 99 ++++++ .../impl/content/UnpublishContentCommand.java | 89 +++--- .../impl/content/UpdateContentCommand.java | 6 +- .../serializer/ContentDataSerializer.java | 12 +- .../serializer/PublishInfoSerializer.java | 7 +- .../serializer/ContentDataSerializerTest.java | 2 +- .../issue/DeleteIssueCommentCommandTest.java | 5 +- .../core/impl/project/ProjectServiceImpl.java | 6 +- .../impl/project/init/ContentInitializer.java | 4 +- .../impl/project/init/IssueInitializer.java | 4 +- .../enonic/xp/repo/impl/NodeBranchEntry.java | 11 + .../com/enonic/xp/repo/impl/ReturnField.java | 18 -- .../com/enonic/xp/repo/impl/ReturnValues.java | 15 +- .../storage/NodeBranchVersionFactory.java | 31 +- .../repo/impl/branch/storage/NodeFactory.java | 25 +- .../search/NodeCommitQueryResultFactory.java | 77 +---- .../storage/NodeCommitEntryFactory.java | 16 +- .../enonic/xp/repo/impl/dump/RepoDumper.java | 210 ++++++------- .../xp/repo/impl/dump/VersionMetaFactory.java | 21 +- .../repo/impl/dump/model/BranchDumpEntry.java | 8 +- .../xp/repo/impl/dump/model/VersionMeta.java | 100 +----- .../dump/reader/AbstractEntryProcessor.java | 6 +- .../dump/reader/BranchEntryProcessor.java | 22 +- .../dump/reader/VersionEntryProcessor.java | 14 +- .../serializer/json/BranchDumpEntryJson.java | 6 +- .../serializer/json/VersionDumpEntryJson.java | 17 +- .../FlattenedPageDataUpgrader.java | 2 +- .../pre6/Pre6BranchDumpEntryJson.java | 14 - .../pre6/Pre6VersionDumpEntryJson.java | 14 +- .../document/indexitem/IndexItem.java | 3 +- .../impl/index/IndexFieldNameNormalizer.java | 19 +- .../node/ApplyNodePermissionsCommand.java | 3 +- .../repo/impl/node/CompareStatusResolver.java | 22 +- .../xp/repo/impl/node/CreateNodeCommand.java | 5 +- .../repo/impl/node/DuplicateNodeCommand.java | 3 + .../node/FindNodesByQueryResultFactory.java | 11 +- ...FindNodesWithVersionDifferenceCommand.java | 28 +- .../xp/repo/impl/node/ImportNodeCommand.java | 19 +- .../xp/repo/impl/node/LoadNodeCommand.java | 6 +- .../xp/repo/impl/node/MoveNodeCommand.java | 117 ++----- .../xp/repo/impl/node/NodeServiceImpl.java | 98 +++--- .../impl}/node/NodeVersionDiffResult.java | 7 +- .../node/NodeVersionDiffResultFactory.java | 3 +- .../xp/repo/impl/node/PatchNodeCommand.java | 8 +- .../xp/repo/impl/node/PushNodesCommand.java | 124 ++++---- .../node/ResolveInsertOrderValueCommand.java | 2 +- .../impl/node/ResolveSyncWorkCommand.java | 270 ++++++----------- .../impl/node/SetRootPermissionsCommand.java | 83 ----- .../xp/repo/impl/node/SortNodeCommand.java | 4 +- .../RepositoryEntryServiceImpl.java | 24 +- .../impl/search/NodeSearchServiceImpl.java | 2 +- .../xp/repo/impl/search/result/SearchHit.java | 26 -- .../repo/impl/storage/NodeStorageService.java | 8 +- .../impl/storage/NodeStorageServiceImpl.java | 117 ++++--- .../xp/repo/impl/storage/StoreNodeParams.java | 52 +--- .../impl/storage/StoreNodeVersionParams.java | 17 ++ .../version/GenericValueDeserializer.java | 85 ++++++ .../repo/impl/version/NodeVersionFactory.java | 44 +-- .../repo/impl/version/VersionIndexPath.java | 1 + .../repo/impl/version/VersionServiceImpl.java | 8 +- .../version/VersionStorageDocFactory.java | 73 +++++ .../search/NodeVersionQueryResultFactory.java | 78 +---- .../storage/VersionStorageDocFactory.java | 40 --- .../index/IndexFieldNameNormalizerTest.java | 15 +- .../RepositoryServiceActivatorTest.java | 4 +- .../FormDefaultValuesProcessorImplTest.java | 2 +- .../com/enonic/xp/core/AbstractNodeTest.java | 24 +- .../content/AbstractContentServiceTest.java | 4 +- ...ntentServiceImplTest_applyPermissions.java | 4 +- .../ContentServiceImplTest_archive.java | 3 +- ...ContentServiceImplTest_getNearestSite.java | 6 +- .../ContentServiceImplTest_publish.java | 10 +- ...ImplTest_publish_update_publishedTime.java | 3 +- .../ContentServiceImplTest_versions.java | 129 +------- .../xp/core/dump/DumpServiceImplTest.java | 16 +- .../xp/core/dump/RepoDumperLoadTest.java | 3 +- .../xp/core/index/IndexServiceImplTest.java | 5 +- .../xp/core/node/CompareNodeCommandTest.java | 23 +- .../xp/core/node/CompareNodesCommandTest.java | 12 +- .../core/node/DuplicateNodeCommandTest.java | 6 +- .../FindNodesDependenciesCommandTest.java | 4 +- ...NodesWithVersionDifferenceCommandTest.java | 7 +- .../xp/core/node/ImportNodeCommandTest.java | 4 +- .../xp/core/node/MoveNodeCommandTest.java | 89 +++--- .../xp/core/node/NodeServiceImplTest.java | 19 +- .../node/PushNodesCommandPerformanceTest.java | 4 +- .../xp/core/node/PushNodesCommandTest.java | 4 +- .../xp/core/node/RenameNodeCommandTest.java | 93 ++---- .../core/node/ResolveSyncWorkCommandTest.java | 53 ++-- .../node/SetRootPermissionsCommandTest.java | 73 ----- .../xp/lib/audit/BaseAuditLogHandlerTest.java | 4 +- .../xp/lib/auth/ModifyProfileHandler.java | 2 +- .../lib/content/ApplyPermissionsHandler.java | 6 +- .../xp/lib/content/PublishContentHandler.java | 7 +- .../content/ApplyPermissionsHandlerTest.java | 4 +- .../content/PublishContentHandlerTest.java | 17 +- .../xp/lib/node/DuplicateNodeHandler.java | 2 +- .../enonic/xp/lib/node/PushNodeHandler.java | 4 +- .../xp/lib/node/DeleteNodeHandlerTest.java | 7 +- .../xp/lib/node/DiffBranchesHandlerTest.java | 10 +- .../xp/lib/node/DuplicateNodeHandlerTest.java | 3 +- .../xp/lib/node/PushNodeHandlerTest.java | 20 +- .../ResolveSyncWorkResultMapperTest.java | 10 +- .../ApplyProjectReadAccessCommand.java | 10 +- 183 files changed, 2677 insertions(+), 3256 deletions(-) delete mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/content/ActiveContentVersionEntry.java create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsScope.java delete mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionDateComparator.java delete mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionPublishInfo.java delete mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsParams.java delete mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsResult.java create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/node/CommitNodeParams.java rename modules/core/{core-repo/src/main/java/com/enonic/xp/repo/impl => core-api/src/main/java/com/enonic/xp}/node/DuplicateNodeResult.java (77%) create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/node/NodeCompareStatus.java create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeParams.java create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/util/GenericValue.java delete mode 100644 modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionDateComparatorTest.java delete mode 100644 modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsParamsTest.java delete mode 100644 modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsResultTest.java create mode 100644 modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java delete mode 100644 modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentVersionFactory.java delete mode 100644 modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetActiveContentVersionsCommand.java create mode 100644 modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/SortContentCommand.java delete mode 100644 modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnField.java rename modules/core/{core-api/src/main/java/com/enonic/xp => core-repo/src/main/java/com/enonic/xp/repo/impl}/node/NodeVersionDiffResult.java (91%) delete mode 100644 modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SetRootPermissionsCommand.java create mode 100644 modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/GenericValueDeserializer.java create mode 100644 modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionStorageDocFactory.java delete mode 100644 modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/storage/VersionStorageDocFactory.java delete mode 100644 modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/SetRootPermissionsCommandTest.java diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/audit/LogAuditLogParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/audit/LogAuditLogParams.java index b96e6122803..4be69f69cbf 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/audit/LogAuditLogParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/audit/LogAuditLogParams.java @@ -3,11 +3,8 @@ import java.time.Instant; import java.util.Objects; -import com.enonic.xp.context.Context; -import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.security.PrincipalKey; -import com.enonic.xp.security.User; public final class LogAuditLogParams { @@ -25,21 +22,14 @@ public final class LogAuditLogParams private LogAuditLogParams( final Builder builder ) { - type = Objects.requireNonNull( builder.type, "AuditLogParams type cannot be null" ); + type = Objects.requireNonNull( builder.type, "LogAuditLogParams type cannot be null" ); time = Objects.requireNonNullElseGet( builder.time, Instant::now ); source = Objects.requireNonNullElse( builder.source, "" ); - user = Objects.requireNonNullElseGet( builder.user, this::getUserKey ); + user = builder.user; objectUris = Objects.requireNonNullElse( builder.objectUris, AuditLogUris.empty() ); data = Objects.requireNonNullElse( builder.data, new PropertyTree() ); } - private PrincipalKey getUserKey() - { - final Context context = ContextAccessor.current(); - final User user = context.getAuthInfo().getUser() != null ? context.getAuthInfo().getUser() : User.ANONYMOUS; - return user.getKey(); - } - public String getType() { return type; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ActiveContentVersionEntry.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ActiveContentVersionEntry.java deleted file mode 100644 index 77f9153b1e9..00000000000 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ActiveContentVersionEntry.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.enonic.xp.content; - -import com.enonic.xp.annotation.PublicApi; -import com.enonic.xp.branch.Branch; - -@PublicApi -public final class ActiveContentVersionEntry -{ - private final Branch branch; - - private final ContentVersion contentVersion; - - public static ActiveContentVersionEntry from( final Branch branch, final ContentVersion contentVersion ) - { - return new ActiveContentVersionEntry( branch, contentVersion ); - } - - private ActiveContentVersionEntry( final Branch branch, final ContentVersion contentVersion ) - { - this.branch = branch; - this.contentVersion = contentVersion; - } - - public ContentVersion getContentVersion() - { - return contentVersion; - } - - public Branch getBranch() - { - return branch; - } -} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsParams.java index 71cd00d2da2..bb333ce7adc 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsParams.java @@ -3,7 +3,6 @@ import com.google.common.base.Preconditions; import com.enonic.xp.annotation.PublicApi; -import com.enonic.xp.node.ApplyPermissionsScope; import com.enonic.xp.security.acl.AccessControlList; import static java.util.Objects.requireNonNull; @@ -20,14 +19,14 @@ public final class ApplyContentPermissionsParams private final AccessControlList removePermissions; - private final ApplyPermissionsScope applyPermissionsScope; + private final ApplyContentPermissionsScope applyPermissionsScope; private final ApplyPermissionsListener listener; private ApplyContentPermissionsParams( Builder builder ) { contentId = requireNonNull( builder.contentId ); - applyPermissionsScope = requireNonNullElse( builder.applyPermissionsScope, ApplyPermissionsScope.SINGLE ); + applyPermissionsScope = requireNonNullElse( builder.applyPermissionsScope, ApplyContentPermissionsScope.SINGLE ); permissions = builder.permissions.build(); addPermissions = builder.addPermissions.build(); removePermissions = builder.removePermissions.build(); @@ -47,7 +46,7 @@ public ContentId getContentId() return contentId; } - public ApplyPermissionsScope getScope() + public ApplyContentPermissionsScope getScope() { return applyPermissionsScope; } @@ -82,7 +81,7 @@ public static final class Builder private final AccessControlList.Builder removePermissions = AccessControlList.create(); - private ApplyPermissionsScope applyPermissionsScope; + private ApplyContentPermissionsScope applyPermissionsScope; private ApplyPermissionsListener listener; @@ -96,7 +95,7 @@ public Builder contentId( final ContentId contentId ) return this; } - public Builder applyPermissionsScope( final ApplyPermissionsScope applyPermissionsScope ) + public Builder applyPermissionsScope( final ApplyContentPermissionsScope applyPermissionsScope ) { this.applyPermissionsScope = applyPermissionsScope; return this; @@ -140,5 +139,4 @@ public ApplyContentPermissionsParams build() return new ApplyContentPermissionsParams( this ); } } - } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsScope.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsScope.java new file mode 100644 index 00000000000..fe11eadc059 --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ApplyContentPermissionsScope.java @@ -0,0 +1,6 @@ +package com.enonic.xp.content; + +public enum ApplyContentPermissionsScope +{ + SINGLE, TREE, SUBTREE +} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/CompareStatus.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/CompareStatus.java index 3626bab73d0..38f2ffcf2d7 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/CompareStatus.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/CompareStatus.java @@ -5,27 +5,5 @@ @PublicApi public enum CompareStatus { - NEW( false, "Offline" ), NEW_TARGET( false, "New in prod" ), NEWER( false, "Modified" ), OLDER( false, "Out-of-date" ), EQUAL( false, - "Online" ), MOVED( - false, "Moved" ), CONFLICT_PATH_EXISTS( true, "Conflict" ), CONFLICT_VERSION_BRANCH_DIVERGS( true, "Conflict version" ); - - private final boolean conflict; - - private final String status; - - CompareStatus( final boolean conflict, final String formattedStatus ) - { - this.conflict = conflict; - this.status = formattedStatus; - } - - public boolean isConflict() - { - return this.conflict; - } - - public String getFormattedStatus() - { - return this.status; - } + NEW, NEW_TARGET, NEWER, OLDER, EQUAL, MOVED } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAccessException.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAccessException.java index 1d6b5c8b5be..b9acea0d851 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAccessException.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAccessException.java @@ -4,8 +4,6 @@ import com.enonic.xp.annotation.PublicApi; import com.enonic.xp.exception.BaseException; -import com.enonic.xp.node.NodeAccessException; -import com.enonic.xp.node.NodePath; import com.enonic.xp.security.User; import com.enonic.xp.security.acl.Permission; @@ -19,18 +17,7 @@ public final class ContentAccessException private final Permission permission; - public ContentAccessException( final NodeAccessException nodeAccessException ) - { - this( nodeAccessException, nodeAccessException.getUser(), translateNodePathToContentPath( nodeAccessException.getNodePath() ), - nodeAccessException.getPermission() ); - } - - public ContentAccessException( final User user, final ContentPath contentPath, final Permission permission ) - { - this( null, user, contentPath, permission ); - } - - private ContentAccessException( final Throwable cause, final User user, final ContentPath contentPath, final Permission permission ) + public ContentAccessException( final Throwable cause, final User user, final ContentPath contentPath, final Permission permission ) { super( cause, MessageFormat.format( "Access denied to [{0}] for [{1}] by user [{2}] {3}", contentPath, permission, user == null ? "unknown" : user.getKey(), @@ -54,17 +41,4 @@ public Permission getPermission() { return permission; } - - private static ContentPath translateNodePathToContentPath( final NodePath nodePath ) - { - final int beginIndex = nodePath.toString().indexOf( '/', 1 ); - if ( beginIndex == -1 ) - { - return ContentPath.ROOT; - } - else - { - return ContentPath.from( nodePath.toString().substring( beginIndex ) ); - } - } } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentConstants.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentConstants.java index fa0a6002bb5..b2f69fdbf60 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentConstants.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentConstants.java @@ -36,9 +36,7 @@ public final class ContentConstants public static final String CONTENT_ROOT_NAME = "content"; - public static final NodePath CONTENT_ROOT_PARENT = NodePath.ROOT; - - public static final NodePath CONTENT_ROOT_PATH = new NodePath( CONTENT_ROOT_PARENT, NodeName.from( CONTENT_ROOT_NAME ) ); + public static final NodePath CONTENT_ROOT_PATH = new NodePath( NodePath.ROOT, NodeName.from( CONTENT_ROOT_NAME ) ); public static final NodeType CONTENT_NODE_COLLECTION = NodeType.from( "content" ); diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentService.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentService.java index 4185c989bb8..3392dbf4cde 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentService.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentService.java @@ -80,8 +80,6 @@ public interface ContentService FindContentVersionsResult getVersions( FindContentVersionsParams params ); - GetActiveContentVersionsResult getActiveVersions( GetActiveContentVersionsParams params ); - ByteSource getBinary( ContentId contentId, BinaryReference binaryReference ); ByteSource getBinary( ContentId contentId, ContentVersionId contentVersionId, BinaryReference binaryReference ); diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java index 98af85d7b3c..0c5c6abfb1d 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java @@ -1,66 +1,72 @@ package com.enonic.xp.content; import java.time.Instant; -import java.util.Objects; +import java.util.List; import com.enonic.xp.annotation.PublicApi; -import com.enonic.xp.index.ChildOrder; import com.enonic.xp.security.PrincipalKey; -import com.enonic.xp.security.acl.AccessControlList; +import com.enonic.xp.node.Attributes; @PublicApi public final class ContentVersion { private final ContentVersionId id; - private final PrincipalKey modifier; + private final ContentPath path; - private final String displayName; + private final Instant timestamp; - private final ContentPath path; + private final String change; - private final Instant modified; + private final List changeFields; - private final Instant timestamp; + private final Instant changedTime; - private final ChildOrder childOrder; + private final PrincipalKey changedBy; - private final String comment; + private final Instant publishedTime; + + private final PrincipalKey publishedBy; + + private final Instant publishedFrom; + + private final Instant publishedTo; + + private final Instant unpublishedTime; - private final ContentVersionPublishInfo publishInfo; + private final PrincipalKey unpublishedBy; - private final WorkflowInfo workflowInfo; + private final String comment; - private final AccessControlList permissions; + private final Attributes attributes; private ContentVersion( Builder builder ) { - this.modifier = builder.modifier; - this.displayName = builder.displayName; + this.id = builder.id; this.path = builder.path; - this.modified = builder.modified; - this.comment = builder.comment; this.timestamp = builder.timestamp; - this.childOrder = builder.childOrder; - this.id = builder.id; - this.publishInfo = builder.publishInfo; - this.workflowInfo = builder.workflowInfo; - this.permissions = builder.permissions; - } - - public PrincipalKey getModifier() - { - return modifier; + this.change = builder.change; + this.changeFields = builder.changeFields == null ? List.of() : List.copyOf( builder.changeFields ); + this.changedBy = builder.modifiedBy; + this.changedTime = builder.modifiedTime; + this.comment = builder.comment; + this.publishedTime = builder.published; + this.publishedBy = builder.publishedBy; + this.publishedFrom = builder.publishedFrom; + this.publishedTo = builder.publishedTo; + this.unpublishedTime = builder.unpublished; + this.unpublishedBy = builder.unpublishedBy; + this.attributes = builder.attributes; } - public String getDisplayName() + public PrincipalKey getChangedBy() { - return displayName; + return changedBy; } - public Instant getModified() + public Instant getChangedTime() { - return modified; + return changedTime; } public String getComment() @@ -73,91 +79,98 @@ public Instant getTimestamp() return timestamp; } - public ChildOrder getChildOrder() + public ContentVersionId getId() { - return childOrder; + return id; } - public ContentVersionId getId() + public ContentPath getPath() { - return id; + return path; } - public ContentVersionPublishInfo getPublishInfo() + public String getChange() { - return publishInfo; + return change; } - public WorkflowInfo getWorkflowInfo() + public List getChangeFields() { - return workflowInfo; + return changeFields; } - public ContentPath getPath() + public Instant getPublishedTime() { - return path; + return publishedTime; } - public AccessControlList getPermissions() + public PrincipalKey getPublishedBy() { - return permissions; + return publishedBy; } - public static Builder create() + public Instant getPublishedFrom() { - return new Builder(); + return publishedFrom; } - @Override - public boolean equals( final Object o ) + public Instant getPublishedTo() { - if ( this == o ) - { - return true; - } - if ( !( o instanceof ContentVersion ) ) - { - return false; - } - final ContentVersion that = (ContentVersion) o; - return Objects.equals( id, that.id ) && Objects.equals( modifier, that.modifier ) && - Objects.equals( displayName, that.displayName ) && Objects.equals( modified, that.modified ) && - Objects.equals( timestamp, that.timestamp ) && Objects.equals( childOrder, that.childOrder ) && - Objects.equals( comment, that.comment ) && Objects.equals( publishInfo, that.publishInfo ) && - Objects.equals( workflowInfo, that.workflowInfo ) && Objects.equals( permissions, that.permissions ) && - Objects.equals( path, that.path ); + return publishedTo; } - @Override - public int hashCode() + public Instant getUnpublishedTime() { - return Objects.hash( id, modifier, displayName, modified, timestamp, childOrder, comment, publishInfo, workflowInfo, path, - permissions ); + return unpublishedTime; } - public static final class Builder + public PrincipalKey getUnpublishedBy() + { + return unpublishedBy; + } + + @Deprecated + public Attributes getAttributes() { - private PrincipalKey modifier; + return attributes; + } - private String displayName; + public static Builder create() + { + return new Builder(); + } + + public static final class Builder + { + private PrincipalKey modifiedBy; private ContentPath path; - private Instant modified; + private String change; - private Instant timestamp; + private List changeFields; - private ChildOrder childOrder; + private Instant modifiedTime; + + private Instant timestamp; private String comment; private ContentVersionId id; - private ContentVersionPublishInfo publishInfo; + private Instant published; + + private PrincipalKey publishedBy; + + private Instant publishedFrom; + + private Instant publishedTo; - private WorkflowInfo workflowInfo; + private Instant unpublished; - private AccessControlList permissions; + private PrincipalKey unpublishedBy; + + private Attributes attributes; private Builder() { @@ -169,63 +182,86 @@ public Builder id( final ContentVersionId id ) return this; } - public Builder modifier( PrincipalKey modifier ) + public Builder changedBy( final PrincipalKey modifier ) { - this.modifier = modifier; + this.modifiedBy = modifier; return this; } - public Builder displayName( String displayName ) + public Builder path( final ContentPath path ) { - this.displayName = displayName; + this.path = path; return this; } - public Builder path( ContentPath path ) + public Builder modified( final Instant modified ) { - this.path = path; + this.modifiedTime = modified; return this; } - public Builder modified( Instant modified ) + public Builder timestamp( final Instant timestamp ) { - this.modified = modified; + this.timestamp = timestamp; return this; } - public Builder timestamp( Instant timestamp ) + public Builder comment( final String comment ) { - this.timestamp = timestamp; + this.comment = comment; return this; } - public Builder childOrder( ChildOrder childOrder ) + public Builder publishedFrom( final Instant publishedFrom ) { - this.childOrder = childOrder; + this.publishedFrom = publishedFrom; return this; } - public Builder comment( String comment ) + public Builder publishedTo( final Instant publishedTo ) { - this.comment = comment; + this.publishedTo = publishedTo; return this; } - public Builder publishInfo( ContentVersionPublishInfo publishInfo ) + public Builder published( final Instant published ) { - this.publishInfo = publishInfo; + this.published = published; return this; } - public Builder workflowInfo( WorkflowInfo workflowInfo ) + public Builder publishedBy( final PrincipalKey publishedBy ) { - this.workflowInfo = workflowInfo; + this.publishedBy = publishedBy; + return this; + } + + public Builder unpublished( final Instant unpublished ) + { + this.unpublished = unpublished; + return this; + } + + public Builder unpublishedBy( final PrincipalKey unpublishedBy ) + { + this.unpublishedBy = unpublishedBy; + return this; + } + + public Builder change( final String change) { + this.change = change; + return this; + } + + public Builder changeFields( final List changeFields) { + this.changeFields = changeFields; return this; } - public Builder permissions( AccessControlList permissions ) + @Deprecated + public Builder attributes( final Attributes attributes ) { - this.permissions = permissions; + this.attributes = attributes; return this; } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionDateComparator.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionDateComparator.java deleted file mode 100644 index 8f7597a3697..00000000000 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionDateComparator.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.enonic.xp.content; - -import java.time.Instant; -import java.util.Comparator; - -final class ContentVersionDateComparator - implements Comparator -{ - public static final ContentVersionDateComparator INSTANCE = new ContentVersionDateComparator(); - - private ContentVersionDateComparator() - { - } - - @Override - public int compare( final ContentVersion thisVersion, final ContentVersion thatVersion ) - { - Instant thisTime; - Instant thatTime; - - if ( thisVersion.getPublishInfo() != null && thisVersion.getPublishInfo().getTimestamp() != null ) - { - thisTime = thisVersion.getPublishInfo().getTimestamp(); - } - else - { - thisTime = thisVersion.getTimestamp(); - - } - if ( thatVersion.getPublishInfo() != null && thatVersion.getPublishInfo().getTimestamp() != null ) - { - thatTime = thatVersion.getPublishInfo().getTimestamp(); - } - else - { - thatTime = thatVersion.getTimestamp(); - } - - return thatTime.compareTo( thisTime ); - } -} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionPublishInfo.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionPublishInfo.java deleted file mode 100644 index 82770733047..00000000000 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersionPublishInfo.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.enonic.xp.content; - -import java.time.Instant; -import java.util.Objects; - -import com.enonic.xp.security.PrincipalKey; - -public final class ContentVersionPublishInfo -{ - private final PrincipalKey publisher; - - private final Instant timestamp; - - private final String message; - - private final CommitType type; - - private final ContentPublishInfo contentPublishInfo; - - private ContentVersionPublishInfo( Builder builder ) - { - publisher = builder.publisher; - timestamp = builder.timestamp; - message = builder.message; - contentPublishInfo = builder.contentPublishInfo; - type = builder.type; - } - - public static Builder create() - { - return new Builder(); - } - - public PrincipalKey getPublisher() - { - return publisher; - } - - public Instant getTimestamp() - { - return timestamp; - } - - public String getMessage() - { - return message; - } - - public ContentPublishInfo getContentPublishInfo() - { - return contentPublishInfo; - } - - public CommitType getType() - { - return type; - } - - @Override - public boolean equals( final Object o ) - { - if ( this == o ) - { - return true; - } - if ( !( o instanceof ContentVersionPublishInfo ) ) - { - return false; - } - final ContentVersionPublishInfo that = (ContentVersionPublishInfo) o; - return Objects.equals( publisher, that.publisher ) && Objects.equals( timestamp, that.timestamp ) && - Objects.equals( message, that.message ) && Objects.equals( contentPublishInfo, that.contentPublishInfo ) && - Objects.equals( type, that.type ); - } - - @Override - public int hashCode() - { - return Objects.hash( publisher, timestamp, message, contentPublishInfo ); - } - - public enum CommitType - { - PUBLISHED, UNPUBLISHED, ARCHIVED, RESTORED, CUSTOM - } - - public static final class Builder - { - private PrincipalKey publisher; - - private Instant timestamp; - - private String message; - - private ContentPublishInfo contentPublishInfo; - - private CommitType type; - - private Builder() - { - } - - public Builder publisher( final PrincipalKey publisher ) - { - this.publisher = publisher; - return this; - } - - public Builder timestamp( final Instant timestamp ) - { - this.timestamp = timestamp; - return this; - } - - public Builder message( final String message ) - { - this.message = message; - return this; - } - - public Builder contentPublishInfo( final ContentPublishInfo contentPublishInfo ) - { - this.contentPublishInfo = contentPublishInfo; - return this; - } - - public Builder type( final CommitType type ) - { - this.type = type; - return this; - } - - public ContentVersionPublishInfo build() - { - return new ContentVersionPublishInfo( this ); - } - } -} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java index 56cec0db68a..41a64332a27 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java @@ -1,8 +1,5 @@ package com.enonic.xp.content; -import java.util.ArrayList; -import java.util.List; - import com.google.common.collect.ImmutableList; import com.enonic.xp.annotation.PublicApi; @@ -12,9 +9,9 @@ public final class ContentVersions extends AbstractImmutableEntityList { - private ContentVersions( Builder builder ) + private ContentVersions( final ImmutableList list ) { - super( ImmutableList.sortedCopyOf( ContentVersionDateComparator.INSTANCE, builder.contentVersions ) ); + super( list ); } public static Builder create() @@ -24,7 +21,7 @@ public static Builder create() public static final class Builder { - private final List contentVersions = new ArrayList<>(); + private final ImmutableList.Builder contentVersions = ImmutableList.builder(); private Builder() { @@ -38,7 +35,7 @@ public Builder add( final ContentVersion contentVersion ) public ContentVersions build() { - return new ContentVersions( this ); + return new ContentVersions( this.contentVersions.build() ); } } } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsParams.java deleted file mode 100644 index c0703459d2d..00000000000 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsParams.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.enonic.xp.content; - -import java.util.Objects; - -import com.enonic.xp.annotation.PublicApi; -import com.enonic.xp.branch.Branches; - -@PublicApi -public final class GetActiveContentVersionsParams -{ - private final ContentId contentId; - - private final Branches branches; - - private GetActiveContentVersionsParams( Builder builder ) - { - contentId = builder.contentId; - branches = builder.branches; - } - - public static Builder create() - { - return new Builder(); - } - - public ContentId getContentId() - { - return contentId; - } - - public Branches getBranches() - { - return branches; - } - - public static final class Builder - { - private ContentId contentId; - - private Branches branches; - - private Builder() - { - } - - public Builder contentId( ContentId contentId ) - { - this.contentId = contentId; - return this; - } - - public Builder branches( Branches branches ) - { - this.branches = branches; - return this; - } - - public GetActiveContentVersionsParams build() - { - Objects.requireNonNull( this.contentId, "contentId is required" ); - return new GetActiveContentVersionsParams( this ); - } - } -} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsResult.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsResult.java deleted file mode 100644 index 1e00261f5be..00000000000 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/GetActiveContentVersionsResult.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.enonic.xp.content; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - -import com.google.common.collect.ImmutableList; - -import com.enonic.xp.annotation.PublicApi; - -@PublicApi -public final class GetActiveContentVersionsResult -{ - private final ImmutableList activeContentVersions; - - private GetActiveContentVersionsResult( final Builder builder ) - { - this.activeContentVersions = ImmutableList.sortedCopyOf( Comparator. - comparing( ActiveContentVersionEntry::getContentVersion, ContentVersionDateComparator.INSTANCE ). - thenComparing( ( ActiveContentVersionEntry activeContentVersionEntry ) -> activeContentVersionEntry.getBranch().getValue() ), - builder.activeContentVersions ); - } - - public List getActiveContentVersions() - { - return activeContentVersions; - } - - public static Builder create() - { - return new Builder(); - } - - public static final class Builder - { - private final List activeContentVersions = new ArrayList<>(); - - private Builder() - { - } - - public Builder add( final ActiveContentVersionEntry activeContentVersion ) - { - if ( activeContentVersion != null && activeContentVersion.getContentVersion() != null ) - { - this.activeContentVersions.add( activeContentVersion ); - } - - return this; - } - - public GetActiveContentVersionsResult build() - { - return new GetActiveContentVersionsResult( this ); - } - } -} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/PublishContentResult.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/PublishContentResult.java index f89c07bd99d..dfa7debfce2 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/PublishContentResult.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/PublishContentResult.java @@ -1,18 +1,23 @@ package com.enonic.xp.content; +import java.util.List; +import java.util.Objects; + +import com.google.common.collect.ImmutableList; + import com.enonic.xp.annotation.PublicApi; @PublicApi public final class PublishContentResult { - private final ContentIds pushedContents; + private final ImmutableList publishedContents; - private final ContentIds failedContents; + private final ImmutableList failedContents; private PublishContentResult( Builder builder ) { - this.pushedContents = builder.pushedContents; - this.failedContents = builder.failedContents; + this.publishedContents = builder.publishedContents.build(); + this.failedContents = builder.failedContents.build(); } public static Builder create() @@ -22,39 +27,68 @@ public static Builder create() public ContentIds getPushedContents() { - return pushedContents; + return publishedContents.stream().map( Result::contentId ).collect( ContentIds.collector() ); } public ContentIds getFailedContents() + { + return failedContents.stream().map( Result::contentId ).collect( ContentIds.collector() ); + } + + public List getFailed() { return failedContents; } + public List getPublished() + { + return publishedContents; + } + public static final class Builder { - private ContentIds pushedContents = ContentIds.empty(); + private ImmutableList.Builder publishedContents = ImmutableList.builder(); - private ContentIds failedContents = ContentIds.empty(); + private ImmutableList.Builder failedContents = ImmutableList.builder(); private Builder() { } - public Builder setPushed( final ContentIds pushedContents ) + public Builder add( Result result ) { - this.pushedContents = pushedContents; + if ( result.failureReason == null ) + { + publishedContents.add( result ); + } + else + { + failedContents.add( result ); + } return this; } - public Builder setFailed( final ContentIds failedContents ) + public PublishContentResult build() { - this.failedContents = failedContents; - return this; + return new PublishContentResult( this ); } + } - public PublishContentResult build() + public enum Reason + { + ALREADY_EXIST, PARENT_NOT_FOUND, ACCESS_DENIED, INVALID, NOT_READY + } + + public record Result(ContentId contentId, Reason failureReason) + { + public static Result success( final ContentId contentId ) { - return new PublishContentResult( this ); + return new Result( contentId, null ); + } + + public static Result failure( final ContentId contentId, Reason failureReason ) + { + return new Result( contentId, Objects.requireNonNull( failureReason ) ); } } } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/PushContentParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/PushContentParams.java index 8ff669c3d9c..30a109b99ba 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/PushContentParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/PushContentParams.java @@ -1,5 +1,6 @@ package com.enonic.xp.content; +import java.time.Instant; import java.util.Objects; import com.google.common.base.Preconditions; @@ -15,7 +16,9 @@ public final class PushContentParams private final ContentIds excludeDescendantsOf; - private final ContentPublishInfo contentPublishInfo; + private final Instant publishFrom; + + private final Instant publishTo; private final boolean includeDependencies; @@ -26,7 +29,8 @@ public final class PushContentParams private PushContentParams( Builder builder ) { this.contentIds = builder.contentIds; - this.contentPublishInfo = builder.contentPublishInfo; + this.publishFrom = builder.publishFrom; + this.publishTo = builder.publishTo; this.includeDependencies = builder.includeDependencies; this.excludeDescendantsOf = Objects.requireNonNullElse( builder.excludeDescendantsOf, ContentIds.empty() ); this.publishContentListener = builder.publishContentListener; @@ -49,9 +53,14 @@ public ContentIds getExcludedContentIds() return excludedContentIds; } - public ContentPublishInfo getContentPublishInfo() + public Instant getPublishFrom() { - return contentPublishInfo; + return publishFrom; + } + + public Instant getPublishTo() + { + return publishTo; } public ContentIds getExcludeDescendantsOf() @@ -82,7 +91,9 @@ public static final class Builder private ContentIds excludeDescendantsOf; - private ContentPublishInfo contentPublishInfo; + private Instant publishFrom; + + private Instant publishTo; private boolean includeDependencies = true; @@ -112,9 +123,15 @@ public Builder excludeDescendantsOf( ContentIds excludeDescendantsOf ) return this; } - public Builder contentPublishInfo( ContentPublishInfo contentPublishInfo ) + public Builder publishFrom( final Instant publishFrom ) + { + this.publishFrom = publishFrom; + return this; + } + + public Builder publishTo( final Instant publishTo ) { - this.contentPublishInfo = contentPublishInfo; + this.publishTo = publishTo; return this; } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertySet.java b/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertySet.java index e5056c5aecb..0ab76e69d1e 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertySet.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertySet.java @@ -542,6 +542,7 @@ public Iterable getValues( final String name ) return valueBuilder.build(); } + @Deprecated public PropertySet getPropertySet( final PropertyPath path ) { final Property property = getProperty( path ); @@ -552,6 +553,7 @@ public PropertySet getPropertySet( final PropertyPath path ) return property.getValue().asData(); } + @Deprecated public PropertySet getPropertySet( final String path ) { return getPropertySet( PropertyPath.from( path ) ); diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertyTree.java b/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertyTree.java index dcc71a3977d..b5e965a86dc 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertyTree.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/data/PropertyTree.java @@ -218,14 +218,16 @@ public Iterable getValues( final String name ) return root.getValues( name ); } + @Deprecated public PropertySet getPropertySet( final PropertyPath path ) { - return root.getPropertySet( path ); + return root.getSet( path ); } + @Deprecated public PropertySet getPropertySet( final String path ) { - return root.getPropertySet( path ); + return root.getSet( path ); } public int getTotalSize() diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/ApplyNodePermissionsParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/ApplyNodePermissionsParams.java index 9a17d6c0052..a426a146733 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/ApplyNodePermissionsParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/ApplyNodePermissionsParams.java @@ -23,6 +23,8 @@ public final class ApplyNodePermissionsParams private final ApplyPermissionsScope scope; + private final Attributes versionAttributes; + private final ApplyNodePermissionsListener listener; private final Branches branches; @@ -34,6 +36,7 @@ private ApplyNodePermissionsParams( Builder builder ) permissions = builder.permissions.build(); addPermissions = builder.addPermissions.build(); removePermissions = builder.removePermissions.build(); + versionAttributes = builder.versionAttributes; listener = builder.listener; branches = Branches.from( builder.branches.build() ); @@ -71,6 +74,11 @@ public ApplyPermissionsScope getScope() return scope; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public ApplyNodePermissionsListener getListener() { return listener; @@ -93,6 +101,8 @@ public static final class Builder private ApplyPermissionsScope scope; + private Attributes versionAttributes; + private ApplyNodePermissionsListener listener; private final ImmutableSet.Builder branches = ImmutableSet.builder(); @@ -152,6 +162,12 @@ public Builder addBranches( final Branches branches ) return this; } + public Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public ApplyNodePermissionsParams build() { return new ApplyNodePermissionsParams( this ); diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java new file mode 100644 index 00000000000..140966746fc --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java @@ -0,0 +1,103 @@ +package com.enonic.xp.node; + +import java.util.List; + +import com.google.common.collect.ImmutableMap; + +import com.enonic.xp.util.GenericValue; + +public final class Attributes +{ + public static final String KEY_PROPERTY = "_key"; + + private final ImmutableMap attrs; + + private Attributes( final ImmutableMap list ) + { + this.attrs = list; + } + + public List list() + { + return attrs.values().asList(); + } + + public GenericValue get( final String key ) + { + return attrs.get( key ); + } + + public static Builder create() + { + return new Builder(); + } + + public static class Builder + { + private final ImmutableMap.Builder builder = ImmutableMap.builder(); + + public AttributeBuilder attribute( final String key ) + { + return new AttributeBuilder( this, key ); + } + + public Builder addAll( final Iterable values ) + { + for ( GenericValue value : values ) + { + builder.put( value.property( KEY_PROPERTY ).asString(), value ); + } + return this; + } + + public Attributes build() + { + return new Attributes( builder.build() ); + } + + public Attributes buildKeepingLast() + { + return new Attributes( builder.buildKeepingLast() ); + } + } + + public static final class AttributeBuilder + { + private final GenericValue.ObjectBuilder obj = GenericValue.object(); + + private final Attributes.Builder attributesBuilder; + + private final String key; + + private AttributeBuilder( final Attributes.Builder attributesBuilder, final String key ) + { + this.attributesBuilder = attributesBuilder; + this.key = key; + obj.put( KEY_PROPERTY, key ); + } + + public AttributeBuilder put( final String key, final GenericValue value ) + { + obj.put( key, value ); + return this; + } + + public AttributeBuilder put( final String key, final String value ) + { + obj.put( key, value ); + return this; + } + + public AttributeBuilder putArray( final String key, final List value ) + { + obj.put( key, GenericValue.stringList( value ) ); + return this; + } + + public Attributes.Builder end() + { + attributesBuilder.builder.put( key, obj.build() ); + return attributesBuilder; + } + } +} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/CommitNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/CommitNodeParams.java new file mode 100644 index 00000000000..0505cca829a --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/CommitNodeParams.java @@ -0,0 +1,57 @@ +package com.enonic.xp.node; + +public final class CommitNodeParams +{ + private final NodeCommitEntry nodeCommitEntry; + + private final NodeVersionIds nodeVersionIds; + + private CommitNodeParams( final Builder builder ) + { + this.nodeCommitEntry = builder.nodeCommitEntry; + this.nodeVersionIds = builder.nodeVersionIds; + } + + public NodeCommitEntry getNodeCommitEntry() + { + return nodeCommitEntry; + } + + public NodeVersionIds getNodeVersionIds() + { + return nodeVersionIds; + } + + public static Builder create() + { + return new Builder(); + } + + public static class Builder + { + private NodeCommitEntry nodeCommitEntry; + + private NodeVersionIds nodeVersionIds; + + private Builder() + { + } + + public Builder nodeCommitEntry( final NodeCommitEntry nodeCommitEntry ) + { + this.nodeCommitEntry = nodeCommitEntry; + return this; + } + + public Builder nodeVersionIds( final NodeVersionIds nodeVersionIds ) + { + this.nodeVersionIds = nodeVersionIds; + return this; + } + + public CommitNodeParams build() + { + return new CommitNodeParams( this ); + } + } +} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/CreateNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/CreateNodeParams.java index 30504bdb66f..30065f3c269 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/CreateNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/CreateNodeParams.java @@ -39,6 +39,8 @@ public final class CreateNodeParams private final BinaryAttachments binaryAttachments; + private final Attributes versionAttributes; + private final RefreshMode refresh; private CreateNodeParams( Builder builder ) @@ -55,6 +57,7 @@ private CreateNodeParams( Builder builder ) this.manualOrderValue = builder.manualOrderValue; this.nodeType = builder.nodeType; this.binaryAttachments = builder.binaryAttachments.build(); + this.versionAttributes = builder.versionAttributes; this.refresh = builder.refresh; } @@ -140,6 +143,11 @@ public BinaryAttachments getBinaryAttachments() return binaryAttachments; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public RefreshMode getRefresh() { return refresh; @@ -171,6 +179,8 @@ public static final class Builder private BinaryAttachments.Builder binaryAttachments = BinaryAttachments.create(); + private Attributes versionAttributes; + private RefreshMode refresh; private Builder() @@ -282,6 +292,12 @@ public Builder setBinaryAttachments( final BinaryAttachments binaryAttachments ) return this; } + public Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public Builder refresh( final RefreshMode refresh ) { this.refresh = refresh; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/DeleteNodeResult.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/DeleteNodeResult.java index 23bd70f1ca1..50778d92329 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/DeleteNodeResult.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/DeleteNodeResult.java @@ -1,17 +1,19 @@ package com.enonic.xp.node; -import java.util.Objects; +import java.util.List; + +import com.google.common.collect.ImmutableList; import com.enonic.xp.annotation.PublicApi; @PublicApi public final class DeleteNodeResult { - private final NodeIds nodeIds; + private final ImmutableList results; private DeleteNodeResult( final Builder builder ) { - this.nodeIds = Objects.requireNonNull( builder.nodeIds ); + this.results = builder.builder.build(); } public static Builder create() @@ -21,20 +23,24 @@ public static Builder create() public NodeIds getNodeIds() { - return nodeIds; + return results.stream().map( Result::nodeId ).collect( NodeIds.collector() ); + } + + public List getDeleted() + { + return results; } public static final class Builder { - private NodeIds nodeIds; + private ImmutableList.Builder builder = ImmutableList.builder(); private Builder() { } - public Builder nodeIds( final NodeIds nodeIds ) - { - this.nodeIds = nodeIds; + public Builder add( final Result result ) { + this.builder.add( result ); return this; } @@ -43,4 +49,7 @@ public DeleteNodeResult build() return new DeleteNodeResult( this ); } } + + public record Result(NodeId nodeId, NodeVersionId nodeVersionId) { + } } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/DuplicateNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/DuplicateNodeParams.java index 87a70ccc43b..8ec5a13b92e 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/DuplicateNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/DuplicateNodeParams.java @@ -19,6 +19,8 @@ public final class DuplicateNodeParams private final NodePath parent; + private final Attributes versionAttributes; + private final RefreshMode refresh; private DuplicateNodeParams( Builder builder ) @@ -29,6 +31,7 @@ private DuplicateNodeParams( Builder builder ) this.includeChildren = builder.includeChildren; this.name = builder.name; this.parent = builder.parent; + this.versionAttributes = builder.versionAttributes; this.refresh = builder.refresh; } @@ -67,6 +70,11 @@ public NodePath getParent() return parent; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public RefreshMode getRefresh() { return refresh; @@ -86,6 +94,8 @@ public static final class Builder private NodePath parent; + private Attributes versionAttributes; + private RefreshMode refresh; private Builder() @@ -128,6 +138,12 @@ public Builder parent( final NodePath parent ) return this; } + public Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public Builder refresh( final RefreshMode refresh ) { this.refresh = refresh; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/DuplicateNodeResult.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/DuplicateNodeResult.java similarity index 77% rename from modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/DuplicateNodeResult.java rename to modules/core/core-api/src/main/java/com/enonic/xp/node/DuplicateNodeResult.java index 440aba1816a..3e4ed84a56a 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/DuplicateNodeResult.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/DuplicateNodeResult.java @@ -1,17 +1,12 @@ -package com.enonic.xp.repo.impl.node; +package com.enonic.xp.node; -import java.util.List; import java.util.Objects; -import com.google.common.collect.ImmutableList; - -import com.enonic.xp.node.Node; - public class DuplicateNodeResult { private final Node node; - private final List children; + private final Nodes children; private DuplicateNodeResult( Builder builder ) { @@ -24,7 +19,7 @@ public static Builder create() return new Builder(); } - public List getChildren() + public Nodes getChildren() { return children; } @@ -36,7 +31,7 @@ public Node getNode() public static class Builder { - private final ImmutableList.Builder children = ImmutableList.builder(); + private final Nodes.Builder children = Nodes.create(); private Node node; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/ImportNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/ImportNodeParams.java index b5f5cf119b2..efaa14bc697 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/ImportNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/ImportNodeParams.java @@ -12,6 +12,8 @@ public final class ImportNodeParams private final boolean importPermissionsOnCreate; + private final Attributes versionAttributes; + private final RefreshMode refresh; private ImportNodeParams( Builder builder ) @@ -21,6 +23,7 @@ private ImportNodeParams( Builder builder ) insertManualStrategy = builder.insertManualStrategy; importPermissions = builder.importPermissions; importPermissionsOnCreate = builder.importPermissionsOnCreate; + versionAttributes = builder.versionAttributes; this.refresh = builder.refresh; } @@ -54,6 +57,11 @@ public boolean isImportPermissionsOnCreate() return importPermissionsOnCreate; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public RefreshMode getRefresh() { return refresh; @@ -71,6 +79,8 @@ public static final class Builder private boolean importPermissionsOnCreate = true; + private Attributes versionAttributes; + private RefreshMode refresh; private Builder() @@ -107,6 +117,12 @@ public Builder importPermissionsOnCreate( boolean importPermissionsOnCreate ) return this; } + public Builder versionAttributes( Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public Builder refresh( final RefreshMode refresh ) { this.refresh = refresh; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/LoadNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/LoadNodeParams.java index 31c79a35173..9c3ebda2aa5 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/LoadNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/LoadNodeParams.java @@ -6,10 +6,13 @@ public final class LoadNodeParams private final NodeCommitId nodeCommitId; + private final Attributes attributes; + private LoadNodeParams( final Builder builder ) { node = builder.node; nodeCommitId = builder.nodeCommitId; + attributes = builder.attributes; } public Node getNode() @@ -22,6 +25,11 @@ public NodeCommitId getNodeCommitId() return nodeCommitId; } + public Attributes getAttributes() + { + return attributes; + } + public static Builder create() { return new Builder(); @@ -34,6 +42,8 @@ public static final class Builder private NodeCommitId nodeCommitId; + private Attributes attributes; + private Builder() { } @@ -50,6 +60,12 @@ public Builder nodeCommitId( final NodeCommitId val ) return this; } + public Builder attributes( final Attributes val ) + { + attributes = val; + return this; + } + public LoadNodeParams build() { return new LoadNodeParams( this ); diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/MoveNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/MoveNodeParams.java index df2950b2d17..6655d73c674 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/MoveNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/MoveNodeParams.java @@ -15,6 +15,8 @@ public final class MoveNodeParams private final NodePath newParentPath; + private final Attributes versionAttributes; + private final MoveNodeListener moveListener; private final NodeDataProcessor processor; @@ -26,6 +28,7 @@ private MoveNodeParams( final Builder builder ) this.nodeId = Objects.requireNonNull( builder.nodeId, "nodeId is required" ); this.newName = builder.newName; this.newParentPath = builder.newParentPath; + this.versionAttributes = builder.versionAttributes; this.moveListener = builder.moveListener; this.processor = Objects.requireNonNullElse( builder.processor, ( n, p ) -> n); this.refresh = builder.refresh; @@ -51,6 +54,11 @@ public NodePath getNewParentPath() return newParentPath; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public MoveNodeListener getMoveListener() { return moveListener; @@ -74,6 +82,8 @@ public static final class Builder private NodePath newParentPath; + private Attributes versionAttributes; + private MoveNodeListener moveListener; private NodeDataProcessor processor; @@ -102,6 +112,12 @@ public Builder newParentPath( final NodePath parentPath ) return this; } + public Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public Builder moveListener( final MoveNodeListener moveListener ) { this.moveListener = moveListener; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeCompareStatus.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeCompareStatus.java new file mode 100644 index 00000000000..5da866a8fa6 --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeCompareStatus.java @@ -0,0 +1,9 @@ +package com.enonic.xp.node; + +import com.enonic.xp.annotation.PublicApi; + +@PublicApi +public enum NodeCompareStatus +{ + NEW, NEW_TARGET, NEWER, OLDER, EQUAL, MOVED; +} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparison.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparison.java index a0fddcb4cb0..bd44f726103 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparison.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparison.java @@ -14,9 +14,9 @@ public final class NodeComparison private final NodeId targetId; - private final CompareStatus compareStatus; + private final NodeCompareStatus compareStatus; - public NodeComparison( final NodeId sourceId, final NodePath sourcePath, NodeId targetId, NodePath targetPath, final CompareStatus compareStatus ) + public NodeComparison( final NodeId sourceId, final NodePath sourcePath, NodeId targetId, NodePath targetPath, final NodeCompareStatus compareStatus ) { this.sourceId = sourceId; this.targetId = targetId; @@ -31,7 +31,7 @@ public NodeId getNodeId() return sourceId != null ? sourceId : targetId; } - public CompareStatus getCompareStatus() + public NodeCompareStatus getCompareStatus() { return compareStatus; } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparisons.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparisons.java index fdff0ccc0b0..6d518ad5c60 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparisons.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeComparisons.java @@ -4,11 +4,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; import com.enonic.xp.annotation.PublicApi; -import com.enonic.xp.content.CompareStatus; @PublicApi public final class NodeComparisons @@ -62,14 +59,6 @@ public NodePaths getSourcePaths() return this.comparisonMap.values().stream().map( NodeComparison::getSourcePath ).collect( NodePaths.collector() ); } - public Set getWithStatus( final CompareStatus status ) - { - return this.comparisonMap.values() - .stream() - .filter( nodeComparison -> nodeComparison.getCompareStatus() == status ) - .collect( Collectors.toSet() ); - } - public Collection getComparisons() { return this.comparisonMap.values(); diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeService.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeService.java index 68ea44989ae..6d84b199616 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeService.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeService.java @@ -17,9 +17,7 @@ public interface NodeService MoveNodeResult move( MoveNodeParams params ); - PushNodesResult push( NodeIds ids, Branch target ); - - PushNodesResult push( NodeIds ids, Branch target, PushNodesListener pushListener ); + PushNodesResult push( PushNodeParams params ); DeleteNodeResult delete( DeleteNodeParams deleteNodeParams ); @@ -33,7 +31,7 @@ public interface NodeService Nodes getByPaths( NodePaths paths ); - Node duplicate( DuplicateNodeParams params ); + DuplicateNodeResult duplicate( DuplicateNodeParams params ); FindNodesByParentResult findByParent( FindNodesByParentParams params ); @@ -71,8 +69,11 @@ public interface NodeService LoadNodeResult loadNode( LoadNodeParams params ); + @Deprecated NodeCommitEntry commit( NodeCommitEntry nodeCommitEntry, RoutableNodeVersionIds routableNodeVersionIds ); + NodeCommitEntry commit( CommitNodeParams params ); + NodeCommitEntry commit( NodeCommitEntry nodeCommitEntry, NodeIds nodeIds ); NodeCommitEntry getCommit( NodeCommitId nodeCommitId ); @@ -86,4 +87,6 @@ public interface NodeService void importNodeVersion( ImportNodeVersionParams params ); void importNodeCommit( ImportNodeCommitParams params ); + + void addAttributes( NodeVersionId nodeVersionId, Attributes attributes ); } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeVersionMetadata.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeVersionMetadata.java index 36f379ab5b1..cccde203ff8 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeVersionMetadata.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeVersionMetadata.java @@ -23,6 +23,8 @@ public final class NodeVersionMetadata private final Instant timestamp; + private final Attributes attributes; + private NodeVersionMetadata( Builder builder ) { nodeVersionId = Objects.requireNonNull( builder.nodeVersionId ); @@ -32,6 +34,7 @@ private NodeVersionMetadata( Builder builder ) nodePath = Objects.requireNonNull( builder.nodePath ); nodeCommitId = builder.nodeCommitId; timestamp = Objects.requireNonNull( builder.timestamp ); + attributes = builder.attributes; } public static Builder create() @@ -39,11 +42,6 @@ public static Builder create() return new Builder(); } - public static Builder create( NodeVersionMetadata nodeVersionMetadata ) - { - return new Builder( nodeVersionMetadata ); - } - public NodeVersionId getNodeVersionId() { return nodeVersionId; @@ -74,6 +72,11 @@ public NodeCommitId getNodeCommitId() return nodeCommitId; } + public Attributes getAttributes() + { + return attributes; + } + public Instant getTimestamp() { return timestamp; @@ -95,19 +98,10 @@ public static final class Builder private Instant timestamp; - private Builder() - { - } + private Attributes attributes; - private Builder( NodeVersionMetadata nodeVersionMetadata ) + private Builder() { - nodeVersionId = nodeVersionMetadata.nodeVersionId; - nodeVersionKey = nodeVersionMetadata.nodeVersionKey; - binaryBlobKeys = nodeVersionMetadata.binaryBlobKeys; - nodeId = nodeVersionMetadata.nodeId; - nodePath = nodeVersionMetadata.nodePath; - nodeCommitId = nodeVersionMetadata.nodeCommitId; - timestamp = nodeVersionMetadata.timestamp; } public Builder nodeVersionId( NodeVersionId nodeVersionId ) @@ -152,6 +146,12 @@ public Builder timestamp( Instant timestamp ) return this; } + public Builder attributes( Attributes attributes ) + { + this.attributes = attributes; + return this; + } + public NodeVersionMetadata build() { return new NodeVersionMetadata( this ); @@ -161,55 +161,16 @@ public NodeVersionMetadata build() @Override public boolean equals( final Object o ) { - if ( this == o ) - { - return true; - } - if ( o == null || getClass() != o.getClass() ) - { - return false; - } - - final NodeVersionMetadata that = (NodeVersionMetadata) o; - - if ( nodeVersionId != null ? !nodeVersionId.equals( that.nodeVersionId ) : that.nodeVersionId != null ) - { - return false; - } - if ( nodeVersionKey != null ? !nodeVersionKey.equals( that.nodeVersionKey ) : that.nodeVersionKey != null ) - { - return false; - } - if ( binaryBlobKeys != null ? !binaryBlobKeys.equals( that.binaryBlobKeys ) : that.binaryBlobKeys != null ) - { - return false; - } - if ( nodeId != null ? !nodeId.equals( that.nodeId ) : that.nodeId != null ) - { - return false; - } - if ( nodePath != null ? !nodePath.equals( that.nodePath ) : that.nodePath != null ) - { - return false; - } - if ( nodeCommitId != null ? !nodeCommitId.equals( that.nodeCommitId ) : that.nodeCommitId != null ) - { - return false; - } - return !( timestamp != null ? !timestamp.equals( that.timestamp ) : that.timestamp != null ); - + return o instanceof final NodeVersionMetadata that && Objects.equals( nodeVersionId, that.nodeVersionId ) && + Objects.equals( nodeVersionKey, that.nodeVersionKey ) && Objects.equals( binaryBlobKeys, that.binaryBlobKeys ) && + Objects.equals( nodeId, that.nodeId ) && Objects.equals( nodePath, that.nodePath ) && + Objects.equals( nodeCommitId, that.nodeCommitId ) && Objects.equals( timestamp, that.timestamp ) && + Objects.equals( attributes, that.attributes ); } @Override public int hashCode() { - int result = nodeVersionId != null ? nodeVersionId.hashCode() : 0; - result = 31 * result + ( nodeVersionKey != null ? nodeVersionKey.hashCode() : 0 ); - result = 31 * result + ( binaryBlobKeys != null ? binaryBlobKeys.hashCode() : 0 ); - result = 31 * result + ( nodeId != null ? nodeId.hashCode() : 0 ); - result = 31 * result + ( nodePath != null ? nodePath.hashCode() : 0 ); - result = 31 * result + ( nodeCommitId != null ? nodeCommitId.hashCode() : 0 ); - result = 31 * result + ( timestamp != null ? timestamp.hashCode() : 0 ); - return result; + return Objects.hash( nodeVersionId, nodeVersionKey, binaryBlobKeys, nodeId, nodePath, nodeCommitId, timestamp, attributes ); } } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/PatchNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/PatchNodeParams.java index 0f4498ae021..35c33fece42 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/PatchNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/PatchNodeParams.java @@ -21,6 +21,8 @@ public final class PatchNodeParams private final BinaryAttachments binaryAttachments; + private final Attributes versionAttributes; + private final RefreshMode refresh; private final Branches branches; @@ -31,6 +33,7 @@ private PatchNodeParams( final Builder builder ) this.path = builder.path; this.editor = builder.editor; this.binaryAttachments = builder.binaryAttachments.build(); + this.versionAttributes = builder.versionAttributes; this.refresh = builder.refresh; this.branches = Branches.from( builder.branches.build() ); } @@ -70,6 +73,11 @@ public Branches getBranches() return branches; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public static final class Builder { private final ImmutableSet.Builder branches = ImmutableSet.builder(); @@ -82,8 +90,9 @@ public static final class Builder private BinaryAttachments.Builder binaryAttachments = BinaryAttachments.create(); - private RefreshMode refresh; + private Attributes versionAttributes; + private RefreshMode refresh; private Builder() { @@ -123,6 +132,12 @@ public Builder setBinaryAttachments( final BinaryAttachments binaryAttachments ) return this; } + public Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public Builder refresh( final RefreshMode refresh ) { this.refresh = refresh; @@ -145,7 +160,7 @@ private void validate() { if ( this.id == null && this.path == null ) { - throw new IllegalArgumentException("Either id or path is required"); + throw new IllegalArgumentException( "Either id or path is required" ); } Objects.requireNonNull( this.editor, "editor is required" ); } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeParams.java new file mode 100644 index 00000000000..28062497f32 --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeParams.java @@ -0,0 +1,93 @@ +package com.enonic.xp.node; + +import java.util.Objects; + +import com.enonic.xp.branch.Branch; + +public final class PushNodeParams +{ + private final NodeIds ids; + + private final Branch target; + + private final PushNodesListener pushListener; + + private final NodeDataProcessor processor; + + private PushNodeParams( final Builder builder ) + { + this.ids = Objects.requireNonNull( builder.ids, "ids is required" ); + this.target = Objects.requireNonNull( builder.target, "target is required" ); + this.pushListener = builder.pushListener; + this.processor = builder.processor; + } + + public NodeIds getIds() + { + return ids; + } + + public Branch getTarget() + { + return target; + } + + public PushNodesListener getPushListener() + { + return pushListener; + } + + public NodeDataProcessor getProcessor() + { + return processor; + } + + public static Builder create() + { + return new Builder(); + } + + public static class Builder + { + private NodeIds ids; + + private Branch target; + + private PushNodesListener pushListener; + + private NodeDataProcessor processor; + + private Builder() + { + } + + public Builder ids( final NodeIds ids ) + { + this.ids = ids; + return this; + } + + public Builder target( final Branch target ) + { + this.target = target; + return this; + } + + public Builder publishListener( final PushNodesListener pushListener ) + { + this.pushListener = pushListener; + return this; + } + + public Builder processor( final NodeDataProcessor processor ) + { + this.processor = processor; + return this; + } + + public PushNodeParams build() + { + return new PushNodeParams( this ); + } + } +} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeResult.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeResult.java index 632c606022f..a7633d393a9 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeResult.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/PushNodeResult.java @@ -1,5 +1,7 @@ package com.enonic.xp.node; +import java.util.Objects; + import com.enonic.xp.annotation.PublicApi; @PublicApi @@ -58,7 +60,7 @@ public static PushNodeResult success( final NodeId nodeId, final NodeVersionId n public static PushNodeResult failure( final NodeId nodeId, final NodePath nodePath, final Reason failureReason ) { - return new PushNodeResult( nodeId, nodePath, null, null, failureReason ); + return new PushNodeResult( nodeId, nodePath, null, null, Objects.requireNonNull( failureReason ) ); } public enum Reason diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionId.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionId.java index fed55d9bab7..45aa6f91718 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionId.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionId.java @@ -1,5 +1,6 @@ package com.enonic.xp.node; +@Deprecated public final class RoutableNodeVersionId { private final NodeId nodeId; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionIds.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionIds.java index b3e0f548354..794bf948414 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionIds.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/RoutableNodeVersionIds.java @@ -5,10 +5,9 @@ import com.google.common.collect.ImmutableList; -import com.enonic.xp.annotation.PublicApi; import com.enonic.xp.support.AbstractImmutableEntityList; -@PublicApi +@Deprecated public final class RoutableNodeVersionIds extends AbstractImmutableEntityList { diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/SortNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/SortNodeParams.java index 9e58fcada08..9a600f0921b 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/SortNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/SortNodeParams.java @@ -19,6 +19,8 @@ public final class SortNodeParams private final ImmutableList reorderChildNodes; + private final Attributes versionAttributes; + private final NodeDataProcessor processor; private final RefreshMode refresh; @@ -29,6 +31,7 @@ private SortNodeParams( final Builder builder ) this.childOrder = builder.childOrder; this.manualOrderSeed = builder.manualOrderSeed; this.reorderChildNodes = builder.reorderChildNodes.build(); + this.versionAttributes = builder.versionAttributes; this.processor = Objects.requireNonNullElse( builder.processor, ( n, p ) -> n ); this.refresh = builder.refresh; } @@ -48,6 +51,16 @@ public ChildOrder getManualOrderSeed() return manualOrderSeed; } + public List getReorderChildNodes() + { + return reorderChildNodes; + } + + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public NodeDataProcessor getProcessor() { return processor; @@ -58,11 +71,6 @@ public RefreshMode getRefresh() return refresh; } - public List getReorderChildNodes() - { - return reorderChildNodes; - } - public static Builder create() { return new Builder(); @@ -78,6 +86,8 @@ public static final class Builder private final ImmutableList.Builder reorderChildNodes = ImmutableList.builder(); + private Attributes versionAttributes; + private NodeDataProcessor processor; private RefreshMode refresh; @@ -110,6 +120,12 @@ public Builder addManualOrder( final ReorderChildNodeParams reorderChildNodePara return this; } + public Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public Builder processor( final NodeDataProcessor processor ) { this.processor = processor; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/SyncWorkResolverParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/SyncWorkResolverParams.java index 587d419db43..6673be32096 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/SyncWorkResolverParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/SyncWorkResolverParams.java @@ -22,7 +22,7 @@ public final class SyncWorkResolverParams private final Function filter; - private final Set statusesToStopDependenciesSearch; + private final Set statusesToStopDependenciesSearch; private SyncWorkResolverParams( Builder builder ) { @@ -60,7 +60,7 @@ public boolean isIncludeDependencies() return includeDependencies; } - public Set getStatusesToStopDependenciesSearch() + public Set getStatusesToStopDependenciesSearch() { return statusesToStopDependenciesSearch; } @@ -87,7 +87,7 @@ public static final class Builder private boolean includeDependencies = true; - private Set statusesToStopDependenciesSearch; + private Set statusesToStopDependenciesSearch; private Function filter; @@ -125,7 +125,7 @@ public Builder includeDependencies( final boolean includeDependencies ) return this; } - public Builder statusesToStopDependenciesSearch( final Set statusesToStopDependenciesSearch ) + public Builder statusesToStopDependenciesSearch( final Set statusesToStopDependenciesSearch ) { this.statusesToStopDependenciesSearch = statusesToStopDependenciesSearch; return this; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/UpdateNodeParams.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/UpdateNodeParams.java index 286120e4331..2762da364c2 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/UpdateNodeParams.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/UpdateNodeParams.java @@ -21,12 +21,15 @@ public final class UpdateNodeParams private final RefreshMode refresh; + private final Attributes versionAttributes; + private UpdateNodeParams( final Builder builder ) { this.id = builder.id; this.path = builder.path; this.editor = builder.editor; this.binaryAttachments = builder.binaryAttachments.build(); + this.versionAttributes = builder.versionAttributes; this.refresh = builder.refresh; } @@ -35,6 +38,11 @@ public BinaryAttachments getBinaryAttachments() return binaryAttachments; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public static Builder create() { return new Builder(); @@ -70,8 +78,9 @@ public static final class Builder private BinaryAttachments.Builder binaryAttachments = BinaryAttachments.create(); - private RefreshMode refresh; + public Attributes versionAttributes; + private RefreshMode refresh; private Builder() { @@ -111,6 +120,12 @@ public Builder setBinaryAttachments( final BinaryAttachments binaryAttachments ) return this; } + public Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + public Builder refresh( final RefreshMode refresh ) { this.refresh = refresh; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/util/GenericValue.java b/modules/core/core-api/src/main/java/com/enonic/xp/util/GenericValue.java new file mode 100644 index 00000000000..460b3407bd3 --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/util/GenericValue.java @@ -0,0 +1,286 @@ +package com.enonic.xp.util; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +public final class GenericValue + implements Serializable +{ + @Serial + private static final long serialVersionUID = 0; + + private final Serializable value; + + private GenericValue( final Serializable value ) + { + this.value = Objects.requireNonNull( value ); + } + + public Optional optional( final String propertyName ) + { + return whenMapOrElse( m -> Optional.ofNullable( m.get( propertyName ) ), Optional::empty ); + } + + public GenericValue property( final String propertyName ) + { + return whenMapOrElse( m -> m.get( propertyName ), () -> { + throw new NoSuchElementException(); + } ); + } + + public Set> getProperties() + { + return whenMapOrElse( Map::entrySet, ImmutableSet::of ); + } + + public List asList() + { + return whenListOrElse( Function.identity(), () -> ImmutableList.of( this ) ); + } + + public String asString() + { + return switch ( value ) + { + case String s -> s; + case Long l -> Long.toString( l ); + case Integer i -> Integer.toString( i ); + case Double d -> Double.toString( d ); + case Boolean b -> Boolean.toString( b ); + default -> throw new IllegalStateException(); + }; + } + + public double asDouble() + { + return switch ( value ) + { + case Double d -> d; + case Long l -> l; + case Integer i -> i; + case String s -> Double.parseDouble( s ); + default -> throw new IllegalStateException(); + }; + } + + public int asInteger() + { + return switch ( value ) + { + case Integer i -> i; + case Long l -> Math.toIntExact( l ); + case Double d -> Math.toIntExact( d.longValue() ); + case String s -> Integer.parseInt( s ); + default -> throw new IllegalStateException(); + }; + } + + public long asLong() + { + return switch ( value ) + { + case Long l -> l; + case Integer i -> i; + case Double d -> d.longValue(); + case String s -> Long.parseLong( s ); + default -> throw new IllegalStateException(); + }; + } + + public boolean asBoolean() + { + return switch ( value ) + { + case Boolean b -> b; + default -> throw new IllegalStateException(); + }; + } + + public List asStringList() + { + return asList().stream().map( GenericValue::asString ).collect( ImmutableList.toImmutableList() ); + } + + public Object rawJava() + { + return switch ( value ) + { + case String s -> s; + case Long l -> l; + case Integer i -> i; + case Double d -> d; + case Boolean b -> b; + case List l -> asList().stream().map( GenericValue::rawJava ).collect( ImmutableList.toImmutableList() ); + case Map m -> + getProperties().stream().collect( ImmutableMap.toImmutableMap( Map.Entry::getKey, e -> e.getValue().rawJava() ) ); + default -> throw new AssertionError( value ); + }; + } + + public Object rawJs() + { + return switch ( value ) + { + case String s -> s; + case Long l -> l.doubleValue(); + case Integer i -> i; + case Double d -> d; + case Boolean b -> b; + case List l -> asList().stream().map( GenericValue::rawJs ).collect( ImmutableList.toImmutableList() ); + case Map m -> + getProperties().stream().collect( ImmutableMap.toImmutableMap( Map.Entry::getKey, e -> e.getValue().rawJs() ) ); + default -> throw new AssertionError( value ); + }; + } + + public Type getType() + { + return switch ( value ) + { + case String s -> Type.STRING; + case Long l -> Type.NUMBER; + case Integer i -> Type.NUMBER; + case Double d -> Type.NUMBER; + case Boolean b -> Type.BOOLEAN; + case List l -> Type.LIST; + case Map m -> Type.OBJECT; + default -> throw new AssertionError( value ); + }; + } + + @SuppressWarnings("unchecked") + private T whenMapOrElse( final Function, T> then, final Supplier orElse ) + { + return value instanceof Map ? then.apply( (Map) value ) : orElse.get(); + } + + @SuppressWarnings("unchecked") + private T whenListOrElse( final Function, T> then, final Supplier orElse ) + { + return value instanceof List ? then.apply( (List) value ) : orElse.get(); + } + + public static GenericValue numberValue( final long value ) + { + return new GenericValue( (int) value == value ? (int) value : value ); + } + + public static GenericValue numberValue( final double value ) + { + return new GenericValue( value ); + } + + public static GenericValue stringValue( final String value ) + { + return new GenericValue( value ); + } + + public static GenericValue booleanValue( final boolean value ) + { + return new GenericValue( value ); + } + + public static GenericValue stringList( final List value ) + { + final var list = list(); + value.stream().map( GenericValue::stringValue ).forEach( list::add ); + return list.build(); + } + + public static ListBuilder list() + { + return new ListBuilder(); + } + + public static ObjectBuilder object() + { + return new ObjectBuilder(); + } + + public enum Type + { + STRING, NUMBER, BOOLEAN, LIST, OBJECT + } + + @Override + public boolean equals( final Object o ) + { + return o instanceof final GenericValue that && Objects.equals( value, that.value ); + } + + @Override + public int hashCode() + { + return Objects.hashCode( value ); + } + + public static final class ListBuilder + { + private final ImmutableList.Builder builder = ImmutableList.builder(); + + private ListBuilder() + { + } + + public ListBuilder add( final GenericValue value ) + { + builder.add( value ); + return this; + } + + public GenericValue build() + { + return new GenericValue( builder.build() ); + } + } + + public static final class ObjectBuilder + { + private final ImmutableMap.Builder builder = ImmutableMap.builder(); + + private ObjectBuilder() + { + } + + public ObjectBuilder put( final String key, final String value ) + { + builder.put( key, GenericValue.stringValue( value ) ); + return this; + } + + public ObjectBuilder put( final String key, final long value ) + { + builder.put( key, GenericValue.numberValue( value ) ); + return this; + } + + public ObjectBuilder put( final String key, final GenericValue value ) + { + builder.put( key, Objects.requireNonNull( value ) ); + return this; + } + + public ObjectBuilder putArray( final String key, final List value ) + { + builder.put( key, GenericValue.stringList( value ) ); + return this; + } + + public GenericValue build() + { + return new GenericValue( ImmutableMap.copyOf( builder.build() ) ); + } + } +} diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/audit/AuditLogParamsTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/audit/AuditLogParamsTest.java index ce811bf333a..4ea6c0f2d3c 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/audit/AuditLogParamsTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/audit/AuditLogParamsTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; class AuditLogParamsTest @@ -25,7 +26,7 @@ void create_only_type() assertEquals( AuditLogTestBuilder.type, params.getType() ); assertNotNull( params.getTime() ); assertNotNull( params.getSource() ); - assertNotNull( params.getUser() ); + assertNull( params.getUser() ); assertNotNull( params.getObjectUris() ); assertNotNull( params.getData() ); } diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/ApplyContentPermissionsParamsTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/ApplyContentPermissionsParamsTest.java index cdb2d237fcc..f53ba07dfe3 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/ApplyContentPermissionsParamsTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/ApplyContentPermissionsParamsTest.java @@ -2,7 +2,6 @@ import org.junit.jupiter.api.Test; -import com.enonic.xp.node.ApplyPermissionsScope; import com.enonic.xp.security.acl.AccessControlList; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -15,7 +14,7 @@ void testCreate() { final ApplyContentPermissionsParams params = ApplyContentPermissionsParams.create() .contentId( ContentId.from( "id1" ) ) - .applyPermissionsScope( ApplyPermissionsScope.TREE ) + .applyPermissionsScope( ApplyContentPermissionsScope.TREE ) .permissions( AccessControlList.create().build() ) .applyContentPermissionsListener( new ApplyPermissionsListener() { @@ -40,7 +39,7 @@ public void notEnoughRights( final int count ) .build(); assertEquals( ContentId.from( "id1" ), params.getContentId() ); - assertEquals( ApplyPermissionsScope.TREE, params.getScope() ); + assertEquals( ApplyContentPermissionsScope.TREE, params.getScope() ); assertEquals( AccessControlList.create().build(), params.getPermissions() ); assertNotNull( params.getListener() ); } diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionDateComparatorTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionDateComparatorTest.java deleted file mode 100644 index c8a94fb0341..00000000000 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionDateComparatorTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.enonic.xp.content; - -import java.time.Instant; - -import org.junit.jupiter.api.Test; - -import com.enonic.xp.security.PrincipalKey; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class ContentVersionDateComparatorTest -{ - @Test - void testComparison() - { - final Instant now1 = Instant.now(); - - final ContentVersion version1 = ContentVersion.create(). - id( ContentVersionId.from( "a" ) ). - modified( now1 ). - timestamp( now1 ). - modifier( PrincipalKey.ofAnonymous() ). - displayName( "contentVersion" ). - comment( "comment" ). - build(); - - final ContentVersion version1Same = ContentVersion.create(). - id( ContentVersionId.from( "a" ) ). - modified( now1 ). - timestamp( now1 ). - modifier( PrincipalKey.ofAnonymous() ). - displayName( "contentVersion" ). - comment( "comment" ). - build(); - - assertEquals( 0, ContentVersionDateComparator.INSTANCE.compare( version1, version1Same ) ); - - final Instant now2 = now1.plusMillis( 1000 ); - - final ContentVersion version2 = ContentVersion.create(). - id( ContentVersionId.from( "b" ) ). - modified( now2 ). - timestamp( now2 ). - modifier( PrincipalKey.ofAnonymous() ). - displayName( "contentVersion" ). - comment( "comment" ). - build(); - - assertEquals( 1, ContentVersionDateComparator.INSTANCE.compare( version1, version2 ) ); - assertEquals( -1, ContentVersionDateComparator.INSTANCE.compare( version2, version1 ) ); - - } -} diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java index 82d3141405d..0ac1c82b5e8 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java @@ -6,12 +6,7 @@ import nl.jqno.equalsverifier.EqualsVerifier; -import com.enonic.xp.index.ChildOrder; import com.enonic.xp.security.PrincipalKey; -import com.enonic.xp.security.RoleKeys; -import com.enonic.xp.security.acl.AccessControlEntry; -import com.enonic.xp.security.acl.AccessControlList; -import com.enonic.xp.security.acl.Permission; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -23,57 +18,20 @@ void testBuilder() final Instant now1 = Instant.now(); final Instant now2 = Instant.now(); - final ContentVersionPublishInfo publishInfo = ContentVersionPublishInfo.create() - .message( "My version 1" ) - .type( ContentVersionPublishInfo.CommitType.ARCHIVED ) - .publisher( PrincipalKey.ofAnonymous() ) - .timestamp( Instant.ofEpochSecond( 1562056003L ) ) - .contentPublishInfo( ContentPublishInfo.create() - .first( Instant.ofEpochSecond( 1562056004L ) ) - .from( Instant.ofEpochSecond( 1562056005L ) ) - .to( Instant.ofEpochSecond( 1562056006L ) ) - .build() ) - .build(); - - assertEquals( ContentVersionPublishInfo.CommitType.ARCHIVED, publishInfo.getType() ); - assertEquals( "My version 1", publishInfo.getMessage() ); - assertEquals( PrincipalKey.ofAnonymous(), publishInfo.getPublisher() ); - assertEquals( Instant.ofEpochSecond( 1562056003L ), publishInfo.getTimestamp() ); - assertEquals( Instant.ofEpochSecond( 1562056004L ), publishInfo.getContentPublishInfo().getFirst() ); - assertEquals( Instant.ofEpochSecond( 1562056005L ), publishInfo.getContentPublishInfo().getFrom() ); - assertEquals( Instant.ofEpochSecond( 1562056006L ), publishInfo.getContentPublishInfo().getTo() ); - - final WorkflowInfo workflowInfo = WorkflowInfo.create().state( WorkflowState.READY ).build(); - - final AccessControlList permissions = AccessControlList.create() - .add( - AccessControlEntry.create().allow( Permission.CREATE, Permission.READ_PERMISSIONS ).principal( RoleKeys.EVERYONE ).build() ) - .build(); - final ContentVersion version = ContentVersion.create() .id( ContentVersionId.from( "a" ) ) .path( ContentPath.from( ContentPath.ROOT, "a" ) ) .modified( now1 ) .timestamp( now2 ) - .childOrder( ChildOrder.manualOrder() ) - .modifier( PrincipalKey.ofAnonymous() ) - .displayName( "contentVersion" ) + .changedBy( PrincipalKey.ofAnonymous() ) .comment( "comment" ) - .publishInfo( publishInfo ) - .workflowInfo( workflowInfo ) - .permissions( permissions ) .build(); assertEquals( ContentVersionId.from( "a" ), version.getId() ); - assertEquals( now1, version.getModified() ); + assertEquals( now1, version.getChangedTime() ); assertEquals( now2, version.getTimestamp() ); assertEquals( "comment", version.getComment() ); - assertEquals( PrincipalKey.ofAnonymous(), version.getModifier() ); - assertEquals( "contentVersion", version.getDisplayName() ); - assertEquals( publishInfo, version.getPublishInfo() ); - assertEquals( workflowInfo, version.getWorkflowInfo() ); - assertEquals( ChildOrder.manualOrder(), version.getChildOrder() ); - assertEquals( permissions, version.getPermissions() ); + assertEquals( PrincipalKey.ofAnonymous(), version.getChangedBy() ); assertEquals( "/a", version.getPath().toString() ); } diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java index d6ad285213c..bb264e80ec0 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java @@ -19,9 +19,7 @@ void testBuilder() final ContentVersion version1 = ContentVersion.create(). id( ContentVersionId.from( "a" ) ). modified( now1 ). - timestamp( now1 ). - modifier( PrincipalKey.ofAnonymous() ). - displayName( "contentVersion" ). + timestamp( now1 ).changedBy( PrincipalKey.ofAnonymous() ). comment( "comment" ). build(); @@ -30,9 +28,7 @@ void testBuilder() final ContentVersion version2 = ContentVersion.create(). id( ContentVersionId.from( "b" ) ). modified( now2 ). - timestamp( now2 ). - modifier( PrincipalKey.ofAnonymous() ). - displayName( "contentVersion" ). + timestamp( now2 ).changedBy( PrincipalKey.ofAnonymous() ). comment( "comment" ). build(); diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsParamsTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsParamsTest.java deleted file mode 100644 index 1bdf7a59333..00000000000 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsParamsTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.enonic.xp.content; - -import org.junit.jupiter.api.Test; - -import com.enonic.xp.branch.Branch; -import com.enonic.xp.branch.Branches; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class GetActiveContentVersionsParamsTest -{ - - private final ContentId contentId = ContentId.from( "a" ); - - @Test - void testEquals() - { - Branch branch = Branch.create().value( "branchName" ).build(); - Branches branches = Branches.from( branch ); - - GetActiveContentVersionsParams params = GetActiveContentVersionsParams.create(). - contentId( contentId ). - branches( branches ). - build(); - - assertEquals( params, params ); - assertEquals( params.getContentId(), contentId ); - assertEquals( params.getBranches().getSet(), branches.getSet() ); - - } - -} diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsResultTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsResultTest.java deleted file mode 100644 index 2bb150e2f4e..00000000000 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/GetActiveContentVersionsResultTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.enonic.xp.content; - -import java.time.Instant; -import java.util.Iterator; - -import org.junit.jupiter.api.Test; - -import com.enonic.xp.branch.Branch; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class GetActiveContentVersionsResultTest -{ - @Test - void same_version() - { - final Instant now = Instant.now(); - - final ContentVersion version = ContentVersion.create(). - id( ContentVersionId.from( "a" ) ). - modified( now ). - timestamp( now ). - build(); - - final Branch draft = Branch.from( "draft" ); - final Branch master = Branch.from( "master" ); - - final GetActiveContentVersionsResult result = GetActiveContentVersionsResult.create(). - add( ActiveContentVersionEntry.from( draft, version ) ). - add( ActiveContentVersionEntry.from( master, version ) ). - build(); - - assertEquals( 2, result.getActiveContentVersions().size() ); - } - - @Test - void skip_null() - { - final Instant now = Instant.now(); - - final ContentVersion version = ContentVersion.create(). - id( ContentVersionId.from( "a" ) ). - modified( now ). - build(); - - final Branch draft = Branch.from( "draft" ); - final Branch master = Branch.from( "master" ); - - final GetActiveContentVersionsResult result = GetActiveContentVersionsResult.create(). - add( ActiveContentVersionEntry.from( draft, version ) ). - add( ActiveContentVersionEntry.from( master, null ) ). - build(); - - assertEquals( 1, result.getActiveContentVersions().size() ); - } - - @Test - void test_ordering() - { - final Instant oldest = Instant.parse( "2014-09-25T10:00:00.00Z" ); - final Instant middle = Instant.parse( "2014-09-25T11:00:00.00Z" ); - final Instant newest = Instant.parse( "2014-09-25T12:00:00.00Z" ); - - final Branch archive = Branch.from( "archive" ); - final Branch draft = Branch.from( "draft" ); - final Branch master = Branch.from( "master" ); - - final ContentVersion oldVersion = ContentVersion.create(). - id( ContentVersionId.from( "b" ) ). - modified( middle ). - timestamp( middle ). - build(); - - final ContentVersion oldestVersion = ContentVersion.create(). - id( ContentVersionId.from( "a" ) ). - modified( oldest ). - timestamp( oldest ). - build(); - - final ContentVersion newVersion = ContentVersion.create(). - id( ContentVersionId.from( "c" ) ). - modified( newest ). - timestamp( newest ). - build(); - - final GetActiveContentVersionsResult result = GetActiveContentVersionsResult.create(). - add( ActiveContentVersionEntry.from( master, oldVersion ) ). - add( ActiveContentVersionEntry.from( draft, newVersion ) ). - add( ActiveContentVersionEntry.from( archive, oldestVersion ) ). - build(); - - final Iterator iterator = result.getActiveContentVersions().iterator(); - - assertEquals( draft, iterator.next().getBranch() ); - assertEquals( master, iterator.next().getBranch() ); - assertEquals( archive, iterator.next().getBranch() ); - } -} diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/data/PropertyTreeTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/data/PropertyTreeTest.java index c27a28d2e79..dbbe6accb78 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/data/PropertyTreeTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/data/PropertyTreeTest.java @@ -467,8 +467,8 @@ void getPropertySet() PropertySet set2 = tree.addSet( "mySet2" ); set1.addLongs( "longs", 1L, 2L ); - assertEquals( set1, tree.getPropertySet( "mySet1" ) ); - assertEquals( set2, tree.getPropertySet( PropertyPath.from( "mySet2" ) ) ); + assertEquals( set1, tree.getSet( "mySet1" ) ); + assertEquals( set2, tree.getSet( PropertyPath.from( "mySet2" ) ) ); } @Test diff --git a/modules/core/core-app/src/test/java/com/enonic/xp/core/impl/app/ApplicationServiceImplTest.java b/modules/core/core-app/src/test/java/com/enonic/xp/core/impl/app/ApplicationServiceImplTest.java index 08531ccf741..7e1b687bb5d 100644 --- a/modules/core/core-app/src/test/java/com/enonic/xp/core/impl/app/ApplicationServiceImplTest.java +++ b/modules/core/core-app/src/test/java/com/enonic/xp/core/impl/app/ApplicationServiceImplTest.java @@ -45,6 +45,7 @@ import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeQuery; import com.enonic.xp.node.NodeService; +import com.enonic.xp.node.NodeVersionId; import com.enonic.xp.node.Nodes; import static org.assertj.core.api.Assertions.assertThat; @@ -180,7 +181,7 @@ void delete_virtual_application() final ApplicationKey appKey = ApplicationKey.from( "app1" ); final DeleteNodeResult result = DeleteNodeResult.create() - .nodeIds( NodeIds.from( NodeId.from( "nodeId" ) ) ) + .add( new DeleteNodeResult.Result(NodeId.from( "nodeId" ), NodeVersionId.from( "nodeVersionId" ) ) ) .build(); when( nodeService.delete( argThat( argument -> new NodePath( "/app1" ).equals( argument.getNodePath() ) ) ) ).thenReturn( result ); @@ -193,7 +194,7 @@ void delete_virtual_application_without_admin() final ApplicationKey appKey = ApplicationKey.from( "app1" ); final DeleteNodeResult result = DeleteNodeResult.create() - .nodeIds( NodeIds.from( NodeId.from( "nodeId" ) ) ) + .add( new DeleteNodeResult.Result(NodeId.from( "nodeId" ), NodeVersionId.from( "nodeVersionId" ) ) ) .build(); when( nodeService.delete( argThat( argument -> new NodePath( "/app1" ).equals( argument.getNodePath() ) ) ) ).thenReturn( result ); diff --git a/modules/core/core-audit/src/main/java/com/enonic/xp/core/impl/audit/serializer/AuditLogSerializer.java b/modules/core/core-audit/src/main/java/com/enonic/xp/core/impl/audit/serializer/AuditLogSerializer.java index c4e97aeb7a6..d7a207f808e 100644 --- a/modules/core/core-audit/src/main/java/com/enonic/xp/core/impl/audit/serializer/AuditLogSerializer.java +++ b/modules/core/core-audit/src/main/java/com/enonic/xp/core/impl/audit/serializer/AuditLogSerializer.java @@ -1,6 +1,7 @@ package com.enonic.xp.core.impl.audit.serializer; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -9,6 +10,7 @@ import com.enonic.xp.audit.AuditLogUri; import com.enonic.xp.audit.AuditLogUris; import com.enonic.xp.audit.LogAuditLogParams; +import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.core.impl.audit.AuditLogConstants; import com.enonic.xp.core.impl.audit.AuditLogPropertyNames; import com.enonic.xp.data.PropertySet; @@ -33,7 +35,13 @@ public static CreateNodeParams.Builder toCreateNodeParams( final LogAuditLogPara data.addString( AuditLogPropertyNames.TYPE, auditLogParams.getType() ); data.addInstant( AuditLogPropertyNames.TIME, auditLogParams.getTime() ); data.addString( AuditLogPropertyNames.SOURCE, auditLogParams.getSource() ); - data.addString( AuditLogPropertyNames.USER, auditLogParams.getUser().toString() ); + + final PrincipalKey userKey = Objects.requireNonNullElseGet( auditLogParams.getUser(), + () -> ContextAccessor.current().getAuthInfo().getUser() != null + ? ContextAccessor.current().getAuthInfo().getUser().getKey() + : PrincipalKey.ofAnonymous() ); + + data.addString( AuditLogPropertyNames.USER, userKey.toString() ); data.addStrings( AuditLogPropertyNames.OBJECTURIS, objectUris ); data.addSet( AuditLogPropertyNames.DATA, auditLogParams.getData().getRoot().copy( data.getTree() ) ); diff --git a/modules/core/core-audit/src/test/java/com/enonic/xp/core/impl/audit/AuditLogServiceImplTest.java b/modules/core/core-audit/src/test/java/com/enonic/xp/core/impl/audit/AuditLogServiceImplTest.java index 8aa9152f0e3..14a4377ca18 100644 --- a/modules/core/core-audit/src/test/java/com/enonic/xp/core/impl/audit/AuditLogServiceImplTest.java +++ b/modules/core/core-audit/src/test/java/com/enonic/xp/core/impl/audit/AuditLogServiceImplTest.java @@ -1,5 +1,7 @@ package com.enonic.xp.core.impl.audit; +import java.util.Objects; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.invocation.InvocationOnMock; @@ -28,8 +30,10 @@ import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodeQuery; import com.enonic.xp.node.NodeService; +import com.enonic.xp.node.NodeVersionId; import com.enonic.xp.node.Nodes; import com.enonic.xp.repository.RepositoryService; +import com.enonic.xp.security.PrincipalKey; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -240,8 +244,7 @@ private void assertLog( AuditLog log ) assertEquals( auditLogParams.getTime(), log.getTime() ); assertNotNull( log.getSource() ); assertEquals( auditLogParams.getSource(), log.getSource() ); - assertNotNull( log.getUser() ); - assertEquals( auditLogParams.getUser(), log.getUser() ); + assertEquals( Objects.requireNonNullElse( auditLogParams.getUser(), PrincipalKey.ofAnonymous()), log.getUser() ); assertNotNull( log.getObjectUris() ); assertEquals( 2, log.getObjectUris().getSize() ); assertEquals( auditLogParams.getObjectUris(), log.getObjectUris() ); @@ -252,7 +255,8 @@ private void assertLog( AuditLog log ) private static DeleteNodeResult answerDeleted( InvocationOnMock answer ) { return DeleteNodeResult.create() - .nodeIds( NodeIds.from( answer.getArgument( 0, DeleteNodeParams.class ).getNodeId() ) ) + .add( new DeleteNodeResult.Result( answer.getArgument( 0, DeleteNodeParams.class ).getNodeId(), + NodeVersionId.from( "nodeVersionId" ) ) ) .build(); } } diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractContentCommand.java index 7ed94ffdbf4..d250b23f1ef 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractContentCommand.java @@ -36,6 +36,7 @@ import com.enonic.xp.schema.content.ContentTypeName; import com.enonic.xp.schema.content.ContentTypeService; import com.enonic.xp.schema.content.GetContentTypeParams; +import com.enonic.xp.security.PrincipalKey; abstract class AbstractContentCommand { @@ -165,6 +166,13 @@ protected Filters createFilters() return Filters.from(); } + static PrincipalKey getCurrentUserKey() + { + final Context context = ContextAccessor.current(); + + return context.getAuthInfo().getUser() != null ? context.getAuthInfo().getUser().getKey() : PrincipalKey.ofAnonymous(); + } + protected T runAsAdmin( final Callable callable ) { return ContextBuilder.from( ContextAccessor.current() ) @@ -284,5 +292,4 @@ void validate() Objects.requireNonNull( translator ); } } - } diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractCreatingOrUpdatingContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractCreatingOrUpdatingContentCommand.java index 8932b1204ed..9d00a83fb71 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractCreatingOrUpdatingContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/AbstractCreatingOrUpdatingContentCommand.java @@ -41,7 +41,6 @@ import com.enonic.xp.schema.xdata.XData; import com.enonic.xp.schema.xdata.XDataName; import com.enonic.xp.schema.xdata.XDataService; -import com.enonic.xp.security.User; import com.enonic.xp.security.auth.AuthenticationInfo; import com.enonic.xp.site.SiteConfig; import com.enonic.xp.site.SiteConfigService; @@ -178,13 +177,6 @@ void validateCreateAttachments( final CreateAttachments createAttachments ) } } - User getCurrentUser() - { - final Context context = ContextAccessor.current(); - - return context.getAuthInfo().getUser() != null ? context.getAuthInfo().getUser() : User.ANONYMOUS; - } - protected boolean isBinaryContentType( final String contentType ) { final MediaType mediaType = MediaType.parse( contentType ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java index d168274a5ec..64b7c0262a5 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java @@ -10,10 +10,12 @@ import com.enonic.xp.node.ApplyNodePermissionsListener; import com.enonic.xp.node.ApplyNodePermissionsParams; import com.enonic.xp.node.ApplyNodePermissionsResult; +import com.enonic.xp.node.ApplyPermissionsScope; +import com.enonic.xp.node.CommitNodeParams; +import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.RoutableNodeVersionId; -import com.enonic.xp.node.RoutableNodeVersionIds; +import com.enonic.xp.node.NodeVersionIds; final class ApplyContentPermissionsCommand @@ -36,7 +38,7 @@ ApplyContentPermissionsResult execute() .permissions( params.getPermissions() ) .addPermissions( params.getAddPermissions() ) .removePermissions( params.getRemovePermissions() ) - .scope( params.getScope() ) + .scope( Enum.valueOf( ApplyPermissionsScope.class, params.getScope().name() ) ) .addBranches( Branches.from( ContentConstants.BRANCH_MASTER, ContentConstants.BRANCH_DRAFT ) ); if ( params.getListener() != null ) @@ -44,6 +46,9 @@ ApplyContentPermissionsResult execute() applyNodePermissionsBuilder.applyPermissionsListener( new ListenerDelegate( params.getListener() ) ); } + applyNodePermissionsBuilder.versionAttributes( + ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.PERMISSIONS_KEY ) ); + final ApplyNodePermissionsResult result = nodeService.applyPermissions( applyNodePermissionsBuilder.build() ); commitResult( result ); @@ -66,9 +71,15 @@ ApplyContentPermissionsResult execute() private void commitResult( final ApplyNodePermissionsResult result ) { - final RoutableNodeVersionIds versionIdsToCommit = result.getResults() + final NodeVersionIds versionIdsToCommit = result.getResults() .entrySet() .stream() + .flatMap( Collection::stream ) + .filter( branchResult -> ContentConstants.BRANCH_MASTER.equals( branchResult.branch() ) ) + .map( ApplyNodePermissionsResult.BranchResult::node ) + .filter( Objects::nonNull ) + .map( Node::getNodeVersionId ) + .collect( NodeVersionIds.collector() ); .flatMap( entry -> entry.getValue() .stream() .filter( br -> ContentConstants.BRANCH_MASTER.equals( br.branch() ) ) @@ -78,8 +89,11 @@ private void commitResult( final ApplyNodePermissionsResult result ) if ( !versionIdsToCommit.isEmpty() ) { - nodeService.commit( NodeCommitEntry.create().message( ContentConstants.APPLY_PERMISSIONS_COMMIT_PREFIX ).build(), - versionIdsToCommit ); + nodeService.commit( CommitNodeParams.create() + .nodeCommitEntry( + NodeCommitEntry.create().message( ContentConstants.APPLY_PERMISSIONS_COMMIT_PREFIX ).build() ) + .nodeVersionIds( versionIdsToCommit ) + .build() ); } } @@ -88,7 +102,7 @@ public static Builder create( final ApplyContentPermissionsParams params ) return new Builder( params ); } - public static class Builder + static class Builder extends AbstractContentCommand.Builder { private final ApplyContentPermissionsParams params; @@ -104,7 +118,7 @@ void validate() super.validate(); } - public ApplyContentPermissionsCommand build() + ApplyContentPermissionsCommand build() { validate(); return new ApplyContentPermissionsCommand( this ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ArchiveContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ArchiveContentCommand.java index c340ce10875..64d17058420 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ArchiveContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ArchiveContentCommand.java @@ -9,14 +9,12 @@ import com.enonic.xp.archive.ArchiveContentException; import com.enonic.xp.archive.ArchiveContentParams; import com.enonic.xp.archive.ArchiveContentsResult; -import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentIds; import com.enonic.xp.content.ContentPath; import com.enonic.xp.content.UnpublishContentParams; -import com.enonic.xp.context.Context; -import com.enonic.xp.context.ContextAccessor; +import com.enonic.xp.node.CommitNodeParams; import com.enonic.xp.node.FindNodesByParentParams; import com.enonic.xp.node.MoveNodeException; import com.enonic.xp.node.MoveNodeParams; @@ -29,11 +27,9 @@ import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodeName; import com.enonic.xp.node.NodePath; +import com.enonic.xp.node.NodeVersionIds; import com.enonic.xp.node.Nodes; import com.enonic.xp.node.RefreshMode; -import com.enonic.xp.node.RoutableNodeVersionId; -import com.enonic.xp.node.RoutableNodeVersionIds; -import com.enonic.xp.security.User; import static com.enonic.xp.content.ContentPropertyNames.ARCHIVED_BY; import static com.enonic.xp.content.ContentPropertyNames.ARCHIVED_TIME; @@ -71,7 +67,7 @@ ArchiveContentsResult execute() } catch ( NodeAccessException e ) { - throw new ContentAccessException( e ); + throw ContentNodeHelper.toContentAccessException( e ); } } @@ -121,7 +117,7 @@ private ContentIds unpublish( final ContentId contentId, final ContentIds descen private NodeDataProcessor updateProperties( final ContentPath originalPath ) { final Instant now = Instant.now(); - final String archivedBy = getCurrentUser().getKey().toString(); + final String archivedBy = getCurrentUserKey().toString(); return ( data, nodePath ) -> { var toBeEdited = data.copy(); @@ -138,15 +134,14 @@ private NodeDataProcessor updateProperties( final ContentPath originalPath ) private void commit( final Nodes nodes ) { - final RoutableNodeVersionIds routableNodeVersionIds = nodes.stream() - .map( n -> RoutableNodeVersionId.from( n.id(), n.getNodeVersionId() ) ) - .collect( RoutableNodeVersionIds.collector() ); - final String commitEntryMessage = params.getMessage() == null ? ContentConstants.ARCHIVE_COMMIT_PREFIX : String.join( ContentConstants.ARCHIVE_COMMIT_PREFIX_DELIMITER, ContentConstants.ARCHIVE_COMMIT_PREFIX, params.getMessage() ); - nodeService.commit( NodeCommitEntry.create().message( commitEntryMessage ).build(), routableNodeVersionIds ); + nodeService.commit( CommitNodeParams.create() + .nodeCommitEntry( NodeCommitEntry.create().message( commitEntryMessage ).build() ) + .nodeVersionIds( nodes.stream().map( Node::getNodeVersionId ).collect( NodeVersionIds.collector() ) ) + .build() ); } private MoveNodeResult rename( final Node node ) @@ -177,6 +172,8 @@ private MoveNodeResult rename( final Node node ) } moveParams.processor( processors.build() ); + moveParams.versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.ARCHIVE_KEY ) ); + return nodeService.move( moveParams.build() ); } @@ -189,12 +186,6 @@ private void validateLocation( final Node node ) } } - private User getCurrentUser() - { - final Context context = ContextAccessor.current(); - return context.getAuthInfo().getUser() != null ? context.getAuthInfo().getUser() : User.ANONYMOUS; - } - public static class Builder extends AbstractContentCommand.Builder { diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareContentsCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareContentsCommand.java index 83c1966767a..c616aca7a71 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareContentsCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareContentsCommand.java @@ -29,10 +29,7 @@ public static Builder create() public CompareContentResults execute() { - final NodeIds nodeIds = ContentNodeHelper.toNodeIds( this.contentIds ); - final NodeComparisons comparisons = this.nodeService.compare( nodeIds, this.target ); - - return CompareResultTranslator.translate( comparisons ); + return CompareResultTranslator.translate( this.nodeService.compare( ContentNodeHelper.toNodeIds( this.contentIds ), this.target ) ); } public static final class Builder diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareResultTranslator.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareResultTranslator.java index e7c3072e89a..ebaed527e88 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareResultTranslator.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CompareResultTranslator.java @@ -2,6 +2,7 @@ import com.enonic.xp.content.CompareContentResult; import com.enonic.xp.content.CompareContentResults; +import com.enonic.xp.content.CompareStatus; import com.enonic.xp.content.ContentId; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeComparisons; @@ -14,7 +15,8 @@ public static CompareContentResults translate( final NodeComparisons nodeCompari for ( final NodeComparison nodeComparison : nodeComparisons ) { - builder.add( new CompareContentResult( nodeComparison.getCompareStatus(), ContentId.from( nodeComparison.getNodeId() ) ) ); + builder.add( new CompareContentResult( Enum.valueOf( CompareStatus.class, nodeComparison.getCompareStatus().name() ), + ContentId.from( nodeComparison.getNodeId() ) ) ); } return builder.build(); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java new file mode 100644 index 00000000000..533a0ea8077 --- /dev/null +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java @@ -0,0 +1,108 @@ +package com.enonic.xp.core.impl.content; + +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; + +import com.enonic.xp.content.Content; +import com.enonic.xp.context.Context; +import com.enonic.xp.context.ContextAccessor; +import com.enonic.xp.node.Attributes; +import com.enonic.xp.security.PrincipalKey; +import com.enonic.xp.util.GenericValue; + +public class ContentAttributesHelper +{ + public static final String USER_PROPERTY = "user"; + + public static final String OPTIME_PROPERTY = "optime"; + + public static final String CREATE_KEY = "content.create"; + + public static final String DUPLICATE_KEY = "content.duplicate"; + + public static final String IMPORT_KEY = "content.import"; + + public static final String UPDATE_KEY = "content.publish"; + + public static final String PERMISSIONS_KEY = "content.permissions"; + + public static final String MOVE_KEY = "content.move"; + + public static final String SORT_KEY = "content.sort"; + + public static final String PATCH_KEY = "content.patch"; + + public static final String ARCHIVE_KEY = "content.archive"; + + public static final String RESTORE_KEY = "content.restore"; + + public static final String PUBLISH_KEY = "content.publish"; + + public static final String UNPUBLISH_KEY = "content.unpublish"; + + public static final Set CHANGE_KEYS = + Set.of( CREATE_KEY, DUPLICATE_KEY, IMPORT_KEY, UPDATE_KEY, PERMISSIONS_KEY, MOVE_KEY, SORT_KEY, PATCH_KEY, ARCHIVE_KEY, + RESTORE_KEY ); + + private static final Clock MILLIS_CLOCK = Clock.tick( Clock.systemUTC(), Duration.ofMillis( 1 ) ); + + private static final Map> FIELD_GETTERS = + Map.of( "displayName", Content::getDisplayName, "data", Content::getData, "x", Content::getAllExtraData, "page", Content::getPage, + "owner", Content::getOwner, "language", Content::getLanguage, "publish", Content::getPublishInfo, "workflow", + Content::getWorkflowInfo, "variantOf", Content::getVariantOf, "attachments", Content::getAttachments ); + + public static List modifiedFields( Content existingContent, Content updatedContent ) + { + return FIELD_GETTERS.entrySet() + .stream() + .filter( e -> !Objects.equals( e.getValue().apply( existingContent ), e.getValue().apply( updatedContent ) ) ) + .map( Map.Entry::getKey ) + .sorted() + .toList(); + } + + public static Attributes versionHistoryAttr( final String key ) + { + return Attributes.create() + .attribute( key ) + .put( USER_PROPERTY, getCurrentUserKey().toString() ) + .put( OPTIME_PROPERTY, Instant.now( MILLIS_CLOCK ).toString() ) + .end() + .build(); + } + + public static Attributes updateVersionHistoryAttr( Content existingContent, Content updatedContent ) + { + return Attributes.create() + .attribute( UPDATE_KEY ) + .putArray( "fields", ContentAttributesHelper.modifiedFields( existingContent, updatedContent ) ) + .put( USER_PROPERTY, getCurrentUserKey().toString() ) + .put( OPTIME_PROPERTY, Instant.now( MILLIS_CLOCK ).toString() ) + .end() + .build(); + } + + public static Instant getOpTime( final GenericValue attribute ) + { + return Instant.parse( attribute.property( ContentAttributesHelper.OPTIME_PROPERTY ).asString() ); + } + + public static PrincipalKey getUser( final GenericValue attribute ) + { + return PrincipalKey.from( attribute.property( ContentAttributesHelper.USER_PROPERTY ).asString() ); + } + + static PrincipalKey getCurrentUserKey() + { + final Context context = ContextAccessor.current(); + + return context.getAuthInfo().getUser() != null ? context.getAuthInfo().getUser().getKey() : PrincipalKey.ofAnonymous(); + } + +} diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAuditLogSupportImpl.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAuditLogSupportImpl.java index 9f4ad1d7394..4bd1c416fda 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAuditLogSupportImpl.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAuditLogSupportImpl.java @@ -280,14 +280,11 @@ private void doPublish( final PushContentParams params, final PublishContentResu params.getExcludedContentIds().stream().map( ContentId::toString ).collect( Collectors.toList() ) ); paramsSet.addStrings( "excludeDescendantsOf", params.getExcludeDescendantsOf().stream().map( ContentId::toString ).collect( Collectors.toList() ) ); - if ( params.getContentPublishInfo() != null ) - { - final ContentPublishInfo contentPublishInfo = params.getContentPublishInfo(); - final PropertySet contentPublishInfoSet = paramsSet.addSet( "contentPublishInfo" ); - contentPublishInfoSet.addInstant( "from", contentPublishInfo.getFrom() ); - contentPublishInfoSet.addInstant( "to", contentPublishInfo.getTo() ); - contentPublishInfoSet.addInstant( "first", contentPublishInfo.getFirst() ); - } + + final PropertySet contentPublishInfoSet = paramsSet.addSet( "contentPublishInfo" ); + contentPublishInfoSet.addInstant( "from", params.getPublishFrom() ); + contentPublishInfoSet.addInstant( "to", params.getPublishTo() ); + paramsSet.addString( "message", params.getMessage() ); paramsSet.addBoolean( "includeDependencies", params.isIncludeDependencies() ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentNodeHelper.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentNodeHelper.java index 0c93d099045..ee73d951bca 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentNodeHelper.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentNodeHelper.java @@ -2,6 +2,7 @@ import java.util.Objects; +import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentIds; @@ -9,6 +10,7 @@ import com.enonic.xp.content.ContentPath; import com.enonic.xp.content.ContentPaths; import com.enonic.xp.context.ContextAccessor; +import com.enonic.xp.node.NodeAccessException; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodeName; @@ -90,6 +92,11 @@ public static NodePath getContentRoot() return Objects.requireNonNullElse( (NodePath) ContextAccessor.current().getAttribute( CONTENT_ROOT_PATH_ATTRIBUTE ), ContentConstants.CONTENT_ROOT_PATH ); } + + public static ContentAccessException toContentAccessException( NodeAccessException nodeAccessException) { + throw new ContentAccessException( nodeAccessException, nodeAccessException.getUser(), ContentNodeHelper.translateNodePathToContentPath( nodeAccessException.getNodePath() ), + nodeAccessException.getPermission() ); + } } diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentServiceImpl.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentServiceImpl.java index 835c70ffd4f..b7805ba2300 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentServiceImpl.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentServiceImpl.java @@ -24,7 +24,6 @@ import com.enonic.xp.content.CompareContentResults; import com.enonic.xp.content.CompareContentsParams; import com.enonic.xp.content.Content; -import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentDependencies; import com.enonic.xp.content.ContentId; @@ -54,8 +53,6 @@ import com.enonic.xp.content.FindContentPathsByQueryResult; import com.enonic.xp.content.FindContentVersionsParams; import com.enonic.xp.content.FindContentVersionsResult; -import com.enonic.xp.content.GetActiveContentVersionsParams; -import com.enonic.xp.content.GetActiveContentVersionsResult; import com.enonic.xp.content.GetContentByIdsParams; import com.enonic.xp.content.GetPublishStatusResult; import com.enonic.xp.content.GetPublishStatusesParams; @@ -71,7 +68,6 @@ import com.enonic.xp.content.PublishStatus; import com.enonic.xp.content.PushContentParams; import com.enonic.xp.content.RenameContentParams; -import com.enonic.xp.content.ReorderChildContentParams; import com.enonic.xp.content.ResolvePublishDependenciesParams; import com.enonic.xp.content.ResolveRequiredDependenciesParams; import com.enonic.xp.content.SortContentParams; @@ -90,14 +86,9 @@ import com.enonic.xp.form.FormDefaultValuesProcessor; import com.enonic.xp.media.MediaInfoService; import com.enonic.xp.node.Node; -import com.enonic.xp.node.NodeAccessException; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeService; -import com.enonic.xp.node.RefreshMode; -import com.enonic.xp.node.ReorderChildNodeParams; -import com.enonic.xp.node.SortNodeParams; -import com.enonic.xp.node.SortNodeResult; import com.enonic.xp.page.PageDefaultValuesProcessor; import com.enonic.xp.page.PageDescriptorService; import com.enonic.xp.project.ProjectService; @@ -360,7 +351,8 @@ public PublishContentResult publish( final PushContentParams params ) .eventPublisher( this.eventPublisher ) .contentIds( params.getContentIds() ) .excludedContentIds( params.getExcludedContentIds() ) - .contentPublishInfo( params.getContentPublishInfo() ) + .publishFrom( params.getPublishFrom() ) + .publishTo( params.getPublishTo() ) .excludeDescendantsOf( params.getExcludeDescendantsOf() ) .includeDependencies( params.isIncludeDependencies() ) .pushListener( params.getPublishContentListener() ) @@ -785,65 +777,21 @@ public FindContentVersionsResult getVersions( final FindContentVersionsParams pa } @Override - public GetActiveContentVersionsResult getActiveVersions( final GetActiveContentVersionsParams params ) + public SortContentResult sort( final SortContentParams params ) { - return GetActiveContentVersionsCommand.create() + verifyContextBranch( ContentConstants.BRANCH_DRAFT ); + + final SortContentResult result = SortContentCommand.create( params ) .nodeService( this.nodeService ) .contentTypeService( this.contentTypeService ) .translator( this.translator ) .eventPublisher( this.eventPublisher ) - .contentId( params.getContentId() ) - .branches( params.getBranches() ) .build() .execute(); - } - - @Override - public SortContentResult sort( final SortContentParams params ) - { - verifyContextBranch( ContentConstants.BRANCH_DRAFT ); - try - { - final SortNodeParams.Builder paramsBuilder = SortNodeParams.create() - .nodeId( NodeId.from( params.getContentId() ) ) - .refresh( RefreshMode.ALL ) - .childOrder( params.getChildOrder() ) - .manualOrderSeed( params.getManualOrderSeed() ); + contentAuditLogSupport.sort( params, result ); - for ( final ReorderChildContentParams param : params.getReorderChildContents() ) - { - paramsBuilder.addManualOrder( ReorderChildNodeParams.create() - .nodeId( NodeId.from( param.getContentToMove() ) ) - .moveBefore( param.getContentToMoveBefore() == null - ? null - : NodeId.from( param.getContentToMoveBefore() ) ) - .build() ); - } - - if ( params.stopInherit() ) - { - paramsBuilder.processor( InheritedContentDataProcessor.SORT ); - } - - final SortNodeResult sortNodeResult = nodeService.sort( paramsBuilder.build() ); - - final Content content = translator.fromNode( sortNodeResult.getNode() ); - - final SortContentResult result = SortContentResult.create() - .content( content ) - .movedChildren( - sortNodeResult.getReorderedNodes().stream().map( Node::id ).map( ContentId::from ).collect( ContentIds.collector() ) ) - .build(); - - contentAuditLogSupport.sort( params, result ); - - return result; - } - catch ( NodeAccessException e ) - { - throw new ContentAccessException( e ); - } + return result; } @Override @@ -1007,16 +955,6 @@ public ImportContentResult importContent( final ImportContentParams params ) .execute(); } - private static void verifyContextBranch( final Branch branch ) - { - final Branch contextBranch = ContextAccessor.current().getBranch(); - - if ( !branch.equals( contextBranch ) ) - { - throw new IllegalStateException( String.format( "Branch must be %s", branch ) ); - } - } - @Override public PatchContentResult patch( final PatchContentParams params ) { @@ -1045,6 +983,16 @@ public PatchContentResult patch( final PatchContentParams params ) return result; } + private static void verifyContextBranch( final Branch branch ) + { + final Branch contextBranch = ContextAccessor.current().getBranch(); + + if ( !branch.equals( contextBranch ) ) + { + throw new IllegalStateException( String.format( "Branch must be %s", branch ) ); + } + } + @Reference public void setContentTypeService( final ContentTypeService contentTypeService ) { diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentVersionFactory.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentVersionFactory.java deleted file mode 100644 index 9d891b31455..00000000000 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentVersionFactory.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.enonic.xp.core.impl.content; - -import com.enonic.xp.content.ContentConstants; -import com.enonic.xp.content.ContentPropertyNames; -import com.enonic.xp.content.ContentPublishInfo; -import com.enonic.xp.content.ContentVersion; -import com.enonic.xp.content.ContentVersionId; -import com.enonic.xp.content.ContentVersionPublishInfo; -import com.enonic.xp.content.WorkflowInfo; -import com.enonic.xp.core.impl.content.serializer.PublishInfoSerializer; -import com.enonic.xp.core.impl.content.serializer.WorkflowInfoSerializer; -import com.enonic.xp.data.PropertySet; -import com.enonic.xp.data.PropertyTree; -import com.enonic.xp.node.NodeCommitEntry; -import com.enonic.xp.node.NodeCommitId; -import com.enonic.xp.node.NodeService; -import com.enonic.xp.node.NodeVersion; -import com.enonic.xp.node.NodeVersionMetadata; -import com.enonic.xp.security.PrincipalKey; - -class ContentVersionFactory -{ - private final NodeService nodeService; - - private final WorkflowInfoSerializer workflowInfoSerializer = new WorkflowInfoSerializer(); - - private final PublishInfoSerializer publishInfoSerializer = new PublishInfoSerializer(); - - ContentVersionFactory( final NodeService nodeService ) - { - this.nodeService = nodeService; - } - - public ContentVersion create( final NodeVersionMetadata nodeVersionMetadata ) - { - final NodeVersion nodeVersion = nodeService.getByNodeVersionKey( nodeVersionMetadata.getNodeVersionKey() ); - return doCreateContentVersion( nodeVersionMetadata, nodeVersion ); - } - - private ContentVersion doCreateContentVersion( final NodeVersionMetadata nodeVersionMetadata, final NodeVersion nodeVersion ) - { - final PropertyTree data = nodeVersion.getData(); - - return ContentVersion.create() - .displayName( data.getProperty( ContentPropertyNames.DISPLAY_NAME ).getString() ) - .path( ContentNodeHelper.translateNodePathToContentPath( nodeVersionMetadata.getNodePath() ) ) - .comment( "No comments" ) - .modified( data.getProperty( ContentPropertyNames.MODIFIED_TIME ).getInstant() ) - .timestamp( nodeVersionMetadata.getTimestamp() ) - .childOrder( nodeVersion.getChildOrder() ) - .modifier( PrincipalKey.from( data.getProperty( ContentPropertyNames.MODIFIER ).getString() ) ) - .id( ContentVersionId.from( nodeVersionMetadata.getNodeVersionId().toString() ) ) - .publishInfo( doCreateContentVersionPublishInfo( nodeVersionMetadata.getNodeCommitId(), data.getRoot() ) ) - .workflowInfo( doCreateContentVersionWorkflowInfo( data.getRoot() ) ) - .permissions( nodeVersion.getPermissions() ) - .build(); - } - - private ContentVersionPublishInfo doCreateContentVersionPublishInfo( final NodeCommitId nodeCommitId, - final PropertySet nodeVersionData ) - { - if ( nodeCommitId != null ) - { - final NodeCommitEntry nodeCommitEntry = nodeService.getCommit( nodeCommitId ); - - if ( nodeCommitEntry != null ) - { - final ContentVersionPublishInfo.Builder builder = ContentVersionPublishInfo.create() - .message( getMessage( nodeCommitEntry ) ) - .type( getType( nodeCommitEntry ) ) - .publisher( nodeCommitEntry.getCommitter() ) - .timestamp( nodeCommitEntry.getTimestamp() ); - - if ( nodeCommitEntry.getMessage().startsWith( ContentConstants.PUBLISH_COMMIT_PREFIX ) || - nodeCommitEntry.getMessage().startsWith( ContentConstants.UNPUBLISH_COMMIT_PREFIX ) ) - { - final ContentPublishInfo contentPublishInfo = publishInfoSerializer.serialize( nodeVersionData ); - - if ( contentPublishInfo != null ) - { - builder.contentPublishInfo( contentPublishInfo ); - } - } - - return builder.build(); - } - } - return null; - } - - private WorkflowInfo doCreateContentVersionWorkflowInfo( final PropertySet nodeVersionData ) - { - final PropertySet workflowInfoSet = nodeVersionData.getPropertySet( ContentPropertyNames.WORKFLOW_INFO ); - return workflowInfoSerializer.extract( workflowInfoSet ); - } - - private String getMessage( final NodeCommitEntry nodeCommitEntry ) - { - if ( nodeCommitEntry.getMessage() - .startsWith( ContentConstants.PUBLISH_COMMIT_PREFIX + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER ) ) - { - return nodeCommitEntry.getMessage() - .substring( ContentConstants.PUBLISH_COMMIT_PREFIX.length() + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER.length() ); - } - - if ( nodeCommitEntry.getMessage() - .startsWith( ContentConstants.ARCHIVE_COMMIT_PREFIX + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER ) ) - { - return nodeCommitEntry.getMessage() - .substring( ContentConstants.ARCHIVE_COMMIT_PREFIX.length() + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER.length() ); - } - - return null; - } - - private ContentVersionPublishInfo.CommitType getType( final NodeCommitEntry nodeCommitEntry ) - { - if ( nodeCommitEntry.getMessage().startsWith( ContentConstants.PUBLISH_COMMIT_PREFIX ) ) - { - return ContentVersionPublishInfo.CommitType.PUBLISHED; - } - - if ( nodeCommitEntry.getMessage().startsWith( ContentConstants.UNPUBLISH_COMMIT_PREFIX ) ) - { - return ContentVersionPublishInfo.CommitType.UNPUBLISHED; - } - - if ( nodeCommitEntry.getMessage().startsWith( ContentConstants.ARCHIVE_COMMIT_PREFIX ) ) - { - return ContentVersionPublishInfo.CommitType.ARCHIVED; - } - - if ( nodeCommitEntry.getMessage().startsWith( ContentConstants.RESTORE_COMMIT_PREFIX ) ) - { - return ContentVersionPublishInfo.CommitType.RESTORED; - } - - return ContentVersionPublishInfo.CommitType.CUSTOM; - } - -} diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateContentCommand.java index 3d7d306175b..392f006e182 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateContentCommand.java @@ -5,7 +5,6 @@ import java.util.Objects; import com.enonic.xp.content.Content; -import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentAlreadyExistsException; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentDataValidationException; @@ -110,6 +109,7 @@ private Content doExecute() .siteService( this.siteService ) .build() .produce() + .versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.CREATE_KEY ) ) .refresh( params.isRefresh() ? RefreshMode.ALL : RefreshMode.STORAGE ) .build(); @@ -126,7 +126,7 @@ private Content doExecute() } catch ( NodeAccessException e ) { - throw new ContentAccessException( e ); + throw ContentNodeHelper.toContentAccessException( e ); } return translator.fromNode( createdNode ); @@ -152,11 +152,11 @@ private void validateContentType( final ContentType contentType ) { if ( contentType == null ) { - throw new IllegalArgumentException( "Content type not found [" + params.getType().toString() + "]" ); + throw new IllegalArgumentException( "Content type not found [" + params.getType() + "]" ); } if ( contentType.isAbstract() ) { - throw new IllegalArgumentException( "Cannot create content with an abstract type [" + params.getType().toString() + "]" ); + throw new IllegalArgumentException( "Cannot create content with an abstract type [" + params.getType() + "]" ); } } @@ -194,7 +194,7 @@ private CreateContentTranslatorParams createContentTranslatorParams( final Proce final CreateContentParams processedContent = processedResult.getCreateContentParams(); final CreateContentTranslatorParams.Builder builder = CreateContentTranslatorParams.create( processedContent ) .processedIds( processedResult.getProcessedReferences() ) - .creator( getCurrentUser().getKey() ) + .creator( getCurrentUserKey() ) .owner( getDefaultOwner( processedContent ) ); populateName( builder ); builder.childOrder( Objects.requireNonNullElse( this.params.getChildOrder(), ContentConstants.DEFAULT_CHILD_ORDER ) ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateNodeParamsFactory.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateNodeParamsFactory.java index 22ad18b0b47..c3699e3f245 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateNodeParamsFactory.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/CreateNodeParamsFactory.java @@ -9,7 +9,6 @@ import com.enonic.xp.content.ExtraDatas; import com.enonic.xp.core.impl.content.index.ContentIndexConfigFactory; import com.enonic.xp.core.impl.content.serializer.ContentDataSerializer; -import com.enonic.xp.data.PropertyPath; import com.enonic.xp.data.PropertySet; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.index.IndexConfigDocument; @@ -63,12 +62,12 @@ public CreateNodeParams.Builder produce() { final PropertyTree contentAsData = contentDataSerializer.toCreateNodeData( params ); - final PropertySet extraDataSet = contentAsData.getPropertySet( PropertyPath.from( ContentPropertyNames.EXTRA_DATA ) ); + final PropertySet extraDataSet = contentAsData.getSet( ContentPropertyNames.EXTRA_DATA ); - final String language = contentAsData.getString( PropertyPath.from( ContentPropertyNames.LANGUAGE ) ); + final String language = contentAsData.getString( ContentPropertyNames.LANGUAGE ); final SiteConfigs siteConfigs = - SiteConfigsDataSerializer.fromData( contentAsData.getPropertySet( PropertyPath.from( ContentPropertyNames.DATA ) ) ); + SiteConfigsDataSerializer.fromData( contentAsData.getSet( ContentPropertyNames.DATA ) ); final Page page = contentAsData.hasProperty( COMPONENTS ) ? contentDataSerializer.fromPageData( contentAsData.getRoot() ) : null; diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DeleteContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DeleteContentCommand.java index e5658fe1a4d..e6888cbb8ef 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DeleteContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DeleteContentCommand.java @@ -3,7 +3,6 @@ import java.util.Objects; -import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentIds; import com.enonic.xp.content.ContentNotFoundException; @@ -47,7 +46,7 @@ DeleteContentsResult execute() } catch ( NodeAccessException e ) { - throw new ContentAccessException( e ); + throw ContentNodeHelper.toContentAccessException( e ); } } @@ -117,7 +116,7 @@ private ContentIds unpublish( final ContentId contentId, final ContentIds descen .getUnpublishedContents(); } - public static class Builder + static class Builder extends AbstractContentCommand.Builder { private DeleteContentParams params; @@ -135,7 +134,7 @@ void validate() Objects.requireNonNull( params, "params cannot be null" ); } - public DeleteContentCommand build() + DeleteContentCommand build() { validate(); return new DeleteContentCommand( this ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DuplicateContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DuplicateContentCommand.java index 2241b519f79..d7834e921ca 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DuplicateContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/DuplicateContentCommand.java @@ -11,8 +11,7 @@ import com.enonic.xp.content.DuplicateContentsResult; import com.enonic.xp.node.DuplicateNodeListener; import com.enonic.xp.node.DuplicateNodeParams; -import com.enonic.xp.node.FindNodesByParentParams; -import com.enonic.xp.node.FindNodesByParentResult; +import com.enonic.xp.node.DuplicateNodeResult; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.RefreshMode; @@ -49,11 +48,11 @@ private DuplicateContentsResult doExecute() { final Node sourceNode = nodeService.getById( NodeId.from( params.getContentId() ) ); - final Node duplicatedNode = nodeService.duplicate( createDuplicateNodeParams( sourceNode ) ); + final DuplicateNodeResult duplicatedNode = nodeService.duplicate( createDuplicateNodeParams( sourceNode ) ); - final Content duplicatedContent = translator.fromNode( duplicatedNode ); + final Content duplicatedContent = translator.fromNode( duplicatedNode.getNode() ); - final ContentIds childrenIds = params.getIncludeChildren() ? getAllChildren( duplicatedContent ) : ContentIds.empty(); + final ContentIds childrenIds = ContentNodeHelper.toContentIds( duplicatedNode.getChildren().getIds() ); return DuplicateContentsResult.create() .setSourceContentPath( ContentNodeHelper.translateNodePathToContentPath( sourceNode.path() ) ) @@ -71,6 +70,7 @@ private DuplicateNodeParams createDuplicateNodeParams( final Node sourceNode ) final DuplicateNodeParams.Builder builder = DuplicateNodeParams.create() .nodeId( sourceNode.id() ) + .versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.DUPLICATE_KEY ) ) .dataProcessor( new DuplicateContentProcessor( params.getWorkflowInfo(), sourceNodeId ) ) .refresh( RefreshMode.SEARCH ); @@ -89,15 +89,7 @@ private DuplicateNodeParams createDuplicateNodeParams( final Node sourceNode ) return builder.build(); } - private ContentIds getAllChildren( final Content duplicatedContent ) - { - final FindNodesByParentResult findNodesByParentResult = this.nodeService.findByParent( - FindNodesByParentParams.create().parentId( NodeId.from( duplicatedContent.getId() ) ).recursive( true ).build() ); - - return ContentNodeHelper.toContentIds( findNodesByParentResult.getNodeIds() ); - } - - public static class Builder + static class Builder extends AbstractContentCommand.Builder { private final DuplicateContentParams params; @@ -114,7 +106,7 @@ void validate() Objects.requireNonNull( params, "params cannot be null" ); } - public DuplicateContentCommand build() + DuplicateContentCommand build() { validate(); return new DuplicateContentCommand( this ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java index dd2e61a2e85..bb67e55c64e 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java @@ -1,12 +1,25 @@ package com.enonic.xp.core.impl.content; +import java.util.List; + +import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; +import com.enonic.xp.content.ContentPropertyNames; +import com.enonic.xp.content.ContentPublishInfo; +import com.enonic.xp.content.ContentVersion; +import com.enonic.xp.content.ContentVersionId; import com.enonic.xp.content.ContentVersions; import com.enonic.xp.content.FindContentVersionsResult; +import com.enonic.xp.core.impl.content.serializer.PublishInfoSerializer; +import com.enonic.xp.data.PropertyTree; +import com.enonic.xp.node.Attributes; import com.enonic.xp.node.GetNodeVersionsParams; +import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeId; +import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.NodeVersionQueryResult; +import com.enonic.xp.util.GenericValue; public class FindContentVersionsCommand extends AbstractContentCommand @@ -34,34 +47,101 @@ public static Builder create() public FindContentVersionsResult execute() { - return doGetContentVersions(); - } - - private FindContentVersionsResult doGetContentVersions() - { - final NodeId nodeId = NodeId.from( this.contentId ); - final NodeVersionQueryResult nodeVersionQueryResult = nodeService.findVersions( GetNodeVersionsParams.create(). - nodeId( nodeId ). - from( this.from ). - size( this.size ). - build() ); + final NodeVersionQueryResult nodeVersionQueryResult = nodeService.findVersions( + GetNodeVersionsParams.create().nodeId( NodeId.from( this.contentId ) ).from( this.from ).size( this.size ).build() ); - final FindContentVersionsResult.Builder findContentVersionsResultBuilder = FindContentVersionsResult.create(). - totalHits( nodeVersionQueryResult.getTotalHits() ); - - final ContentVersionFactory contentVersionFactory = new ContentVersionFactory( this.nodeService ); + final FindContentVersionsResult.Builder findContentVersionsResultBuilder = + FindContentVersionsResult.create().totalHits( nodeVersionQueryResult.getTotalHits() ); final ContentVersions.Builder contentVersionsBuilder = ContentVersions.create(); for ( final NodeVersionMetadata nodeVersionMetadata : nodeVersionQueryResult.getNodeVersionMetadatas() ) { - contentVersionsBuilder.add( contentVersionFactory.create( nodeVersionMetadata ) ); + contentVersionsBuilder.add( createVersion( nodeVersionMetadata ) ); } return findContentVersionsResultBuilder.contentVersions( contentVersionsBuilder.build() ).build(); } + public ContentVersion createVersion( final NodeVersionMetadata nodeVersionMetadata ) + { + final Attributes attributes = nodeVersionMetadata.getAttributes(); + + final ContentVersion.Builder builder = ContentVersion.create() + .id( ContentVersionId.from( nodeVersionMetadata.getNodeVersionId().toString() ) ) + .path( ContentNodeHelper.translateNodePathToContentPath( nodeVersionMetadata.getNodePath() ) ) + .timestamp( nodeVersionMetadata.getTimestamp() ) + .attributes( attributes ); + + if ( attributes != null ) + { + final GenericValue publishAttr = attributes.get( ContentAttributesHelper.PUBLISH_KEY ); + final GenericValue unpublishAttr = attributes.get( ContentAttributesHelper.UNPUBLISH_KEY ); + if ( publishAttr != null || unpublishAttr != null ) + { + final NodeVersion nodeVersion = nodeService.getByNodeVersionKey( nodeVersionMetadata.getNodeVersionKey() ); + final PropertyTree data = nodeVersion.getData(); + + final ContentPublishInfo publishInfo = PublishInfoSerializer.serialize( data.getSet( ContentPropertyNames.PUBLISH_INFO ) ); + if ( publishAttr != null ) + { + builder.published( ContentAttributesHelper.getOpTime( publishAttr ) ); + builder.publishedBy( ContentAttributesHelper.getUser( publishAttr ) ); + } + + builder.publishedFrom( publishInfo.getFrom() ); + builder.publishedTo( publishInfo.getTo() ); + + if ( unpublishAttr != null ) + { + builder.unpublished( ContentAttributesHelper.getOpTime( unpublishAttr ) ); + builder.unpublishedBy( ContentAttributesHelper.getUser( unpublishAttr ) ); + } + } + + attributes.list() + .stream() + .filter( v -> ContentAttributesHelper.CHANGE_KEYS.contains( v.property( Attributes.KEY_PROPERTY ).asString() ) ) + .reduce( ( first, second ) -> second ) + .ifPresent( changeAttr -> { + builder.changedBy( ContentAttributesHelper.getUser( changeAttr ) ); + builder.changeFields( changeAttr.optional( "fields" ).map( GenericValue::asStringList ).orElse( List.of() ) ); + builder.change( changeAttr.property( Attributes.KEY_PROPERTY ).asString() ); + } ); + } + + if ( nodeVersionMetadata.getNodeCommitId() != null ) + { + final NodeCommitEntry nodeCommitEntry = nodeService.getCommit( nodeVersionMetadata.getNodeCommitId() ); + if ( nodeCommitEntry != null ) + { + final String commitMessage = nodeCommitEntry.getMessage(); + builder.comment( getCommentPart( commitMessage ) ); + } + } + + return builder.build(); + } + + private static String getCommentPart( final String message ) + { + if ( message.startsWith( ContentConstants.PUBLISH_COMMIT_PREFIX + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER ) ) + { + return message.substring( + ContentConstants.PUBLISH_COMMIT_PREFIX.length() + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER.length() ); + } + else if ( message.startsWith( ContentConstants.ARCHIVE_COMMIT_PREFIX + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER ) ) + { + return message.substring( + ContentConstants.ARCHIVE_COMMIT_PREFIX.length() + ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER.length() ); + } + else + { + return null; + } + } + public static final class Builder extends AbstractContentCommand.Builder diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetActiveContentVersionsCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetActiveContentVersionsCommand.java deleted file mode 100644 index be0d3534a66..00000000000 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetActiveContentVersionsCommand.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.enonic.xp.core.impl.content; - -import java.util.Map; - -import com.enonic.xp.branch.Branch; -import com.enonic.xp.branch.Branches; -import com.enonic.xp.content.ActiveContentVersionEntry; -import com.enonic.xp.content.ContentId; -import com.enonic.xp.content.GetActiveContentVersionsResult; -import com.enonic.xp.node.GetActiveNodeVersionsParams; -import com.enonic.xp.node.GetActiveNodeVersionsResult; -import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeVersionMetadata; - -public class GetActiveContentVersionsCommand - extends AbstractContentCommand -{ - private final Branches branches; - - private final ContentId contentId; - - private GetActiveContentVersionsCommand( final Builder builder ) - { - super( builder ); - branches = builder.branches; - contentId = builder.contentId; - } - - public static Builder create() - { - return new Builder(); - } - - public GetActiveContentVersionsResult execute() - { - final NodeId nodeId = NodeId.from( contentId ); - - final GetActiveNodeVersionsResult activeNodeVersions = this.nodeService.getActiveVersions( GetActiveNodeVersionsParams.create(). - nodeId( nodeId ). - branches( this.branches ). - build() ); - - final ContentVersionFactory contentVersionFactory = new ContentVersionFactory( this.nodeService ); - - final GetActiveContentVersionsResult.Builder builder = GetActiveContentVersionsResult.create(); - - final Map nodeVersionsMap = activeNodeVersions.getNodeVersions(); - for ( final Branch branch : nodeVersionsMap.keySet() ) - { - final NodeVersionMetadata nodeVersionMetadata = nodeVersionsMap.get( branch ); - builder.add( ActiveContentVersionEntry.from( branch, contentVersionFactory.create( nodeVersionMetadata ) ) ); - } - - return builder.build(); - } - - public static final class Builder - extends AbstractContentCommand.Builder - { - private Branches branches; - - private ContentId contentId; - - private Builder() - { - } - - public Builder branches( final Branches branches ) - { - this.branches = branches; - return this; - } - - public Builder contentId( final ContentId contentId ) - { - this.contentId = contentId; - return this; - } - - public GetActiveContentVersionsCommand build() - { - return new GetActiveContentVersionsCommand( this ); - } - } -} diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ImportContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ImportContentCommand.java index d6f675e2049..11b07aa0384 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ImportContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ImportContentCommand.java @@ -42,6 +42,7 @@ private ImportContentResult doExecute() .insertManualStrategy( params.getInsertManualStrategy() ) .importPermissions( params.isImportPermissions() ) .importPermissionsOnCreate( params.isImportPermissionsOnCreate() ) + .versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.IMPORT_KEY ) ) .refresh( RefreshMode.ALL ) .build(); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/MoveContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/MoveContentCommand.java index 5ee42985c7b..a75866dbca0 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/MoveContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/MoveContentCommand.java @@ -3,7 +3,6 @@ import java.util.Objects; import com.enonic.xp.content.Content; -import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentAlreadyExistsException; import com.enonic.xp.content.ContentAlreadyMovedException; import com.enonic.xp.content.ContentId; @@ -52,7 +51,7 @@ MoveContentsResult execute() } catch ( NodeAccessException e ) { - throw new ContentAccessException( e ); + throw ContentNodeHelper.toContentAccessException( e ); } } @@ -77,6 +76,7 @@ private MoveContentsResult doExecute() final MoveNodeParams.Builder moveParams = MoveNodeParams.create() .nodeId( sourceNodeId ) .newParentPath( newParentPath ) + .versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.MOVE_KEY ) ) .refresh( RefreshMode.ALL ); if ( params.getMoveContentListener() != null ) @@ -96,7 +96,7 @@ private MoveContentsResult doExecute() return MoveContentsResult.create().setContentName( movedContent.getDisplayName() ).addMoved( movedContent.getId() ).build(); } - public static class Builder + static class Builder extends AbstractContentCommand.Builder { private final MoveContentParams params; @@ -113,11 +113,10 @@ void validate() Objects.requireNonNull( params, "params cannot be null" ); } - public MoveContentCommand build() + MoveContentCommand build() { validate(); return new MoveContentCommand( this ); } } - } diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchContentCommand.java index 668e1523aca..d8a5abab8b9 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchContentCommand.java @@ -61,8 +61,10 @@ private PatchContentResult doExecute() .build(); } - final PatchNodeParams patchNodeParams = PatchNodeParamsFactory.create().editedContent( patchedContent ) + final PatchNodeParams patchNodeParams = PatchNodeParamsFactory.create() + .editedContent( patchedContent ) .createAttachments( params.getCreateAttachments() ) + .versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.PATCH_KEY ) ) .branches( params.getBranches() ) .contentTypeService( this.contentTypeService ) .xDataService( this.xDataService ) diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchNodeParamsFactory.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchNodeParamsFactory.java index 1dd22d61cf3..52f3b284d96 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchNodeParamsFactory.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PatchNodeParamsFactory.java @@ -23,6 +23,7 @@ import com.enonic.xp.schema.xdata.XDataService; import com.enonic.xp.site.SiteConfigsDataSerializer; import com.enonic.xp.site.SiteService; +import com.enonic.xp.node.Attributes; public class PatchNodeParamsFactory { @@ -30,6 +31,8 @@ public class PatchNodeParamsFactory private final CreateAttachments createAttachments; + private final Attributes versionAttributes; + private final ContentTypeService contentTypeService; private final XDataService xDataService; @@ -57,6 +60,7 @@ public PatchNodeParamsFactory( final Builder builder ) this.layoutDescriptorService = builder.layoutDescriptorService; this.contentDataSerializer = builder.contentDataSerializer; this.siteService = builder.siteService; + this.versionAttributes = builder.versionAttributes; branches = Branches.from( builder.branches.build() ); } @@ -73,6 +77,7 @@ public PatchNodeParams produce() .id( NodeId.from( editedContent.getId() ) ) .editor( nodeEditor ) .addBranches( branches ) + .versionAttributes( versionAttributes ) .refresh( RefreshMode.ALL ); for ( final CreateAttachment createAttachment : createAttachments ) @@ -116,6 +121,8 @@ public static class Builder private CreateAttachments createAttachments = CreateAttachments.empty(); + private Attributes versionAttributes; + private ContentTypeService contentTypeService; private XDataService xDataService; @@ -142,6 +149,12 @@ Builder createAttachments( final CreateAttachments createAttachments ) return this; } + Builder versionAttributes( final Attributes versionAttributes ) + { + this.versionAttributes = versionAttributes; + return this; + } + Builder branches( final Branches branches ) { this.branches.addAll( branches ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PublishContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PublishContentCommand.java index 604a38b342a..b5bf5109837 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PublishContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/PublishContentCommand.java @@ -1,31 +1,32 @@ package com.enonic.xp.core.impl.content; import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Objects; + +import com.google.common.base.Preconditions; import com.enonic.xp.content.CompareContentResults; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentIds; import com.enonic.xp.content.ContentPropertyNames; -import com.enonic.xp.content.ContentPublishInfo; import com.enonic.xp.content.ContentValidityResult; import com.enonic.xp.content.PublishContentResult; import com.enonic.xp.content.PushContentListener; -import com.enonic.xp.context.Context; -import com.enonic.xp.context.ContextAccessor; -import com.enonic.xp.context.ContextBuilder; import com.enonic.xp.data.PropertySet; +import com.enonic.xp.data.PropertyTree; +import com.enonic.xp.node.CommitNodeParams; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitEntry; -import com.enonic.xp.node.NodeId; +import com.enonic.xp.node.NodeDataProcessor; import com.enonic.xp.node.NodeIds; +import com.enonic.xp.node.NodePath; +import com.enonic.xp.node.NodeVersionIds; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodeResult; import com.enonic.xp.node.PushNodesResult; -import com.enonic.xp.node.RoutableNodeVersionId; -import com.enonic.xp.node.RoutableNodeVersionIds; -import com.enonic.xp.node.UpdateNodeParams; -import com.enonic.xp.security.RoleKeys; -import com.enonic.xp.security.auth.AuthenticationInfo; public class PublishContentCommand extends AbstractContentCommand @@ -36,7 +37,9 @@ public class PublishContentCommand private final ContentIds excludeDescendantsOf; - private final ContentPublishInfo contentPublishInfo; + private final Instant publishFrom; + + private final Instant publishTo; private final boolean includeDependencies; @@ -51,7 +54,9 @@ private PublishContentCommand( final Builder builder ) super( builder ); this.contentIds = builder.contentIds; this.excludedContentIds = builder.excludedContentIds; - this.contentPublishInfo = builder.contentPublishInfo; + this.publishFrom = Objects.requireNonNullElseGet( builder.publishFrom, Instant::now ).truncatedTo( ChronoUnit.MILLIS ); + this.publishTo = builder.publishTo != null ? builder.publishTo.truncatedTo( ChronoUnit.MILLIS ) : null; + Preconditions.checkArgument( publishTo == null || publishTo.isAfter( publishFrom ), "publishTo must be after publishFrom" ); this.includeDependencies = builder.includeDependencies; this.excludeDescendantsOf = builder.excludeDescendantsOf; this.resultBuilder = PublishContentResult.create(); @@ -77,7 +82,7 @@ PublishContentResult execute() final PublishContentResult result = resultBuilder.build(); - if ( !result.getPushedContents().isEmpty() ) + if ( !result.getPublished().isEmpty() ) { runAsAdmin( this::doPushRoot ); } @@ -91,43 +96,76 @@ private void doPush( final ContentIds ids ) return; } - if ( !checkIfAllContentsValid( ids ) ) + final ContentValidityResult contentValidityResult = checkIfAllContentsValid( ids ); + if ( !contentValidityResult.allValid() ) { - this.resultBuilder.setFailed( ids ); + contentValidityResult.getNotValidContentIds() + .stream() + .map( c -> PublishContentResult.Result.failure( c, PublishContentResult.Reason.INVALID ) ) + .forEach( resultBuilder::add ); + contentValidityResult.getNotReadyContentIds() + .stream() + .map( c -> PublishContentResult.Result.failure( c, PublishContentResult.Reason.NOT_READY ) ) + .forEach( resultBuilder::add ); return; } - doPushNodes( ContentNodeHelper.toNodeIds( ids ) ); + + final NodeIds nodesToPush = ContentNodeHelper.toNodeIds( ids ); + final PushNodeParams.Builder pushNodeParams = + PushNodeParams.create().ids( nodesToPush ).processor( setPublishInfo() ).target( ContentConstants.BRANCH_MASTER ); + if ( publishContentListener != null ) + { + pushNodeParams.publishListener( publishContentListener::contentPushed ); + } + + final PushNodesResult pushNodesResult = nodeService.push( pushNodeParams.build() ); + + commit( pushNodesResult.getSuccessful() ); + + for ( var pushNodeResult : pushNodesResult.getSuccessful() ) + { + nodeService.addAttributes( pushNodeResult.getNodeVersionId(), + ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.PUBLISH_KEY ) ); + } + + pushNodesResult.getFailed() + .stream() + .map( r -> PublishContentResult.Result.failure( ContentId.from( r.getNodeId() ), + Enum.valueOf( PublishContentResult.Reason.class, + r.getFailureReason().toString() ) ) ) + .forEach( resultBuilder::add ); + + pushNodesResult.getSuccessful() + .stream() + .map( r -> PublishContentResult.Result.success( ContentId.from( r.getNodeId() ) ) ) + .forEach( resultBuilder::add ); } private PushNodesResult doPushRoot() { final Node contentRootNode = nodeService.getByPath( ContentConstants.CONTENT_ROOT_PATH ); - return nodeService.push( NodeIds.from( contentRootNode.id() ), ContentConstants.BRANCH_MASTER ); + final PushNodeParams pushNodeParams = + PushNodeParams.create().ids( NodeIds.from( contentRootNode.id() ) ).target( ContentConstants.BRANCH_MASTER ).build(); + return nodeService.push( pushNodeParams ); } private CompareContentResults getSyncWork() { - final Context context = ContextAccessor.current(); - - final Context adminContext = ContextBuilder.from( context ) - .authInfo( AuthenticationInfo.copyOf( context.getAuthInfo() ).principals( RoleKeys.ADMIN ).build() ) - .build(); - - return adminContext.callWith( ResolveContentsToBePublishedCommand.create() - .contentIds( this.contentIds ) - .excludedContentIds( this.excludedContentIds ) - .excludeDescendantsOf( this.excludeDescendantsOf ) - .includeDependencies( this.includeDependencies ) - .contentTypeService( this.contentTypeService ) - .eventPublisher( this.eventPublisher ) - .translator( this.translator ) - .nodeService( this.nodeService ) - .build()::execute ); + return runAsAdmin( ResolveContentsToBePublishedCommand.create() + .contentIds( this.contentIds ) + .excludedContentIds( this.excludedContentIds ) + .excludeDescendantsOf( this.excludeDescendantsOf ) + .includeDependencies( this.includeDependencies ) + .contentTypeService( this.contentTypeService ) + .eventPublisher( this.eventPublisher ) + .translator( this.translator ) + .nodeService( this.nodeService ) + .build()::execute ); } - private boolean checkIfAllContentsValid( final ContentIds pushContentsIds ) + private ContentValidityResult checkIfAllContentsValid( final ContentIds pushContentsIds ) { - final ContentValidityResult result = CheckContentValidityCommand.create() + return CheckContentValidityCommand.create() .translator( this.translator ) .nodeService( this.nodeService ) .eventPublisher( this.eventPublisher ) @@ -135,111 +173,50 @@ private boolean checkIfAllContentsValid( final ContentIds pushContentsIds ) .contentIds( pushContentsIds ) .build() .execute(); - - return result.allValid(); } - private void doPushNodes( final NodeIds nodesToPush ) + private NodeDataProcessor setPublishInfo() { - setPublishInfo( nodesToPush ); + return ( PropertyTree data, NodePath nodePath ) -> { + var toBeEdited = data.copy(); + final PropertySet publishInfo = Objects.requireNonNullElseGet( toBeEdited.getSet( ContentPropertyNames.PUBLISH_INFO ), + () -> toBeEdited.addSet( ContentPropertyNames.PUBLISH_INFO ) ); + + final Instant currentPublishFrom = publishInfo.getInstant( ContentPropertyNames.PUBLISH_FROM ); - final PushNodesResult pushNodesResult = nodeService.push( nodesToPush, ContentConstants.BRANCH_MASTER, count -> { - if ( publishContentListener != null ) + if ( !publishInfo.hasProperty( ContentPropertyNames.PUBLISH_FIRST ) ) { - publishContentListener.contentPushed( count ); + publishInfo.setInstant( ContentPropertyNames.PUBLISH_FIRST, Objects.requireNonNullElse( currentPublishFrom, publishFrom ) ); } - } ); - - commitPushedNodes( pushNodesResult.getSuccessful() ); - - this.resultBuilder.setFailed( pushNodesResult.getFailed() - .stream() - .map( PushNodeResult::getNodeId ) - .map( ContentId::from ) - .collect( ContentIds.collector() ) ); - this.resultBuilder.setPushed( pushNodesResult.getSuccessful() - .stream() - .map( PushNodeResult::getNodeId ) - .map( ContentId::from ) - .collect( ContentIds.collector() ) ); - } - - private void setPublishInfo( final NodeIds nodesToPush ) - { - final Instant publishFrom = contentPublishInfo.getFrom(); - final Instant publishTo = contentPublishInfo.getTo(); - - for ( final NodeId id : nodesToPush ) - { - this.nodeService.update( UpdateNodeParams.create().editor( toBeEdited -> { - - PropertySet publishInfo = toBeEdited.data.getSet( ContentPropertyNames.PUBLISH_INFO ); - - if ( publishInfo == null ) - { - publishInfo = toBeEdited.data.addSet( ContentPropertyNames.PUBLISH_INFO ); - } - - final Instant currentPublishFirst = publishInfo.getInstant( ContentPropertyNames.PUBLISH_FIRST ); - final Instant currentPublishFrom = publishInfo.getInstant( ContentPropertyNames.PUBLISH_FROM ); - if ( currentPublishFirst != null && currentPublishFrom != null ) - { - return; - } + if ( currentPublishFrom == null ) + { + publishInfo.setInstant( ContentPropertyNames.PUBLISH_FROM, publishFrom ); - if ( currentPublishFirst == null ) + if ( publishTo == null ) { - if ( currentPublishFrom == null ) - { - publishInfo.setInstant( ContentPropertyNames.PUBLISH_FIRST, publishFrom ); - } - else - { - //TODO Special case for Enonic XP 6.7 and 6.8 contents. Remove after 7.0 - publishInfo.setInstant( ContentPropertyNames.PUBLISH_FIRST, currentPublishFrom ); - } + publishInfo.removeProperties( ContentPropertyNames.PUBLISH_TO ); } - - if ( currentPublishFrom == null ) + else { - publishInfo.setInstant( ContentPropertyNames.PUBLISH_FROM, publishFrom ); - if ( publishTo == null ) - { - if ( publishInfo.hasProperty( ContentPropertyNames.PUBLISH_TO ) ) - { - publishInfo.removeProperty( ContentPropertyNames.PUBLISH_TO ); - } - } - else - { - publishInfo.setInstant( ContentPropertyNames.PUBLISH_TO, publishTo ); - } + publishInfo.setInstant( ContentPropertyNames.PUBLISH_TO, publishTo ); } - - } ).id( id ).build() ); - if ( publishContentListener != null ) - { - publishContentListener.contentPushed( 1 ); } - } + return toBeEdited; + }; } - private void commitPushedNodes( final Iterable branchEntries ) + private void commit( final List branchEntries ) { final String commitEntryMessage = message == null ? ContentConstants.PUBLISH_COMMIT_PREFIX : String.join( ContentConstants.PUBLISH_COMMIT_PREFIX_DELIMITER, ContentConstants.PUBLISH_COMMIT_PREFIX, message ); - final NodeCommitEntry commitEntry = NodeCommitEntry.create().message( commitEntryMessage ).build(); - final RoutableNodeVersionIds.Builder routableNodeVersionIds = RoutableNodeVersionIds.create(); - for ( PushNodeResult branchEntry : branchEntries ) - { - final RoutableNodeVersionId routableNodeVersionId = - RoutableNodeVersionId.from( branchEntry.getNodeId(), branchEntry.getNodeVersionId() ); - routableNodeVersionIds.add( routableNodeVersionId ); - } - nodeService.commit( commitEntry, routableNodeVersionIds.build() ); + nodeService.commit( CommitNodeParams.create() + .nodeCommitEntry( NodeCommitEntry.create().message( commitEntryMessage ).build() ) + .nodeVersionIds( + branchEntries.stream().map( PushNodeResult::getNodeVersionId ).collect( NodeVersionIds.collector() ) ) + .build() ); } public static class Builder @@ -251,7 +228,9 @@ public static class Builder private ContentIds excludeDescendantsOf; - private ContentPublishInfo contentPublishInfo; + private Instant publishFrom; + + private Instant publishTo; private boolean includeDependencies = true; @@ -277,20 +256,15 @@ public Builder excludeDescendantsOf( final ContentIds excludeDescendantsOf ) return this; } - public Builder contentPublishInfo( final ContentPublishInfo contentPublishInfo ) + public Builder publishFrom( Instant publishFrom ) { - if ( contentPublishInfo == null ) - { - this.contentPublishInfo = ContentPublishInfo.create().from( Instant.now() ).build(); - } - else if ( contentPublishInfo.getFrom() == null ) - { - this.contentPublishInfo = ContentPublishInfo.create().from( Instant.now() ).to( contentPublishInfo.getTo() ).build(); - } - else - { - this.contentPublishInfo = contentPublishInfo; - } + this.publishFrom = publishFrom; + return this; + } + + public Builder publishTo( Instant publishTo ) + { + this.publishTo = publishTo; return this; } @@ -316,7 +290,6 @@ public Builder message( final String message ) void validate() { super.validate(); - ContentPublishInfoPreconditions.check( contentPublishInfo ); } public PublishContentCommand build() diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RenameContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RenameContentCommand.java index 62d0b7db2f0..a74eab1f281 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RenameContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RenameContentCommand.java @@ -97,6 +97,7 @@ private Content doExecute() final MoveNodeParams moveParams = MoveNodeParams.create() .nodeId( NodeId.from( params.getContentId() ) ) .newName( NodeName.from( params.getNewName() ) ) + .versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.MOVE_KEY ) ) .processor( initProcessors() ) .refresh( RefreshMode.ALL ) .build(); @@ -106,7 +107,7 @@ private Content doExecute() return translator.fromNode( node ); } - public static class Builder + static class Builder extends AbstractCreatingOrUpdatingContentCommand.Builder { private final RenameContentParams params; @@ -122,7 +123,7 @@ void validate() super.validate(); } - public RenameContentCommand build() + RenameContentCommand build() { validate(); return new RenameContentCommand( this ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveContentsToBePublishedCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveContentsToBePublishedCommand.java index d3f550c45da..bc936fcc827 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveContentsToBePublishedCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveContentsToBePublishedCommand.java @@ -5,11 +5,11 @@ import com.enonic.xp.archive.ArchiveConstants; import com.enonic.xp.content.CompareContentResults; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentIds; import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.ResolveSyncWorkResult; @@ -68,7 +68,7 @@ private ResolveSyncWorkResult getWorkResult( final ContentId contentId ) .nodeId( NodeId.from( contentId ) ) .excludedNodeIds( ContentNodeHelper.toNodeIds( excludedContentIds ) ) .branch( ContentConstants.BRANCH_MASTER ) - .statusesToStopDependenciesSearch( Set.of( CompareStatus.EQUAL ) ) + .statusesToStopDependenciesSearch( Set.of( NodeCompareStatus.EQUAL ) ) .filter( ( ids ) -> nodeService.getByIds( ids ) .stream() .filter( node -> !node.path() diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveRequiredDependenciesCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveRequiredDependenciesCommand.java index 7c999218187..07281e471f3 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveRequiredDependenciesCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ResolveRequiredDependenciesCommand.java @@ -3,10 +3,10 @@ import java.util.Collection; import java.util.Objects; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentIds; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeComparisons; import com.enonic.xp.node.NodePath; @@ -17,13 +17,11 @@ public class ResolveRequiredDependenciesCommand { private final ContentIds contentIds; - private final ContentIds.Builder resultBuilder; private ResolveRequiredDependenciesCommand( final Builder builder ) { super( builder ); this.contentIds = builder.contentIds; - this.resultBuilder = ContentIds.create(); } public static Builder create() @@ -32,13 +30,6 @@ public static Builder create() } ContentIds execute() - { - resolveDependencies(); - - return resultBuilder.build(); - } - - private void resolveDependencies() { final NodeComparisons nodeComparisons = nodeService.compare( ContentNodeHelper.toNodeIds( contentIds ), ContentConstants.BRANCH_MASTER ); @@ -46,29 +37,16 @@ private void resolveDependencies() final NodePaths parentPaths = getParentPaths( nodeComparisons.getComparisons() ); final NodePaths resultPaths = nodeComparisons.getSourcePaths(); - parentPaths.stream(). - filter( resultPaths::contains ). - map( parentPath -> { - final NodeComparison comparison = nodeComparisons.getBySourcePath( parentPath ); - - if ( !CompareStatus.NEWER.equals( comparison.getCompareStatus() ) ) - { - return ContentId.from( comparison.getNodeId() ); - } - return null; - } ). - filter( Objects::nonNull ). - forEach( resultBuilder::add ); + return parentPaths.stream() + .filter( resultPaths::contains ) + .map( nodeComparisons::getBySourcePath ) + .filter( comparison -> NodeCompareStatus.NEWER != comparison.getCompareStatus() ) + .map( NodeComparison::getNodeId ) + .map( ContentId::from ) + .collect( ContentIds.collector() ); } private NodePaths getParentPaths( final Collection comparisons ) - { - - return getPathsFromComparisons( comparisons ); - - } - - private NodePaths getPathsFromComparisons( final Collection comparisons ) { final NodePaths.Builder parentPathsBuilder = NodePaths.create(); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RestoreContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RestoreContentCommand.java index 11fdb713736..613e456c71e 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RestoreContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/RestoreContentCommand.java @@ -6,13 +6,13 @@ import com.enonic.xp.archive.RestoreContentException; import com.enonic.xp.archive.RestoreContentParams; import com.enonic.xp.archive.RestoreContentsResult; -import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentNotFoundException; import com.enonic.xp.content.ContentPath; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.data.Property; +import com.enonic.xp.node.CommitNodeParams; import com.enonic.xp.node.MoveNodeException; import com.enonic.xp.node.MoveNodeParams; import com.enonic.xp.node.MoveNodeResult; @@ -23,10 +23,9 @@ import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeName; import com.enonic.xp.node.NodePath; +import com.enonic.xp.node.NodeVersionIds; import com.enonic.xp.node.Nodes; import com.enonic.xp.node.RefreshMode; -import com.enonic.xp.node.RoutableNodeVersionId; -import com.enonic.xp.node.RoutableNodeVersionIds; import static com.enonic.xp.content.ContentPropertyNames.ARCHIVED_BY; import static com.enonic.xp.content.ContentPropertyNames.ARCHIVED_TIME; @@ -62,7 +61,7 @@ RestoreContentsResult execute() } catch ( NodeAccessException e ) { - throw new ContentAccessException( e ); + throw ContentNodeHelper.toContentAccessException( e ); } } @@ -78,7 +77,11 @@ private RestoreContentsResult doExecute() final MoveNodeResult moveNodeResult = rename( nodeToRestore, parentPathToRestore ); - commit( moveNodeResult.getMovedNodes().stream().map( MoveNodeResult.MovedNode::getNode ).collect( Nodes.collector() ) ); + final Nodes nodes = moveNodeResult.getMovedNodes().stream().map( MoveNodeResult.MovedNode::getNode ).collect( Nodes.collector() ); + nodeService.commit( CommitNodeParams.create() + .nodeCommitEntry( NodeCommitEntry.create().message( ContentConstants.RESTORE_COMMIT_PREFIX ).build() ) + .nodeVersionIds( nodes.stream().map( Node::getNodeVersionId ).collect( NodeVersionIds.collector() ) ) + .build() ); this.nodeService.refresh( RefreshMode.SEARCH ); @@ -119,6 +122,7 @@ private MoveNodeResult rename( final Node nodeToRestore, final NodePath parentPa .nodeId( nodeToRestore.id() ) .newParentPath( parentPathToRestore ) .newName( newNodeName ) + .versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.RESTORE_KEY ) ) .refresh( RefreshMode.ALL ); if ( params.getRestoreContentListener() != null ) @@ -148,15 +152,6 @@ private NodeDataProcessor updateProperties() }; } - private void commit( final Nodes nodes ) - { - final RoutableNodeVersionIds routableNodeVersionIds = nodes.stream() - .map( n -> RoutableNodeVersionId.from( n.id(), n.getNodeVersionId() ) ) - .collect( RoutableNodeVersionIds.collector() ); - - nodeService.commit( NodeCommitEntry.create().message( ContentConstants.RESTORE_COMMIT_PREFIX ).build(), routableNodeVersionIds ); - } - private NodePath getParentPathToRestore( final Node node ) { if ( ArchiveConstants.ARCHIVE_ROOT_PATH.equals( node.parentPath() ) ) @@ -215,7 +210,7 @@ private NodeName buildName( final NodePath newParentPath, final NodeName name ) return newName; } - public static class Builder + static class Builder extends AbstractContentCommand.Builder { private final RestoreContentParams params; @@ -231,7 +226,7 @@ void validate() super.validate(); Objects.requireNonNull( params, "params cannot be null" ); } - public RestoreContentCommand build() + RestoreContentCommand build() { validate(); return new RestoreContentCommand( this ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/SortContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/SortContentCommand.java new file mode 100644 index 00000000000..fb559217078 --- /dev/null +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/SortContentCommand.java @@ -0,0 +1,99 @@ +package com.enonic.xp.core.impl.content; + +import java.util.Objects; + +import com.enonic.xp.content.Content; +import com.enonic.xp.content.ContentId; +import com.enonic.xp.content.ContentIds; +import com.enonic.xp.content.ReorderChildContentParams; +import com.enonic.xp.content.SortContentParams; +import com.enonic.xp.content.SortContentResult; +import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeAccessException; +import com.enonic.xp.node.NodeId; +import com.enonic.xp.node.RefreshMode; +import com.enonic.xp.node.ReorderChildNodeParams; +import com.enonic.xp.node.SortNodeParams; +import com.enonic.xp.node.SortNodeResult; + +class SortContentCommand + extends AbstractContentCommand +{ + private final SortContentParams params; + + public static Builder create( final SortContentParams params ) + { + return new Builder( params ); + } + + SortContentResult execute() { + try + { + final SortNodeParams.Builder paramsBuilder = SortNodeParams.create() + .nodeId( NodeId.from( params.getContentId() ) ) + .refresh( RefreshMode.ALL ) + .childOrder( params.getChildOrder() ) + .manualOrderSeed( params.getManualOrderSeed() ); + + for ( final ReorderChildContentParams param : params.getReorderChildContents() ) + { + paramsBuilder.addManualOrder( ReorderChildNodeParams.create() + .nodeId( NodeId.from( param.getContentToMove() ) ) + .moveBefore( param.getContentToMoveBefore() == null + ? null + : NodeId.from( param.getContentToMoveBefore() ) ) + .build() ); + } + + if ( params.stopInherit() ) + { + paramsBuilder.processor( InheritedContentDataProcessor.SORT ); + } + + paramsBuilder.versionAttributes( ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.SORT_KEY ) ); + + final SortNodeResult sortNodeResult = nodeService.sort( paramsBuilder.build() ); + + final Content content = translator.fromNode( sortNodeResult.getNode() ); + + return SortContentResult.create() + .content( content ) + .movedChildren( + sortNodeResult.getReorderedNodes().stream().map( Node::id ).map( ContentId::from ).collect( ContentIds.collector() ) ) + .build(); + } + catch ( NodeAccessException e ) + { + throw ContentNodeHelper.toContentAccessException( e ); + } + } + + private SortContentCommand( final Builder builder ) + { + super( builder ); + this.params = builder.params; + } + + public static class Builder + extends AbstractContentCommand.Builder + { + private final SortContentParams params; + + private Builder( final SortContentParams params ) + { + this.params = Objects.requireNonNull( params, "params cannot be null" ); + } + + @Override + void validate() + { + super.validate(); + } + + SortContentCommand build() + { + validate(); + return new SortContentCommand( this ); + } + } +} diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UnpublishContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UnpublishContentCommand.java index ea0ca0e8574..6da7b024bae 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UnpublishContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UnpublishContentCommand.java @@ -5,23 +5,22 @@ import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; -import com.enonic.xp.content.ContentIds; import com.enonic.xp.content.ContentPropertyNames; import com.enonic.xp.content.UnpublishContentParams; import com.enonic.xp.content.UnpublishContentsResult; import com.enonic.xp.context.Context; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.context.ContextBuilder; -import com.enonic.xp.data.PropertyPath; import com.enonic.xp.data.PropertySet; +import com.enonic.xp.node.CommitNodeParams; import com.enonic.xp.node.DeleteNodeParams; +import com.enonic.xp.node.DeleteNodeResult; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; +import com.enonic.xp.node.NodeVersionIds; import com.enonic.xp.node.RefreshMode; -import com.enonic.xp.node.RoutableNodeVersionId; -import com.enonic.xp.node.RoutableNodeVersionIds; import com.enonic.xp.node.UpdateNodeParams; public class UnpublishContentCommand @@ -45,64 +44,68 @@ public UnpublishContentsResult execute() { final Context masterContext = ContextBuilder.from( ContextAccessor.current() ).branch( ContentConstants.BRANCH_MASTER ).build(); - final ContentIds contentIds = masterContext.callWith( this::delete ); - - removePublishInfoAndCommit( contentIds ); - - this.nodeService.refresh( RefreshMode.SEARCH ); - - final UnpublishContentsResult.Builder resultBuilder = UnpublishContentsResult.create().addUnpublished( contentIds ); + final Instant now = Instant.now(); - return resultBuilder.build(); - } + final NodeIds.Builder allDeletedBuilder = NodeIds.create(); + masterContext.runWith( () -> { + for ( final ContentId contentId : this.params.getContentIds() ) + { + final DeleteNodeResult deleteNodeResult = + this.nodeService.delete( DeleteNodeParams.create().nodeId( NodeId.from( contentId ) ).build() ); - private ContentIds delete() - { - final ContentIds.Builder contentBuilder = ContentIds.create(); + final NodeIds nodeIds = deleteNodeResult.getNodeIds(); + if ( !nodeIds.isEmpty() ) + { + allDeletedBuilder.addAll( nodeIds ); - for ( final ContentId contentId : this.params.getContentIds() ) - { - final NodeIds nodeIds = this.nodeService.delete( - DeleteNodeParams.create().nodeId( NodeId.from( contentId ) ).refresh( RefreshMode.SEARCH ).build() ) - .getNodeIds(); + if ( params.getPublishContentListener() != null ) + { + params.getPublishContentListener().contentPushed( nodeIds.getSize() ); + } + } - if ( !nodeIds.isEmpty() ) - { - if ( params.getPublishContentListener() != null ) + for ( DeleteNodeResult.Result deleted : deleteNodeResult.getDeleted() ) { - params.getPublishContentListener().contentPushed( nodeIds.getSize() ); + this.nodeService.addAttributes( deleted.nodeVersionId(), + ContentAttributesHelper.versionHistoryAttr( ContentAttributesHelper.UNPUBLISH_KEY ) ); } - contentBuilder.addAll( ContentNodeHelper.toContentIds( nodeIds ) ); } - } - return contentBuilder.build(); + } ); + + final NodeIds allDeleted = allDeletedBuilder.build(); + + removePublishInfoAndCommit( allDeleted, now ); + + this.nodeService.refresh( RefreshMode.SEARCH ); + + final UnpublishContentsResult.Builder resultBuilder = + UnpublishContentsResult.create().addUnpublished( ContentNodeHelper.toContentIds( allDeleted ) ); + + return resultBuilder.build(); + } - private void removePublishInfoAndCommit( final ContentIds contentIds ) + private void removePublishInfoAndCommit( final NodeIds deleteNodeResult, Instant now ) { - final Instant now = Instant.now(); - for ( final ContentId contentId : contentIds ) + for ( final var deleted : deleteNodeResult ) { - final Node updated = nodeService.update( UpdateNodeParams.create().editor( toBeEdited -> { - - if ( toBeEdited.data.getInstant( - PropertyPath.from( ContentPropertyNames.PUBLISH_INFO, ContentPropertyNames.PUBLISH_FROM ) ) != null ) + final Node updated = nodeService.update( UpdateNodeParams.create().id( deleted ).editor( toBeEdited -> { + PropertySet publishInfo = toBeEdited.data.getSet( ContentPropertyNames.PUBLISH_INFO ); + if ( publishInfo != null ) { - PropertySet publishInfo = toBeEdited.data.getSet( ContentPropertyNames.PUBLISH_INFO ); - publishInfo.removeProperties( ContentPropertyNames.PUBLISH_FROM ); - publishInfo.removeProperties( ContentPropertyNames.PUBLISH_TO ); - if ( publishInfo.getInstant( ContentPropertyNames.PUBLISH_FIRST ).isAfter( now ) ) { - publishInfo.removeProperty( ContentPropertyNames.PUBLISH_FIRST ); + publishInfo.removeProperties( ContentPropertyNames.PUBLISH_FIRST ); } } - } ).id( NodeId.from( contentId ) ).build() ); + } ).build() ); - nodeService.commit( NodeCommitEntry.create().message( ContentConstants.UNPUBLISH_COMMIT_PREFIX ).build(), - RoutableNodeVersionIds.from( RoutableNodeVersionId.from( updated.id(), updated.getNodeVersionId() ) ) ); + nodeService.commit( CommitNodeParams.create() + .nodeCommitEntry( NodeCommitEntry.create().message( ContentConstants.UNPUBLISH_COMMIT_PREFIX ).build() ) + .nodeVersionIds( NodeVersionIds.from( updated.getNodeVersionId() ) ) + .build() ); } } diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UpdateContentCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UpdateContentCommand.java index 576d4a549a5..76d92331a2c 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UpdateContentCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/UpdateContentCommand.java @@ -14,7 +14,6 @@ import com.enonic.xp.branch.Branches; import com.enonic.xp.content.AttachmentValidationError; import com.enonic.xp.content.Content; -import com.enonic.xp.content.ContentAccessException; import com.enonic.xp.content.ContentDataValidationException; import com.enonic.xp.content.ContentEditor; import com.enonic.xp.content.ContentInheritType; @@ -78,7 +77,7 @@ Content execute() } catch ( NodeAccessException e ) { - throw new ContentAccessException( e ); + throw ContentNodeHelper.toContentAccessException( e ); } } @@ -109,6 +108,7 @@ private Content doExecute() final PatchNodeParams patchNodeParams = PatchNodeParamsFactory.create() .editedContent( editedContent ) .createAttachments( params.getCreateAttachments() ) + .versionAttributes( ContentAttributesHelper.updateVersionHistoryAttr( contentBeforeChange, editedContent ) ) .branches( Branches.from( ContextAccessor.current().getBranch() ) ) .contentTypeService( this.contentTypeService ) .xDataService( this.xDataService ) @@ -130,7 +130,7 @@ private Content editContentMetadata( Content content ) final PatchableContent patchableContent = new PatchableContent( content ); patchableContent.inherit.setPatcher( c -> stopInherit( c.inherit.originalValue ) ); patchableContent.attachments.setPatcher( c -> mergeExistingAndUpdatedAttachments( c.attachments.originalValue ) ); - patchableContent.modifier.setValue( getCurrentUser().getKey() ); + patchableContent.modifier.setValue( getCurrentUserKey() ); patchableContent.modifiedTime.setValue( Instant.now() ); patchableContent.validationErrors.setPatcher( c -> validateContent( c.source ) ); patchableContent.valid.setPatcher( c -> !c.validationErrors.getProducedValue().hasErrors() ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializer.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializer.java index 5634615aca6..c550f357ed9 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializer.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializer.java @@ -67,8 +67,6 @@ public final class ContentDataSerializer private final WorkflowInfoSerializer workflowInfoSerializer; - private final PublishInfoSerializer publishInfoSerializer; - private final ValidationErrorsSerializer validationErrorsSerializer; public ContentDataSerializer( ) @@ -81,7 +79,6 @@ private ContentDataSerializer( final PageDataSerializer pageDataSerializer ) this.pageDataSerializer = pageDataSerializer; this.extraDataSerializer = new ExtraDataSerializer(); this.workflowInfoSerializer = new WorkflowInfoSerializer(); - this.publishInfoSerializer = new PublishInfoSerializer(); this.validationErrorsSerializer = new ValidationErrorsSerializer(); } @@ -240,7 +237,7 @@ private void addProcessedReferences( final PropertySet contentAsData, final Cont .toArray( Reference[]::new ) ); } - private void addPublishInfo( final PropertySet contentAsData, final ContentPublishInfo data ) + private static void addPublishInfo( final PropertySet contentAsData, final ContentPublishInfo data ) { if ( data != null ) { @@ -283,12 +280,7 @@ private void extractUserInfo( final PropertySet contentAsSet, final Content.Buil private void extractPublishInfo( final PropertySet contentAsSet, final Content.Builder builder ) { - final ContentPublishInfo publishInfo = publishInfoSerializer.serialize( contentAsSet ); - - if ( publishInfo != null ) - { - builder.publishInfo( publishInfo ); - } + builder.publishInfo( PublishInfoSerializer.serialize( contentAsSet.getSet( PUBLISH_INFO ) ) ); } private void extractAttachments( final PropertySet contentAsSet, final Content.Builder builder ) diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/PublishInfoSerializer.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/PublishInfoSerializer.java index a598d818c6f..82345ac220d 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/PublishInfoSerializer.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/serializer/PublishInfoSerializer.java @@ -6,11 +6,12 @@ public class PublishInfoSerializer { - - public ContentPublishInfo serialize( final PropertySet contentAsSet ) + private PublishInfoSerializer() { - final PropertySet publishInfo = contentAsSet.getSet( ContentPropertyNames.PUBLISH_INFO ); + } + public static ContentPublishInfo serialize( final PropertySet publishInfo ) + { if ( publishInfo == null ) { return null; diff --git a/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializerTest.java b/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializerTest.java index ab03293d420..0c57d5d7eb2 100644 --- a/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializerTest.java +++ b/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/content/serializer/ContentDataSerializerTest.java @@ -355,7 +355,7 @@ void create_propertyTree_populated_with_workflowInfo() final PropertySet workflowData = data.getSet( ContentPropertyNames.WORKFLOW_INFO ); assertEquals( workflowInfo.getState().toString(), workflowData.getString( ContentPropertyNames.WORKFLOW_INFO_STATE ) ); - final PropertySet workflowChecks = workflowData.getPropertySet( ContentPropertyNames.WORKFLOW_INFO_CHECKS ); + final PropertySet workflowChecks = workflowData.getSet( ContentPropertyNames.WORKFLOW_INFO_CHECKS ); assertEquals( check1State.toString(), workflowChecks.getString( check1Name ) ); assertEquals( check2State.toString(), workflowChecks.getString( check2Name ) ); } diff --git a/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/issue/DeleteIssueCommentCommandTest.java b/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/issue/DeleteIssueCommentCommandTest.java index 75cd5bcae3a..b959502267d 100644 --- a/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/issue/DeleteIssueCommentCommandTest.java +++ b/modules/core/core-content/src/test/java/com/enonic/xp/core/impl/issue/DeleteIssueCommentCommandTest.java @@ -12,8 +12,8 @@ import com.enonic.xp.node.DeleteNodeParams; import com.enonic.xp.node.DeleteNodeResult; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodeService; +import com.enonic.xp.node.NodeVersionId; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -66,7 +66,8 @@ private DeleteIssueCommentCommand createDeleteIssueCommentCommand( DeleteIssueCo private static DeleteNodeResult answerDeleted( InvocationOnMock answer ) { return DeleteNodeResult.create() - .nodeIds( NodeIds.from( answer.getArgument( 0, DeleteNodeParams.class ).getNodeId() ) ) + .add( new DeleteNodeResult.Result( answer.getArgument( 0, DeleteNodeParams.class ).getNodeId(), + NodeVersionId.from( "nodeVersionId" ) ) ) .build(); } } diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java index ac5a5117b87..0fe54ab4f15 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java @@ -173,7 +173,7 @@ private List getProjectRepositories( final Repositories repositories private static void buildIcon( final Project.Builder project, final PropertySet projectData ) { - final PropertySet iconData = projectData.getPropertySet( ProjectConstants.PROJECT_ICON_PROPERTY ); + final PropertySet iconData = projectData.getSet( ProjectConstants.PROJECT_ICON_PROPERTY ); if ( iconData != null ) { @@ -674,14 +674,14 @@ private SiteConfigs getProjectSiteConfigs( final ProjectName projectName ) private SiteConfigs getProjectSiteConfigs( final PropertyTree contentRootData ) { - return Optional.ofNullable( contentRootData.getPropertySet( "data" ) ).map( SiteConfigsDataSerializer::fromData ) + return Optional.ofNullable( contentRootData.getSet( ContentPropertyNames.DATA ) ).map( SiteConfigsDataSerializer::fromData ) .orElse( SiteConfigs.empty() ); } private Node updateProjectSiteConfigs( final ProjectName projectName, final SiteConfigs siteConfigs ) { final NodeEditor editor = edit -> { - final PropertySet data = edit.data.getPropertySet( "data" ); + final PropertySet data = edit.data.getSet( ContentPropertyNames.DATA ); if ( data == null ) { throw new IllegalStateException( "Cannot update project config" ); diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java index d3fdf243dd1..13103040bb8 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java @@ -17,6 +17,7 @@ import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.query.Direction; import com.enonic.xp.repository.BranchNotFoundException; @@ -141,7 +142,8 @@ private void initContentNode() LOG.info( "Created content root-node: {}", contentRoot ); - nodeService.push( NodeIds.from( contentRoot.id() ), ContentConstants.BRANCH_MASTER ); + final NodeIds ids = NodeIds.from( contentRoot.id() ); + nodeService.push( PushNodeParams.create().ids( ids ).target( ContentConstants.BRANCH_MASTER ).build() ); } } diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/IssueInitializer.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/IssueInitializer.java index 34452aedc2c..ea3bef2245b 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/IssueInitializer.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/IssueInitializer.java @@ -16,6 +16,7 @@ import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.security.RoleKeys; import com.enonic.xp.security.User; @@ -95,7 +96,8 @@ private void initIssueNode() LOG.info( "Created issue root-node: " + issueRoot.path() ); - nodeService.push( NodeIds.from( issueRoot.id() ), ContentConstants.BRANCH_MASTER ); + final NodeIds ids = NodeIds.from( issueRoot.id() ); + nodeService.push( PushNodeParams.create().ids( ids ).target( ContentConstants.BRANCH_MASTER ).build() ); } public static class Builder diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/NodeBranchEntry.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/NodeBranchEntry.java index fcdcd2e66b3..f1ecb3cee81 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/NodeBranchEntry.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/NodeBranchEntry.java @@ -7,6 +7,7 @@ import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.NodeVersionMetadata; public final class NodeBranchEntry { @@ -104,6 +105,16 @@ public int hashCode() return result; } + public static NodeBranchEntry fromNodeVersionMetadata( final NodeVersionMetadata nodeVersionMetadata ) { + return NodeBranchEntry.create() + .nodeId( nodeVersionMetadata.getNodeId() ) + .nodeVersionId( nodeVersionMetadata.getNodeVersionId() ) + .nodePath( nodeVersionMetadata.getNodePath() ) + .nodeVersionKey( nodeVersionMetadata.getNodeVersionKey() ) + .timestamp( nodeVersionMetadata.getTimestamp() ) + .build(); + } + public static final class Builder { private NodeVersionId nodeVersionId; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnField.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnField.java deleted file mode 100644 index 7379acf8965..00000000000 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnField.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.enonic.xp.repo.impl; - -import com.enonic.xp.index.IndexPath; - -class ReturnField -{ - private final IndexPath indexPath; - - ReturnField( final IndexPath indexPath ) - { - this.indexPath = indexPath; - } - - public String getPath() - { - return indexPath.getPath(); - } -} diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java index c50bba4966b..6800cf2d363 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java @@ -3,8 +3,11 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Optional; +import com.enonic.xp.index.IndexPath; + public class ReturnValues { private final Map returnValues; @@ -19,21 +22,21 @@ public static Builder create() return new Builder(); } - public Object getSingleValue( final String key ) + public String getStringValue( final IndexPath key ) { - final ReturnValue returnValue = returnValues.get( key ); + final ReturnValue returnValue = returnValues.get( key.getPath() ); if ( returnValue == null ) { - return null; + throw new NoSuchElementException( key.getPath() ); } - return returnValue.getSingleValue(); + return returnValue.getSingleValue().toString(); } - public Optional getOptional( final String key ) + public Optional getOptional( final IndexPath key ) { - final ReturnValue returnValue = returnValues.get( key ); + final ReturnValue returnValue = returnValues.get( key.getPath() ); return returnValue == null ? Optional.empty() : Optional.of( returnValue.getSingleValue() ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java index 267b6c0d21d..573c3c39ffb 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java @@ -3,10 +3,10 @@ import java.time.Instant; import com.enonic.xp.blob.BlobKey; -import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.repo.impl.NodeBranchEntry; import com.enonic.xp.repo.impl.ReturnValues; @@ -14,24 +14,25 @@ public class NodeBranchVersionFactory { public static NodeBranchEntry create( final ReturnValues returnValues ) { - final Object path = returnValues.getSingleValue( BranchIndexPath.PATH.getPath() ); - final Object versionId = returnValues.getSingleValue( BranchIndexPath.VERSION_ID.getPath() ); - final Object nodeBlobKey = returnValues.getSingleValue( BranchIndexPath.NODE_BLOB_KEY.getPath() ); - final Object indexConfigBlobKey = returnValues.getSingleValue( BranchIndexPath.INDEX_CONFIG_BLOB_KEY.getPath() ); - final Object accessControlBlobKey = returnValues.getSingleValue( BranchIndexPath.ACCESS_CONTROL_BLOB_KEY.getPath() ); - final Object timestamp = returnValues.getSingleValue( BranchIndexPath.TIMESTAMP.getPath() ); - final Object nodeId = returnValues.getSingleValue( BranchIndexPath.NODE_ID.getPath() ); + final NodePath path = + returnValues.getOptional( BranchIndexPath.PATH ).map( Object::toString ).map( NodePath::new ).orElse( NodePath.ROOT ); + final NodeVersionId versionId = NodeVersionId.from( returnValues.getStringValue( BranchIndexPath.VERSION_ID ) ); + final BlobKey nodeBlobKey = BlobKey.from( returnValues.getStringValue( BranchIndexPath.NODE_BLOB_KEY ) ); + final BlobKey indexConfigBlobKey = BlobKey.from( returnValues.getStringValue( BranchIndexPath.INDEX_CONFIG_BLOB_KEY ) ); + final BlobKey accessControlBlobKey = BlobKey.from( returnValues.getStringValue( BranchIndexPath.ACCESS_CONTROL_BLOB_KEY ) ); + final Instant timestamp = Instant.parse( returnValues.getStringValue( BranchIndexPath.TIMESTAMP ) ); + final NodeId nodeId = NodeId.from( returnValues.getStringValue( BranchIndexPath.NODE_ID ) ); return NodeBranchEntry.create() - .nodePath( path != null ? new NodePath( path.toString() ) : NodePath.ROOT ) - .nodeVersionId( NodeVersionId.from( versionId ) ) + .nodePath( path ) + .nodeVersionId( versionId ) .nodeVersionKey( NodeVersionKey.create() - .nodeBlobKey( BlobKey.from( nodeBlobKey.toString() ) ) - .indexConfigBlobKey( BlobKey.from( indexConfigBlobKey.toString() ) ) - .accessControlBlobKey( BlobKey.from( accessControlBlobKey.toString() ) ) + .nodeBlobKey( nodeBlobKey ) + .indexConfigBlobKey( indexConfigBlobKey ) + .accessControlBlobKey( accessControlBlobKey ) .build() ) - .timestamp( Instant.parse( timestamp.toString() ) ) - .nodeId( NodeId.from( nodeId ) ) + .timestamp( timestamp ) + .nodeId( nodeId ) .build(); } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeFactory.java index a067e151fbd..a6adae53035 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeFactory.java @@ -1,7 +1,11 @@ package com.enonic.xp.repo.impl.branch.storage; +import java.time.Instant; + import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersion; +import com.enonic.xp.node.NodeVersionId; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.repo.impl.NodeBranchEntry; @@ -10,24 +14,23 @@ public class NodeFactory { public static Node create( final NodeVersion nodeVersion, final NodeBranchEntry nodeBranchEntry ) { - final Node.Builder builder = - Node.create( nodeVersion ).nodeVersionId( nodeBranchEntry.getVersionId() ).timestamp( nodeBranchEntry.getTimestamp() ); - if ( !Node.ROOT_UUID.equals( nodeVersion.getId() ) ) - { - builder.parentPath( nodeBranchEntry.getNodePath().getParentPath() ).name( nodeBranchEntry.getNodePath().getName() ); - } - return builder.build(); + return create( nodeVersion, nodeBranchEntry.getVersionId(), nodeBranchEntry.getNodePath(), + nodeBranchEntry.getTimestamp() ); } public static Node create( final NodeVersion nodeVersion, final NodeVersionMetadata nodeVersionMetadata ) { - final Node.Builder builder = Node.create( nodeVersion ) - .nodeVersionId( nodeVersionMetadata.getNodeVersionId() ) - .timestamp( nodeVersionMetadata.getTimestamp() ); + return create( nodeVersion, nodeVersionMetadata.getNodeVersionId(), nodeVersionMetadata.getNodePath(), + nodeVersionMetadata.getTimestamp() ); + } + public static Node create( final NodeVersion nodeVersion, final NodeVersionId nodeVersionId, final NodePath nodePath, + final Instant timestamp ) + { + final Node.Builder builder = Node.create( nodeVersion ).nodeVersionId( nodeVersionId ).timestamp( timestamp ); if ( !Node.ROOT_UUID.equals( nodeVersion.getId() ) ) { - builder.parentPath( nodeVersionMetadata.getNodePath().getParentPath() ).name( nodeVersionMetadata.getNodePath().getName() ); + builder.parentPath( nodePath.getParentPath() ).name( nodePath.getName() ); } return builder.build(); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/search/NodeCommitQueryResultFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/search/NodeCommitQueryResultFactory.java index 43a7b4c9796..541d0206cc7 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/search/NodeCommitQueryResultFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/search/NodeCommitQueryResultFactory.java @@ -1,81 +1,22 @@ package com.enonic.xp.repo.impl.commit.search; -import java.time.Instant; - -import com.enonic.xp.index.IndexPath; import com.enonic.xp.node.NodeCommitEntries; -import com.enonic.xp.node.NodeCommitEntry; -import com.enonic.xp.node.NodeCommitId; import com.enonic.xp.node.NodeCommitQueryResult; -import com.enonic.xp.repo.impl.ReturnValue; -import com.enonic.xp.repo.impl.commit.storage.CommitIndexPath; +import com.enonic.xp.repo.impl.commit.storage.NodeCommitEntryFactory; import com.enonic.xp.repo.impl.search.result.SearchHit; import com.enonic.xp.repo.impl.search.result.SearchResult; -import com.enonic.xp.security.PrincipalKey; public class NodeCommitQueryResultFactory { public static NodeCommitQueryResult create( final SearchResult searchResult ) { - if ( searchResult.isEmpty() ) - { - final long totalHits = searchResult.getTotalHits(); - return NodeCommitQueryResult.create(). - nodeCommitEntries( NodeCommitEntries.empty() ). - totalHits( totalHits ). - build(); - } - - final NodeCommitQueryResult.Builder nodeCommitQueryResult = NodeCommitQueryResult.create(); - - nodeCommitQueryResult.totalHits( searchResult.getTotalHits() ); - - nodeCommitQueryResult.nodeCommitEntries( buildNodeCommitEntries( searchResult ) ); - - return nodeCommitQueryResult.build(); - } - - private static NodeCommitEntries buildNodeCommitEntries( final SearchResult searchResult ) - { - final NodeCommitEntries.Builder nodeCommitEntries = NodeCommitEntries.create(); - - for ( final SearchHit searchHit : searchResult.getHits() ) - { - nodeCommitEntries.add( createNodeCommitEntry( searchHit ) ); - } - - return nodeCommitEntries.build(); - } - - private static NodeCommitEntry createNodeCommitEntry( final SearchHit hit ) - { - final String commitId = getStringValue( hit, CommitIndexPath.COMMIT_ID, true ); - - final String message = getStringValue( hit, CommitIndexPath.MESSAGE, false ); - - final String committer = getStringValue( hit, CommitIndexPath.COMMITTER, false ); - - final String timestamp = getStringValue( hit, CommitIndexPath.TIMESTAMP, true ); - - return NodeCommitEntry.create(). - nodeCommitId( NodeCommitId.from( commitId ) ). - message( message ). - committer( PrincipalKey.from(committer) ). - timestamp( Instant.parse( timestamp ) ). - build(); - } - - private static String getStringValue( final SearchHit hit, final IndexPath indexPath, final boolean required ) - { - final ReturnValue field = hit.getField( indexPath.getPath(), required ); - - if ( field == null ) - { - return null; - } - - return field.getSingleValue().toString(); + return NodeCommitQueryResult.create() + .totalHits( searchResult.getTotalHits() ) + .nodeCommitEntries( searchResult.getHits() + .stream() + .map( SearchHit::getReturnValues ) + .map( NodeCommitEntryFactory::create ) + .collect( NodeCommitEntries.collector() ) ) + .build(); } - - } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/NodeCommitEntryFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/NodeCommitEntryFactory.java index f95b920c41a..0a052381e11 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/NodeCommitEntryFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/NodeCommitEntryFactory.java @@ -11,17 +11,11 @@ public class NodeCommitEntryFactory { public static NodeCommitEntry create( final ReturnValues returnValues ) { + final NodeCommitId commitId = NodeCommitId.from( returnValues.getStringValue( CommitIndexPath.COMMIT_ID ) ); + final String message = returnValues.getStringValue( CommitIndexPath.MESSAGE ); + final Instant timestamp = Instant.parse( returnValues.getStringValue( CommitIndexPath.TIMESTAMP ) ); + final PrincipalKey committer = PrincipalKey.from( returnValues.getStringValue( CommitIndexPath.COMMITTER ) ); - final Object commitId = returnValues.getSingleValue( CommitIndexPath.COMMIT_ID.getPath() ); - final Object message = returnValues.getSingleValue( CommitIndexPath.MESSAGE.getPath() ); - final Object timestamp = returnValues.getSingleValue( CommitIndexPath.TIMESTAMP.getPath() ); - final Object committer = returnValues.getSingleValue( CommitIndexPath.COMMITTER.getPath() ); - - return NodeCommitEntry.create(). - nodeCommitId( NodeCommitId.from( commitId ) ). - message( message.toString() ). - timestamp( Instant.parse( timestamp.toString() ) ). - committer( PrincipalKey.from(committer.toString()) ). - build(); + return NodeCommitEntry.create().nodeCommitId( commitId ).message( message ).timestamp( timestamp ).committer( committer ).build(); } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/RepoDumper.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/RepoDumper.java index d0c511aa28f..c90ff93f775 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/RepoDumper.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/RepoDumper.java @@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory; import com.enonic.xp.blob.BlobKey; -import com.enonic.xp.node.NodeVersionKey; +import com.enonic.xp.blob.BlobKeys; import com.enonic.xp.branch.Branch; import com.enonic.xp.branch.Branches; import com.enonic.xp.context.Context; @@ -35,8 +35,8 @@ import com.enonic.xp.node.NodeCommitQuery; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeService; -import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.NodeVersionQuery; import com.enonic.xp.node.NodeVersionQueryResult; @@ -93,70 +93,57 @@ public RepoDumpResult execute() final Consumer nodeIdsAccumulator = includeVersions ? dumpedNodes::add : nodeId -> { }; - for ( Branch branch : this.repository.getBranches() ) - { - setContext( branch ).runWith( () -> dumpBranch( nodeIdsAccumulator ) ); - } - - if ( includeVersions ) - { - setContext( RepositoryConstants.MASTER_BRANCH ).runWith( () -> dumpVersions( dumpedNodes ) ); - } - - setContext( RepositoryConstants.MASTER_BRANCH ).runWith( this::dumpCommits ); + setContext( RepositoryConstants.MASTER_BRANCH ).runWith( () -> { + this.nodeService.refresh( RefreshMode.ALL ); + for ( Branch branch : this.repository.getBranches() ) + { + dumpBranch( branch, nodeIdsAccumulator ); + } + if ( includeVersions ) + { + dumpVersions( dumpedNodes ); + } + dumpCommits(); + } ); return this.dumpResult.build(); } - private void dumpBranch( Consumer nodeIdsAccumulator ) + private void dumpBranch( final Branch branch, Consumer nodeIdsAccumulator ) { - this.nodeService.refresh( RefreshMode.ALL ); - - final Branch branch = ContextAccessor.current().getBranch(); - - final BranchDumpResult.Builder branchDumpResult = BranchDumpResult.create( branch ); - writer.openBranchMeta( repository.getId(), branch ); - try - { + setContext( branch ).runWith( () -> { + final BranchDumpResult.Builder branchDumpResult = BranchDumpResult.create( branch ); + writer.openBranchMeta( repository.getId(), branch ); try { - dumpBranch( branchDumpResult, nodeIdsAccumulator ); + final FindNodesByParentResult children = this.nodeService.findByParent( + FindNodesByParentParams.create().parentId( Node.ROOT_UUID ).recursive( true ).childOrder( ChildOrder.path() ).build() ); + + this.listener.dumpingBranch( repository.getId(), branch, children.getTotalHits() + 1 ); + LOG.info( "Dumping repository [{}], branch [{}]", repository.getId(), branch ); + + doDumpNode( Node.ROOT_UUID, branch, branchDumpResult ); + nodeIdsAccumulator.accept( Node.ROOT_UUID ); + + for ( final NodeId child : children.getNodeIds() ) + { + doDumpNode( child, branch, branchDumpResult ); + nodeIdsAccumulator.accept( child ); + } } catch ( Exception e ) { - throw new RepoDumpException( "Error occurred when dumping repository " + repository.getId(), e ); + LOG.error( "Cannot fully dump repository [{}] branch [{}]", repository.getId(), branch, e ); + branchDumpResult.error( DumpError.error( + "Cannot fully dump repository [" + repository.getId() + "] branch [" + branch + "]: " + e.getMessage() ) ); } finally { writer.closeMeta(); } - } - catch ( RepoDumpException e ) - { - LOG.error( "Cannot fully dump repository [{}] branch [{}]",repository.getId(), branch, e ); - branchDumpResult.error( - DumpError.error( "Cannot fully dump repository [" + repository.getId() + "] branch [" + branch + "]: " + e.getMessage() ) ); - } - this.dumpResult.add( branchDumpResult.build() ); - } - private void dumpBranch( final BranchDumpResult.Builder dumpResult, Consumer nodeIdsAccumulator ) - { - final FindNodesByParentResult children = this.nodeService.findByParent( - FindNodesByParentParams.create().parentId( Node.ROOT_UUID ).recursive( true ).childOrder( ChildOrder.path() ).build() ); - - final Branch branch = ContextAccessor.current().getBranch(); - this.listener.dumpingBranch( repository.getId(), branch, children.getTotalHits() + 1 ); - LOG.info( "Dumping repository [{}], branch [{}]", repository.getId(), branch ); - - doDumpNode( Node.ROOT_UUID, dumpResult ); - nodeIdsAccumulator.accept( Node.ROOT_UUID ); - - for ( final NodeId child : children.getNodeIds() ) - { - doDumpNode( child, dumpResult ); - nodeIdsAccumulator.accept( child ); - } + this.dumpResult.add( branchDumpResult.build() ); + } ); } private void dumpVersions( final Collection dumpedNodes ) @@ -164,32 +151,29 @@ private void dumpVersions( final Collection dumpedNodes ) writer.openVersionsMeta( repository.getId() ); try { - try + for ( NodeId nodeId : dumpedNodes ) { - for ( NodeId nodeId : dumpedNodes ) - { - final VersionsDumpEntry.Builder builder = VersionsDumpEntry.create( nodeId ); - - final NodeVersionQueryResult versions = getVersions( nodeId ); - for ( final NodeVersionMetadata metaData : versions.getNodeVersionMetadatas() ) - { - doStoreVersion( builder, metaData, this.dumpResult ); - this.dumpResult.addedVersion(); - } + final VersionsDumpEntry.Builder builder = VersionsDumpEntry.create( nodeId ); - writer.writeVersionsEntry( builder.build() ); + final NodeVersionQueryResult versions = getVersions( nodeId ); + for ( final NodeVersionMetadata metaData : versions.getNodeVersionMetadatas() ) + { + builder.addVersion( VersionMetaFactory.create( metaData ) ); + doStoreVersion( metaData, this.dumpResult ); + this.dumpResult.addedVersion(); } - } - finally - { - writer.closeMeta(); + + writer.writeVersionsEntry( builder.build() ); } } - catch ( RepoDumpException e ) + catch ( Exception e ) { - LOG.error( "Cannot fully dump repository [{}] versions",repository.getId(), e ); - dumpResult.error( - DumpError.error( "Cannot fully dump repository [" + repository.getId() + "] versions: " + e.getMessage() ) ); + LOG.error( "Cannot fully dump repository [{}] versions", repository.getId(), e ); + dumpResult.error( DumpError.error( "Cannot fully dump repository [" + repository.getId() + "] versions: " + e.getMessage() ) ); + } + finally + { + writer.closeMeta(); } } @@ -200,17 +184,16 @@ private void dumpCommits() { final NodeCommitQuery nodeCommitQuery = NodeCommitQuery.create().size( -1 ).build(); - final NodeCommitEntries nodeCommitEntries = this.nodeService.findCommits( nodeCommitQuery ). - getNodeCommitEntries(); - - nodeCommitEntries.stream(). - map( nodeCommitEntry -> CommitDumpEntry.create(). - nodeCommitId( nodeCommitEntry.getNodeCommitId() ). - message( nodeCommitEntry.getMessage() ). - committer( nodeCommitEntry.getCommitter() ). - timestamp( nodeCommitEntry.getTimestamp() ). - build() ). - forEach( writer::writeCommitEntry ); + final NodeCommitEntries nodeCommitEntries = this.nodeService.findCommits( nodeCommitQuery ).getNodeCommitEntries(); + + nodeCommitEntries.stream() + .map( nodeCommitEntry -> CommitDumpEntry.create() + .nodeCommitId( nodeCommitEntry.getNodeCommitId() ) + .message( nodeCommitEntry.getMessage() ) + .committer( nodeCommitEntry.getCommitter() ) + .timestamp( nodeCommitEntry.getTimestamp() ) + .build() ) + .forEach( writer::writeCommitEntry ); } finally { @@ -218,16 +201,13 @@ private void dumpCommits() } } - private void doStoreVersion( final VersionsDumpEntry.Builder builder, final NodeVersionMetadata metaData, + private void doStoreVersion( final NodeVersionMetadata metaData, final RepoDumpResult.Builder dumpResult ) { try { - final NodeVersion nodeVersion = this.nodeService.getByNodeVersionKey( metaData.getNodeVersionKey() ); - builder.addVersion( VersionMetaFactory.create( metaData ) ); - storeVersionBlob( metaData.getNodeVersionId(), metaData.getNodeVersionKey() ); - storeVersionBinaries( metaData.getNodeVersionId(), nodeVersion ); + storeVersionBinaries( metaData.getNodeVersionId(), metaData.getBinaryBlobKeys() ); } catch ( Exception e ) { @@ -248,36 +228,33 @@ private void storeVersionBlob( final NodeVersionId nodeVersionId, final NodeVers } } - private void storeVersionBinaries( final NodeVersionId nodeVersionId, final NodeVersion nodeVersion ) + private void storeVersionBinaries( final NodeVersionId nodeVersionId, final BlobKeys attachedBinaries ) { - nodeVersion.getAttachedBinaries().forEach( ( attachedBinary ) -> { + attachedBinaries.forEach( ( attachedBinary ) -> { try { - this.writer.writeBinaryBlob( repository.getId(), BlobKey.from( attachedBinary.getBlobKey() ) ); + this.writer.writeBinaryBlob( repository.getId(), attachedBinary ); } catch ( Exception e ) { // Report - LOG.error( "Failed to write binary for nodeVersion " + nodeVersionId + ", binary " + attachedBinary.getBlobKey(), e ); + LOG.error( "Failed to write binary for nodeVersion " + nodeVersionId + ", binary " + attachedBinary, e ); } } ); } private Context setContext( final Branch branch ) { - return ContextBuilder.from( ContextAccessor.current() ). - repositoryId( repository.getId() ). - branch( branch ). - build(); + return ContextBuilder.from( ContextAccessor.current() ).repositoryId( repository.getId() ).branch( branch ).build(); } - private void doDumpNode( final NodeId nodeId, final BranchDumpResult.Builder dumpResult ) + private void doDumpNode( final NodeId nodeId, final Branch branch, final BranchDumpResult.Builder dumpResult ) { try { - final BranchDumpEntry branchDumpEntry = createDumpEntry( nodeId ); + final BranchDumpEntry branchDumpEntry = createDumpEntry( nodeId, branch ); writer.writeBranchEntry( branchDumpEntry ); - writer.writeNodeVersionBlobs( repository.getId(), branchDumpEntry.getMeta().getNodeVersionKey() ); + writer.writeNodeVersionBlobs( repository.getId(), branchDumpEntry.getMeta().nodeVersionKey() ); writeBinaries( dumpResult, branchDumpEntry.getBinaryReferences() ); dumpResult.addedNode(); this.listener.nodeDumped(); @@ -303,50 +280,37 @@ private void writeBinaries( final BranchDumpResult.Builder dumpResult, final Col } ); } - private BranchDumpEntry createDumpEntry( final NodeId nodeId ) + private BranchDumpEntry createDumpEntry( final NodeId nodeId, final Branch branch ) { - final BranchDumpEntry.Builder builder = BranchDumpEntry.create(). - nodeId( nodeId ); + final BranchDumpEntry.Builder builder = BranchDumpEntry.create().nodeId( nodeId ); final Node currentNode = this.nodeService.getById( nodeId ); - final NodeVersionMetadata currentVersionMetaData = getActiveVersion( nodeId ); - builder.meta( VersionMetaFactory.create( currentNode, currentVersionMetaData ) ); + final NodeVersionMetadata currentVersionMetaData = this.nodeService.getActiveVersions( + GetActiveNodeVersionsParams.create().nodeId( nodeId ).branches( Branches.from( branch ) ).build() ) + .getNodeVersions() + .get( branch ); + + builder.meta( VersionMetaFactory.create( currentVersionMetaData ) ); if ( this.includeBinaries ) { - builder.addBinaryReferences( - currentNode.getAttachedBinaries().stream().map( AttachedBinary::getBlobKey ).collect( Collectors.toSet() ) ); + builder.setBinaryReferences( + currentNode.getAttachedBinaries().stream().map( AttachedBinary::getBlobKey ).collect( Collectors.toList() ) ); } return builder.build(); } - private NodeVersionMetadata getActiveVersion( final NodeId nodeId ) - { - final Branch branch = ContextAccessor.current(). - getBranch(); - final GetActiveNodeVersionsParams params = GetActiveNodeVersionsParams.create().nodeId( nodeId ). - branches( Branches.from( branch ) ). - build(); - return this.nodeService.getActiveVersions( params ). - getNodeVersions(). - get( branch ); - } - private NodeVersionQueryResult getVersions( final NodeId nodeId ) { - final NodeVersionQuery.Builder queryBuilder = NodeVersionQuery.create(). - nodeId( nodeId ). - size( this.maxVersions != null ? this.maxVersions : -1 ); + final NodeVersionQuery.Builder queryBuilder = + NodeVersionQuery.create().nodeId( nodeId ).size( this.maxVersions != null ? this.maxVersions : -1 ); if ( this.maxAge != null ) { final Value ageValue = ValueFactory.newDateTime( Instant.now().minus( Duration.ofDays( this.maxAge ) ) ); - queryBuilder.addQueryFilter( RangeFilter.create(). - fieldName( VersionIndexPath.TIMESTAMP.getPath() ). - from( ageValue ). - build() ); + queryBuilder.addQueryFilter( RangeFilter.create().fieldName( VersionIndexPath.TIMESTAMP.getPath() ).from( ageValue ).build() ); } return this.nodeService.findVersions( queryBuilder.build() ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/VersionMetaFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/VersionMetaFactory.java index 301e33b2c4f..4e1d9fe52bb 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/VersionMetaFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/VersionMetaFactory.java @@ -1,30 +1,13 @@ package com.enonic.xp.repo.impl.dump; -import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.repo.impl.dump.model.VersionMeta; class VersionMetaFactory { - public static VersionMeta create( final Node node, final NodeVersionMetadata metaData ) - { - return VersionMeta.create(). - timestamp( node.getTimestamp() ). - nodePath( node.path() ). - version( node.getNodeVersionId() ). - nodeVersionKey( metaData.getNodeVersionKey() ). - nodeCommitId( metaData.getNodeCommitId() ). - build(); - } - public static VersionMeta create( final NodeVersionMetadata metaData ) { - return VersionMeta.create(). - timestamp( metaData.getTimestamp() ). - nodePath( metaData.getNodePath() ). - version( metaData.getNodeVersionId() ). - nodeVersionKey( metaData.getNodeVersionKey() ). - nodeCommitId( metaData.getNodeCommitId() ). - build(); + return new VersionMeta( metaData.getNodeVersionId(), metaData.getNodeVersionKey(), metaData.getNodePath(), metaData.getTimestamp(), + metaData.getNodeCommitId(), metaData.getAttributes() ); } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/BranchDumpEntry.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/BranchDumpEntry.java index 728a15b35fe..704a2d94932 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/BranchDumpEntry.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/BranchDumpEntry.java @@ -69,13 +69,7 @@ public Builder meta( final VersionMeta meta ) public Builder setBinaryReferences( final Collection references ) { - this.binaryReferences = ImmutableSet.builder().addAll( Objects.requireNonNullElse( references, List.of() ) ); - return this; - } - - public Builder addBinaryReferences( final Collection references ) - { - this.binaryReferences.addAll( references ); + this.binaryReferences = ImmutableSet.builder().addAll( references ); return this; } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/VersionMeta.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/VersionMeta.java index 21fef890980..b338256cd81 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/VersionMeta.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/model/VersionMeta.java @@ -2,56 +2,15 @@ import java.time.Instant; -import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeCommitId; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.NodeVersionKey; +import com.enonic.xp.node.Attributes; -public class VersionMeta +public record VersionMeta(NodeVersionId version, NodeVersionKey nodeVersionKey, NodePath nodePath, Instant timestamp, + NodeCommitId nodeCommitId, Attributes attributes) { - private final NodePath nodePath; - - private final Instant timestamp; - - private final NodeVersionId version; - - private final NodeVersionKey nodeVersionKey; - - private final NodeCommitId nodeCommitId; - - private VersionMeta( final Builder builder ) - { - nodePath = builder.nodePath; - timestamp = builder.timestamp; - version = builder.version; - nodeVersionKey = builder.nodeVersionKey; - nodeCommitId = builder.nodeCommitId; - } - - public NodePath getNodePath() - { - return nodePath; - } - - public Instant getTimestamp() - { - return timestamp; - } - - public NodeVersionId getVersion() - { - return version; - } - - public NodeVersionKey getNodeVersionKey() - { - return nodeVersionKey; - } - - public NodeCommitId getNodeCommitId() - { - return nodeCommitId; - } public static Builder create() { @@ -70,6 +29,8 @@ public static final class Builder private NodeCommitId nodeCommitId; + private Attributes attributes; + private Builder() { } @@ -104,54 +65,15 @@ public Builder nodeCommitId( final NodeCommitId val ) return this; } - public VersionMeta build() - { - return new VersionMeta( this ); - } - } - - @Override - public boolean equals( final Object o ) - { - if ( this == o ) - { - return true; - } - if ( o == null || getClass() != o.getClass() ) + public Builder attributes( final Attributes val ) { - return false; + attributes = val; + return this; } - final VersionMeta meta = (VersionMeta) o; - - if ( nodePath != null ? !nodePath.equals( meta.nodePath ) : meta.nodePath != null ) - { - return false; - } - if ( timestamp != null ? !timestamp.equals( meta.timestamp ) : meta.timestamp != null ) - { - return false; - } - if ( version != null ? !version.equals( meta.version ) : meta.version != null ) - { - return false; - } - if ( nodeVersionKey != null ? !nodeVersionKey.equals( meta.nodeVersionKey ) : meta.nodeVersionKey != null ) + public VersionMeta build() { - return false; + return new VersionMeta( version, nodeVersionKey, nodePath, timestamp, nodeCommitId, attributes ); } - return nodeCommitId != null ? nodeCommitId.equals( meta.nodeCommitId ) : meta.nodeCommitId == null; - - } - - @Override - public int hashCode() - { - int result = nodePath != null ? nodePath.hashCode() : 0; - result = 31 * result + ( timestamp != null ? timestamp.hashCode() : 0 ); - result = 31 * result + ( version != null ? version.hashCode() : 0 ); - result = 31 * result + ( nodeVersionKey != null ? nodeVersionKey.hashCode() : 0 ); - result = 31 * result + ( nodeCommitId != null ? nodeCommitId.hashCode() : 0 ); - return result; } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/AbstractEntryProcessor.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/AbstractEntryProcessor.java index fb104e92241..bc9adea44af 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/AbstractEntryProcessor.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/AbstractEntryProcessor.java @@ -33,7 +33,7 @@ class AbstractEntryProcessor final RepositoryId repositoryId; - AbstractEntryProcessor( final Builder builder ) + AbstractEntryProcessor( final Builder builder ) { blobStore = builder.blobStore; nodeService = builder.nodeService; @@ -69,13 +69,13 @@ private void reportBinaryError( final NodeVersion nodeVersion, final EntryLoadRe void reportVersionError( final EntryLoadResult.Builder result, final VersionMeta meta ) { final String message = - String.format( "Failed to load version for node with path %s, blobKey %s", meta.getNodePath(), meta.getVersion() ); + String.format( "Failed to load version for node with path %s, blobKey %s", meta.nodePath(), meta.version() ); result.error( EntryLoadError.error( message ) ); LOG.error( message ); } - public static class Builder + public static class Builder> { private BlobStore blobStore; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/BranchEntryProcessor.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/BranchEntryProcessor.java index c1a828a6260..6d031354e23 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/BranchEntryProcessor.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/BranchEntryProcessor.java @@ -11,6 +11,7 @@ import com.enonic.xp.node.LoadNodeParams; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeVersion; +import com.enonic.xp.repo.impl.branch.storage.NodeFactory; import com.enonic.xp.repo.impl.dump.RepoLoadException; import com.enonic.xp.repo.impl.dump.model.BranchDumpEntry; import com.enonic.xp.repo.impl.dump.model.VersionMeta; @@ -54,18 +55,13 @@ private void addNode( final EntryLoadResult.Builder result, final VersionMeta me return; } - final Node.Builder nodeBuilder = Node.create( nodeVersion ).nodeVersionId( meta.getVersion() ).timestamp( meta.getTimestamp().truncatedTo( ChronoUnit.MILLIS ) ); - if ( !nodeVersion.getId().equals( Node.ROOT_UUID ) ) - { - nodeBuilder.parentPath( meta.getNodePath().getParentPath() ).name( meta.getNodePath().getName() ); - } - try { - this.nodeService.loadNode( LoadNodeParams.create(). - node( nodeBuilder.build() ). - nodeCommitId( meta.getNodeCommitId() ). - build() ); + final Node node = NodeFactory.create( nodeVersion, meta.version(), meta.nodePath(), + meta.timestamp().truncatedTo( ChronoUnit.MILLIS ) ); + + this.nodeService.loadNode( + LoadNodeParams.create().node( node ).nodeCommitId( meta.nodeCommitId() ).attributes( meta.attributes() ).build() ); addBinary( nodeVersion, result ); @@ -74,7 +70,7 @@ private void addNode( final EntryLoadResult.Builder result, final VersionMeta me catch ( Exception e ) { final String message = - String.format( "Cannot load node with id %s, path %s: %s", nodeVersion.getId(), meta.getNodePath(), e.getMessage() ); + String.format( "Cannot load node with id %s, path %s: %s", nodeVersion.getId(), meta.nodePath(), e.getMessage() ); result.error( EntryLoadError.error( message ) ); LOG.error( message, e ); } @@ -84,11 +80,11 @@ private NodeVersion getVersion( final VersionMeta meta ) { try { - return this.dumpReader.get( repositoryId, meta.getNodeVersionKey() ); + return this.dumpReader.get( repositoryId, meta.nodeVersionKey() ); } catch ( RepoLoadException e ) { - LOG.error( "Cannot load version, missing in existing blobStore, and not present in dump: {}", meta.getVersion(), e ); + LOG.error( "Cannot load version, missing in existing blobStore, and not present in dump: {}", meta.version(), e ); return null; } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/VersionEntryProcessor.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/VersionEntryProcessor.java index 6b18c99be97..363bb8ff2fa 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/VersionEntryProcessor.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/reader/VersionEntryProcessor.java @@ -60,11 +60,11 @@ private void addVersions( final EntryLoadResult.Builder result, final VersionsDu { this.nodeService.importNodeVersion( ImportNodeVersionParams.create(). nodeId( versionsDumpEntry.getNodeId() ). - timestamp( version.getTimestamp() ). - nodePath( version.getNodePath() ). + timestamp( version.timestamp() ). + nodePath( version.nodePath() ). nodeVersion( nodeVersion ). - nodeVersionId( version.getVersion() ). - nodeCommitId( version.getNodeCommitId() ). + nodeVersionId( version.version() ). + nodeCommitId( version.nodeCommitId() ). build() ); addBinary( nodeVersion, result ); @@ -73,7 +73,7 @@ private void addVersions( final EntryLoadResult.Builder result, final VersionsDu catch ( Exception e ) { final String message = - String.format( "Cannot load version with id %s, path %s: %s", versionsDumpEntry.getNodeId(), version.getNodePath(), + String.format( "Cannot load version with id %s, path %s: %s", versionsDumpEntry.getNodeId(), version.nodePath(), e.getMessage() ); result.error( EntryLoadError.error( message ) ); LOG.error( message, e ); @@ -85,11 +85,11 @@ private NodeVersion getVersion( final VersionMeta meta ) { try { - return this.dumpReader.get( repositoryId, meta.getNodeVersionKey() ); + return this.dumpReader.get( repositoryId, meta.nodeVersionKey() ); } catch ( RepoLoadException e ) { - LOG.error( "Cannot load version, missing in existing blobStore, and not present in dump: " + meta.getVersion(), e ); + LOG.error( "Cannot load version, missing in existing blobStore, and not present in dump: " + meta.version(), e ); return null; } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/BranchDumpEntryJson.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/BranchDumpEntryJson.java index 3605be537e4..2e5b9a0d316 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/BranchDumpEntryJson.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/BranchDumpEntryJson.java @@ -1,6 +1,8 @@ package com.enonic.xp.repo.impl.dump.serializer.json; import java.util.Collection; +import java.util.Collections; +import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; @@ -41,8 +43,8 @@ public static BranchDumpEntry fromJson( final BranchDumpEntryJson json ) { return BranchDumpEntry.create(). nodeId( NodeId.from( json.getNodeId() ) ). - meta( VersionDumpEntryJson.fromJson( json.getMeta() ) ). - setBinaryReferences( json.getBinaries() ). + meta( VersionDumpEntryJson.fromJson( json.getMeta() ) ).setBinaryReferences( + Objects.requireNonNullElse( json.getBinaries(), Collections.emptyList() ) ). build(); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/VersionDumpEntryJson.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/VersionDumpEntryJson.java index 536d3a205e7..f158e1c0eb2 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/VersionDumpEntryJson.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/serializer/json/VersionDumpEntryJson.java @@ -39,6 +39,7 @@ public class VersionDumpEntryJson @JsonProperty("commitId") private String commitId; + @SuppressWarnings("unused") public VersionDumpEntryJson() { } @@ -72,13 +73,13 @@ public static VersionMeta fromJson( final VersionDumpEntryJson json ) public static VersionDumpEntryJson from( final VersionMeta meta ) { return VersionDumpEntryJson.create(). - nodePath( meta.getNodePath().toString() ). - timestamp( Objects.toString( meta.getTimestamp(), null ) ). - version( Objects.toString( meta.getVersion(), null ) ). - nodeBlobKey( meta.getNodeVersionKey().getNodeBlobKey().toString() ). - indexConfigBlobKey( meta.getNodeVersionKey().getIndexConfigBlobKey().toString() ). - accessControlBlobKey( meta.getNodeVersionKey().getAccessControlBlobKey().toString() ). - commitId( Objects.toString( meta.getNodeCommitId(), null ) ). + nodePath( meta.nodePath().toString() ). + timestamp( Objects.toString( meta.timestamp(), null ) ). + version( Objects.toString( meta.version(), null ) ). + nodeBlobKey( meta.nodeVersionKey().getNodeBlobKey().toString() ). + indexConfigBlobKey( meta.nodeVersionKey().getIndexConfigBlobKey().toString() ). + accessControlBlobKey( meta.nodeVersionKey().getAccessControlBlobKey().toString() ). + commitId( Objects.toString( meta.nodeCommitId(), null ) ). build(); } @@ -141,8 +142,6 @@ public static final class Builder private String accessControlBlobKey; - private String nodeState; - private String commitId; private Builder() diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/flattenedpage/FlattenedPageDataUpgrader.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/flattenedpage/FlattenedPageDataUpgrader.java index 0405fb2f40e..ee4c6d7693b 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/flattenedpage/FlattenedPageDataUpgrader.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/flattenedpage/FlattenedPageDataUpgrader.java @@ -56,7 +56,7 @@ public boolean upgrade( final PropertyTree nodeData ) if ( isFragmentPage( sourcePageSet ) ) { - final PropertySet sourcePageFragmentSet = sourcePageSet.getPropertySet( SRC_FRAGMENT_KEY ); + final PropertySet sourcePageFragmentSet = sourcePageSet.getSet( SRC_FRAGMENT_KEY ); addComponent( sourcePageFragmentSet, "/", nodeData ); } else diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6BranchDumpEntryJson.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6BranchDumpEntryJson.java index c34db5d1941..a86fcc94d4e 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6BranchDumpEntryJson.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6BranchDumpEntryJson.java @@ -23,13 +23,6 @@ public Pre6BranchDumpEntryJson() { } - private Pre6BranchDumpEntryJson( final String nodeId, final Collection binaries, final Pre6VersionDumpEntryJson meta ) - { - this.nodeId = nodeId; - this.binaries = binaries; - this.meta = meta; - } - private Pre6BranchDumpEntryJson( final Builder builder ) { nodeId = builder.nodeId; @@ -46,13 +39,6 @@ public static BranchDumpEntry fromJson( final Pre6BranchDumpEntryJson json ) build(); } - public static Pre6BranchDumpEntryJson from( final BranchDumpEntry branchDumpEntry ) - { - String nodeId = branchDumpEntry.getNodeId().toString(); - return new Pre6BranchDumpEntryJson( nodeId, branchDumpEntry.getBinaryReferences(), - Pre6VersionDumpEntryJson.from( branchDumpEntry.getMeta() ) ); - } - public static Builder create( final Pre6BranchDumpEntryJson source ) { return new Builder( source ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6VersionDumpEntryJson.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6VersionDumpEntryJson.java index a2de3ac6d9a..fa1fbd3fb31 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6VersionDumpEntryJson.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/dump/upgrade/obsoletemodel/pre6/Pre6VersionDumpEntryJson.java @@ -2,7 +2,6 @@ import java.time.Instant; -import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; @@ -35,6 +34,7 @@ public class Pre6VersionDumpEntryJson @JsonProperty("nodeState") private String nodeState; + @SuppressWarnings("unused") public Pre6VersionDumpEntryJson() { } @@ -64,18 +64,6 @@ public static VersionMeta fromJson( final Pre6VersionDumpEntryJson json ) .build(); } - public static Pre6VersionDumpEntryJson from( final VersionMeta meta ) - { - return Pre6VersionDumpEntryJson.create(). - nodePath( meta.getNodePath().toString() ). - timestamp( Objects.toString( meta.getTimestamp(), null ) ). - version( Objects.toString( meta.getVersion(), null ) ). - nodeBlobKey( meta.getNodeVersionKey().getNodeBlobKey().toString() ). - indexConfigBlobKey( meta.getNodeVersionKey().getIndexConfigBlobKey().toString() ). - accessControlBlobKey( meta.getNodeVersionKey().getAccessControlBlobKey().toString() ). - build(); - } - public static Builder create() { return new Builder(); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/document/indexitem/IndexItem.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/document/indexitem/IndexItem.java index 615cc3d0d6e..5c7b423a7aa 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/document/indexitem/IndexItem.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/document/indexitem/IndexItem.java @@ -1,7 +1,6 @@ package com.enonic.xp.repo.impl.elasticsearch.document.indexitem; import com.enonic.xp.index.IndexPath; -import com.enonic.xp.repo.impl.index.IndexFieldNameNormalizer; import com.enonic.xp.repo.impl.index.IndexValueTypeInterface; import static com.google.common.base.Strings.isNullOrEmpty; @@ -22,7 +21,7 @@ public abstract class IndexItem private String getBasePath() { - return IndexFieldNameNormalizer.normalize( indexPath.getPath() ); + return indexPath.getPath(); } public abstract IndexValueTypeInterface valueType(); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizer.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizer.java index f74985e43a4..dcda263ffe7 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizer.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizer.java @@ -1,26 +1,11 @@ package com.enonic.xp.repo.impl.index; -import java.util.Collection; +import com.enonic.xp.index.IndexPath; public class IndexFieldNameNormalizer { public static String normalize( final String path ) { - return doNormalize( path ); + return IndexPath.from( path ).getPath(); } - - private static String doNormalize( final String path ) - { - String normalized = path; - - normalized = normalized.toLowerCase().trim(); - - return normalized; - } - - public static String[] normalize( final Collection paths ) - { - return paths.stream().map( IndexFieldNameNormalizer::doNormalize ).toArray( String[]::new ); - } - } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java index 84e955bfb7c..fc3748c30e1 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java @@ -205,6 +205,7 @@ private NodeVersionData updatePermissionsInBranch( final NodeId nodeId, final No return NodeHelper.runAsAdmin( () -> { if ( updatedVersionData != null ) { + this.nodeStorageService.push( List.of( NodeBranchEntry.fromNodeVersionMetadata( updatedVersionMetadata ) ), branch, l -> { this.nodeStorageService.push( List.of( NodeBranchEntry.create() .nodeVersionId( updatedVersionData.node().getNodeVersionId() ) .nodePath( updatedVersionData.node().path() ) @@ -221,7 +222,7 @@ private NodeVersionData updatePermissionsInBranch( final NodeId nodeId, final No { final Node editedNode = Node.create( persistedNode ).timestamp( Instant.now( CLOCK ) ).permissions( permissions ) .build(); - final NodeVersionData result = this.nodeStorageService.store( StoreNodeParams.newVersion( editedNode ), targetContext ); + final NodeVersionData result = this.nodeStorageService.store( StoreNodeParams.newVersion( editedNode, params.getVersionAttributes() ), targetContext ); listener.permissionsApplied( 1 ); return result; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CompareStatusResolver.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CompareStatusResolver.java index ff97db9af6d..075affa53aa 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CompareStatusResolver.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CompareStatusResolver.java @@ -2,8 +2,8 @@ import java.util.Objects; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.context.ContextAccessor; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeNotFoundException; import com.enonic.xp.node.NodeVersionMetadata; @@ -40,45 +40,45 @@ public NodeComparison resolve() if ( source == null ) { - return new NodeComparison( null, null, target.getNodeId(), target.getNodePath(), CompareStatus.NEW_TARGET ); + return new NodeComparison( null, null, target.getNodeId(), target.getNodePath(), NodeCompareStatus.NEW_TARGET ); } else if ( target == null ) { - return new NodeComparison( source.getNodeId(), source.getNodePath(), null, null, CompareStatus.NEW ); + return new NodeComparison( source.getNodeId(), source.getNodePath(), null, null, NodeCompareStatus.NEW ); } if ( source.equals( target ) ) { return new NodeComparison( source.getNodeId(), source.getNodePath(), target.getNodeId(), target.getNodePath(), - CompareStatus.EQUAL ); + NodeCompareStatus.EQUAL ); } if ( !source.getNodePath().equals( target.getNodePath() ) ) { return new NodeComparison( source.getNodeId(), source.getNodePath(), target.getNodeId(), target.getNodePath(), - CompareStatus.MOVED ); + NodeCompareStatus.MOVED ); } return new NodeComparison( source.getNodeId(), source.getNodePath(), target.getNodeId(), target.getNodePath(), resolveFromVersion() ); } - private CompareStatus resolveFromVersion() + private NodeCompareStatus resolveFromVersion() { final NodeVersionMetadata sourceVersion = getVersion( this.source ); final NodeVersionMetadata targetVersion = getVersion( this.target ); if ( sourceVersion.getTimestamp().isAfter( targetVersion.getTimestamp() ) ) { - return CompareStatus.NEWER; + return NodeCompareStatus.NEWER; } if ( sourceVersion.getTimestamp().isBefore( targetVersion.getTimestamp() ) ) { - return CompareStatus.OLDER; + return NodeCompareStatus.OLDER; } - return CompareStatus.EQUAL; + return NodeCompareStatus.EQUAL; } private NodeVersionMetadata getVersion( final NodeBranchEntry nodeBranchEntry ) @@ -95,7 +95,7 @@ private NodeVersionMetadata getVersion( final NodeBranchEntry nodeBranchEntry ) return version; } - public static final class Builder + static final class Builder { private NodeBranchEntry source; @@ -130,7 +130,7 @@ private void validate() Objects.requireNonNull( this.nodeStorageService ); } - public CompareStatusResolver build() + CompareStatusResolver build() { this.validate(); return new CompareStatusResolver( this ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java index d9d33bcdf06..f17bb9a4389 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java @@ -89,8 +89,9 @@ public Node execute() .attachedBinaries( attachedBinaries ) .timestamp( this.timestamp != null ? this.timestamp : Instant.now( CLOCK ) ); - final Node newNode = this.nodeStorageService.store( StoreNodeParams.newVersion( nodeBuilder.build() ), - InternalContext.from( ContextAccessor.current() ) ).node(); + final Node newNode = + this.nodeStorageService.store( StoreNodeParams.newVersion( nodeBuilder.build(), params.getVersionAttributes() ), + InternalContext.from( ContextAccessor.current() ) ).node(); refresh( params.getRefresh() ); return newNode; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/DuplicateNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/DuplicateNodeCommand.java index c6f00e3d1c8..08803ccccc1 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/DuplicateNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/DuplicateNodeCommand.java @@ -13,6 +13,7 @@ import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.DuplicateNodeListener; import com.enonic.xp.node.DuplicateNodeParams; +import com.enonic.xp.node.DuplicateNodeResult; import com.enonic.xp.node.InsertManualStrategy; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeAlreadyExistAtPathException; @@ -114,6 +115,8 @@ private Node doDuplicateNode( final Node existingNode ) paramsBuilder.parent( params.getParent() ); } + paramsBuilder.versionAttributes( params.getVersionAttributes() ); + if ( params.getName() != null || params.getParent() != null ) { final CreateNodeParams processedParams = executeProcessors( paramsBuilder.build() ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryResultFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryResultFactory.java index b675de8f0f5..7fdf7fd2a79 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryResultFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryResultFactory.java @@ -26,12 +26,13 @@ static FindNodesByQueryResult create( final SearchResult result ) highlight( hit.getHighlightedProperties() ). sort( hit.getSortValues() ); - final String nodePath = (String) hit.getReturnValues().getSingleValue( NodeIndexPath.PATH.getPath() ); + final NodePath nodePath = hit.getReturnValues() + .getOptional( NodeIndexPath.PATH ) + .map( Object::toString ) + .map( NodePath::new ) + .orElse( null ); - if ( nodePath != null ) - { - nodeHit.nodePath( new NodePath( nodePath ) ); - } + nodeHit.nodePath( nodePath ); resultBuilder.addNodeHit( nodeHit.build() ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java index 5612559a045..e55d51b8dbd 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java @@ -5,9 +5,7 @@ import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodePaths; -import com.enonic.xp.node.NodeVersionDiffResult; import com.enonic.xp.repo.impl.InternalContext; -import com.enonic.xp.repo.impl.NodeBranchEntries; import com.enonic.xp.repo.impl.NodeBranchEntry; import com.enonic.xp.repo.impl.search.NodeSearchService; import com.enonic.xp.repo.impl.search.result.SearchResult; @@ -49,7 +47,12 @@ public NodeVersionDiffResult execute() { final InternalContext context = InternalContext.from( ContextAccessor.current() ); - final NodePaths excludeEntries = getExcludePaths( context ); + final NodePaths excludeEntries = excludes.isEmpty() + ? NodePaths.empty() + : this.nodeStorageService.getBranchNodeVersions( excludes, context ) + .stream() + .map( NodeBranchEntry::getNodePath ) + .collect( NodePaths.collector() ); final SearchResult result = this.nodeSearchService.query( NodeVersionDiffQuery.create() .source( source ) @@ -63,25 +66,6 @@ public NodeVersionDiffResult execute() return NodeVersionDiffResultFactory.create( result ); } - private NodePaths getExcludePaths( final InternalContext context ) - { - if ( this.excludes.isEmpty() ) - { - return NodePaths.empty(); - } - - final NodePaths.Builder builder = NodePaths.create(); - - final NodeBranchEntries result = this.nodeStorageService.getBranchNodeVersions( excludes, context ); - - for ( final NodeBranchEntry entry : result ) - { - builder.addNodePath( entry.getNodePath() ); - } - - return builder.build(); - } - public static final class Builder { private NodeSearchService nodeSearchService; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ImportNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ImportNodeCommand.java index 36ed4ee621c..1e9e7c6a10e 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ImportNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ImportNodeCommand.java @@ -18,6 +18,7 @@ import com.enonic.xp.security.RoleKeys; import com.enonic.xp.security.acl.AccessControlList; import com.enonic.xp.security.auth.AuthenticationInfo; +import com.enonic.xp.node.Attributes; public class ImportNodeCommand extends AbstractNodeCommand @@ -34,6 +35,8 @@ public class ImportNodeCommand private final boolean importPermissionsOnCreate; + private final Attributes versionAttributes; + private final RefreshMode refresh; private ImportNodeCommand( Builder builder ) @@ -46,7 +49,7 @@ private ImportNodeCommand( Builder builder ) this.importPermissions = builder.importPermissions; this.importPermissionsOnCreate = builder.importPermissionsOnCreate; this.refresh = builder.refresh; - + this.versionAttributes = builder.versionAttributes; } public static Builder create() @@ -111,6 +114,7 @@ private Node createNode() .name( this.importNode.name() ) .parent( this.importNode.parentPath() ) .permissions( permissions ) + .versionAttributes( versionAttributes ) .build(); node = CreateNodeCommand.create( this ) @@ -129,9 +133,8 @@ private Node updateNode( final Node existingNode ) final PatchNodeParams updateNodeParams = PatchNodeParams.create() .id( existingNode.id() ) .setBinaryAttachments( this.binaryAttachments ) - .editor( editableNode -> { - editableNode.data = this.importNode.data(); - } ) + .editor( editableNode -> editableNode.data = this.importNode.data() ) + .versionAttributes( this.versionAttributes ) .refresh( RefreshMode.ALL ) .build(); @@ -196,6 +199,8 @@ public static final class Builder private boolean importPermissionsOnCreate = true; + private Attributes versionAttributes; + private RefreshMode refresh; private Builder() @@ -238,6 +243,12 @@ public Builder importPermissionsOnCreate( boolean importPermissionsOnCreate ) return this; } + public Builder versionAttributes( final Attributes attributes ) + { + this.versionAttributes = attributes; + return this; + } + public Builder refresh( final RefreshMode refresh ) { this.refresh = refresh; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/LoadNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/LoadNodeCommand.java index 386322fd477..c50b32683e6 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/LoadNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/LoadNodeCommand.java @@ -52,11 +52,7 @@ private LoadNodeResult loadNode() verifyParentExists(); deleteIfExistsAtPath(); - final StoreNodeParams storeNodeParams = StoreNodeParams.create(). - node( params.getNode() ). - nodeCommitId( params.getNodeCommitId() ). - overrideVersion(). - build(); + final StoreNodeParams storeNodeParams = StoreNodeParams.overrideVersion( params.getNode(), params.getNodeCommitId(), params.getAttributes() ); final Node loadedNode = this.nodeStorageService.store( storeNodeParams, InternalContext.from( ContextAccessor.current() ) ).node(); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/MoveNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/MoveNodeCommand.java index b0101230cab..8496aeef717 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/MoveNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/MoveNodeCommand.java @@ -8,10 +8,10 @@ import com.enonic.xp.context.ContextBuilder; import com.enonic.xp.node.MoveNodeException; import com.enonic.xp.node.MoveNodeListener; +import com.enonic.xp.node.MoveNodeParams; import com.enonic.xp.node.MoveNodeResult; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeAlreadyExistAtPathException; -import com.enonic.xp.node.NodeDataProcessor; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIndexPath; import com.enonic.xp.node.NodeName; @@ -36,15 +36,7 @@ public class MoveNodeCommand extends AbstractNodeCommand { - private final NodeId nodeId; - - private final NodePath newParentPath; - - private final NodeName newNodeName; - - private final RefreshMode refresh; - - private final NodeDataProcessor processor; + private final MoveNodeParams params; private final MoveNodeListener moveListener; @@ -53,13 +45,9 @@ public class MoveNodeCommand private MoveNodeCommand( final Builder builder ) { super( builder ); - this.nodeId = builder.id; - this.newParentPath = builder.newParentPath; - this.newNodeName = builder.newNodeName; - this.moveListener = Objects.requireNonNullElse( builder.moveListener, count -> { + this.params = builder.params; + this.moveListener = Objects.requireNonNullElse( builder.params.getMoveListener(), count -> { } ); - this.processor = builder.processor; - this.refresh = builder.refresh; this.result = MoveNodeResult.create(); } @@ -68,18 +56,13 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - public MoveNodeResult execute() { - final Node existingNode = doGetById( nodeId ); + final Node existingNode = doGetById( params.getNodeId() ); if ( existingNode == null ) { - throw new NodeNotFoundException( "cannot rename/move node with id [" + nodeId + "]" ); + throw new NodeNotFoundException( "cannot rename/move node with id [" + params.getNodeId() + "]" ); } if ( existingNode.isRoot() ) @@ -89,13 +72,14 @@ public MoveNodeResult execute() final NodeName newNodeName = resolveNodeName( existingNode ); - final NodePath newParentPath = Objects.requireNonNullElseGet( this.newParentPath, existingNode::parentPath ); + final NodePath newParentPath = Objects.requireNonNullElseGet( params.getNewParentPath(), existingNode::parentPath ); final Context context = ContextAccessor.current(); if ( noChanges( existingNode, newParentPath, newNodeName ) ) { - throw new NodeAlreadyExistAtPathException( new NodePath( newParentPath, newNodeName ), context.getRepositoryId(), context.getBranch() ); + throw new NodeAlreadyExistAtPathException( new NodePath( newParentPath, newNodeName ), context.getRepositoryId(), + context.getBranch() ); } checkNotMovedToSelfOrChild( existingNode, newParentPath, newNodeName ); @@ -110,9 +94,9 @@ public MoveNodeResult execute() .authInfo( AuthenticationInfo.copyOf( context.getAuthInfo() ).principals( RoleKeys.ADMIN ).build() ) .build(); - adminContext.callWith( () -> doMoveNode( newParentPath, newNodeName, nodeId ) ); + adminContext.callWith( () -> doMoveNode( newParentPath, newNodeName, params.getNodeId() ) ); - refresh( refresh ); + refresh( params.getRefresh() ); return result.build(); } @@ -131,16 +115,7 @@ private void checkContextUserPermissionOrAdmin( final NodePath newParentPath ) private NodeName resolveNodeName( final Node existingNode ) { - final NodeName newNodeName; - if ( this.newNodeName == null ) - { - newNodeName = existingNode.name(); - } - else - { - newNodeName = this.newNodeName; - } - return newNodeName; + return params.getNewNodeName() == null ? existingNode.name() : params.getNewNodeName(); } private void checkNotMovedToSelfOrChild( final Node existingNode, final NodePath newParentPath, final NodeName newNodeName ) @@ -164,12 +139,12 @@ private Node doMoveNode( final NodePath newParentPath, final NodeName newNodeNam final Node.Builder nodeToMoveBuilder = Node.create( persistedNode ) .name( newNodeName ) .data( - processor.process( persistedNode.data(), NodePath.create( newParentPath ).addElement( newNodeName ).build() ) ) + params.getProcessor().process( persistedNode.data(), NodePath.create( newParentPath ).addElement( newNodeName ).build() ) ) .parentPath( newParentPath ) .indexConfigDocument( persistedNode.getIndexConfigDocument() ) .timestamp( Instant.now( CLOCK ) ); - final boolean isTheOriginalMovedNode = persistedNode.id().equals( this.nodeId ); + final boolean isTheOriginalMovedNode = persistedNode.id().equals( params.getNodeId() ); if ( isTheOriginalMovedNode ) { final boolean isRenaming = newParentPath.equals( persistedNode.parentPath() ); @@ -188,7 +163,7 @@ private Node doMoveNode( final NodePath newParentPath, final NodeName newNodeNam final InternalContext internalContext = InternalContext.from( ContextAccessor.current() ); final Node movedNode = - this.nodeStorageService.store( StoreNodeParams.create().node( nodeToMoveBuilder.build() ).build(), internalContext ).node(); + this.nodeStorageService.store( StoreNodeParams.newVersion( nodeToMoveBuilder.build(), params.getVersionAttributes() ), internalContext ).node(); this.nodeStorageService.invalidatePath( persistedNode.path(), internalContext ); this.result.addMovedNode( MoveNodeResult.MovedNode.create().previousPath( persistedNode.path() ).node( movedNode ).build() ); @@ -204,7 +179,7 @@ private Node doMoveNode( final NodePath newParentPath, final NodeName newNodeNam for ( final SearchHit nodeBranchEntry : children.getHits() ) { doMoveNode( movedNode.path(), - NodeName.from( (String) nodeBranchEntry.getField( NodeIndexPath.NAME.toString() ).getSingleValue() ), + NodeName.from( nodeBranchEntry.getReturnValues().getStringValue( NodeIndexPath.NAME ) ), NodeId.from( nodeBranchEntry.getId() ) ); } @@ -219,61 +194,16 @@ private void verifyNoExistingAtNewPath( final NodePath newParentPath, final Node public static class Builder extends AbstractNodeCommand.Builder { - private NodeId id; - - private NodePath newParentPath; - - private NodeName newNodeName; - - private NodeDataProcessor processor = ( n, p ) -> n; - - private MoveNodeListener moveListener; - - private RefreshMode refresh; + private MoveNodeParams params; private Builder() { super(); } - private Builder( final AbstractNodeCommand source ) + public Builder params( final MoveNodeParams params ) { - super( source ); - } - - public Builder id( final NodeId nodeId ) - { - this.id = nodeId; - return this; - } - - public Builder newParent( final NodePath parentNodePath ) - { - this.newParentPath = parentNodePath; - return this; - } - - public Builder newNodeName( final NodeName nodeName ) - { - this.newNodeName = nodeName; - return this; - } - - public Builder moveListener( final MoveNodeListener moveListener ) - { - this.moveListener = moveListener; - return this; - } - - public Builder processor( final NodeDataProcessor processor ) - { - this.processor = processor; - return this; - } - - public Builder refresh( final RefreshMode refresh ) - { - this.refresh = refresh; + this.params = params; return this; } @@ -287,14 +217,7 @@ public MoveNodeCommand build() void validate() { super.validate(); - Objects.requireNonNull( id, "id is required" ); - Objects.requireNonNull( processor, "processor cant be null" ); - - if ( this.newParentPath == null && this.newNodeName == null ) - { - throw new IllegalArgumentException( "Must provide either newNodeName or newParentPath" ); - } - + Objects.requireNonNull( params, "params cannot be null" ); } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java index c9d34be86ec..5846579ed6f 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java @@ -21,10 +21,13 @@ import com.enonic.xp.event.EventPublisher; import com.enonic.xp.node.ApplyNodePermissionsParams; import com.enonic.xp.node.ApplyNodePermissionsResult; +import com.enonic.xp.node.Attributes; +import com.enonic.xp.node.CommitNodeParams; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.DeleteNodeParams; import com.enonic.xp.node.DeleteNodeResult; import com.enonic.xp.node.DuplicateNodeParams; +import com.enonic.xp.node.DuplicateNodeResult; import com.enonic.xp.node.FindNodesByMultiRepoQueryResult; import com.enonic.xp.node.FindNodesByParentParams; import com.enonic.xp.node.FindNodesByParentResult; @@ -58,12 +61,14 @@ import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionId; import com.enonic.xp.node.NodeVersionKey; +import com.enonic.xp.node.NodeVersionIds; +import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeVersionQuery; import com.enonic.xp.node.NodeVersionQueryResult; import com.enonic.xp.node.Nodes; import com.enonic.xp.node.PatchNodeParams; import com.enonic.xp.node.PatchNodeResult; -import com.enonic.xp.node.PushNodesListener; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodesResult; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.node.ResolveSyncWorkResult; @@ -78,6 +83,7 @@ import com.enonic.xp.query.expr.OrderExpr; import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.NodeBranchEntries; +import com.enonic.xp.repo.impl.NodeBranchEntry; import com.enonic.xp.repo.impl.NodeEvents; import com.enonic.xp.repo.impl.SearchPreference; import com.enonic.xp.repo.impl.binary.BinaryService; @@ -380,7 +386,9 @@ public Node update( final UpdateNodeParams params ) { verifyContext(); - final PatchNodeResult result = PatchNodeCommand.create().params( convertUpdateParams( params ) ).binaryService( this.binaryService ) + final PatchNodeResult result = PatchNodeCommand.create() + .params( convertUpdateParams( params ) ) + .binaryService( this.binaryService ) .indexServiceInternal( this.indexServiceInternal ) .storageService( this.nodeStorageService ) .searchService( this.nodeSearchService ) @@ -446,12 +454,7 @@ public MoveNodeResult move( final MoveNodeParams params ) { verifyContext(); final MoveNodeResult moveNodeResult = MoveNodeCommand.create() - .id( params.getNodeId() ) - .newNodeName( params.getNewNodeName() ) - .newParent( params.getNewParentPath() ) - .moveListener( params.getMoveListener() ) - .processor( params.getProcessor() ) - .refresh( params.getRefresh() ) + .params( params ) .indexServiceInternal( this.indexServiceInternal ) .storageService( this.nodeStorageService ) .searchService( this.nodeSearchService ) @@ -496,28 +499,25 @@ public DeleteNodeResult delete( final DeleteNodeParams deleteNodeParams ) this.eventPublisher.publish( NodeEvents.deleted( deletedNodes, InternalContext.from( ContextAccessor.current() ) ) ); } - return DeleteNodeResult.create().nodeIds( NodeIds.from( deletedNodes.getKeys() ) ).build(); - } - - @Override - public PushNodesResult push( final NodeIds ids, final Branch target ) - { - return push( ids, target, null ); + final DeleteNodeResult.Builder builder = DeleteNodeResult.create(); + for ( NodeBranchEntry deletedNode : deletedNodes ) + { + builder.add( new DeleteNodeResult.Result( deletedNode.getNodeId(), deletedNode.getVersionId() ) ); + } + return builder.build(); } @Override - public PushNodesResult push( final NodeIds ids, final Branch target, final PushNodesListener pushListener ) + public PushNodesResult push( final PushNodeParams params ) { verifyContext(); - verifyBranchExists( target, ContextAccessor.current().getRepositoryId() ); + verifyBranchExists( params.getTarget(), ContextAccessor.current().getRepositoryId() ); final PushNodesResult pushNodesResult = PushNodesCommand.create() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.nodeStorageService ) .searchService( this.nodeSearchService ) - .ids( ids ) - .target( target ) - .pushListener( pushListener ) + .params( params ) .build() .execute(); @@ -525,7 +525,7 @@ public PushNodesResult push( final NodeIds ids, final Branch target, final PushN { this.eventPublisher.publish( NodeEvents.pushed( pushNodesResult.getSuccessful(), InternalContext.create( ContextAccessor.current() ) - .branch( target ) + .branch( params.getTarget() ) .build() ) ); } @@ -533,7 +533,7 @@ public PushNodesResult push( final NodeIds ids, final Branch target, final PushN } @Override - public Node duplicate( final DuplicateNodeParams params ) + public DuplicateNodeResult duplicate( final DuplicateNodeParams params ) { verifyContext(); final DuplicateNodeResult result = DuplicateNodeCommand.create() @@ -550,7 +550,7 @@ public Node duplicate( final DuplicateNodeParams params ) this.eventPublisher.publish( NodeEvents.duplicated( result.getNode(), internalContext ) ); result.getChildren().forEach( child -> this.eventPublisher.publish( NodeEvents.created( child, internalContext ) ) ); - return result.getNode(); + return result; } @Override @@ -797,6 +797,7 @@ public ImportNodeResult importNode( final ImportNodeParams params ) .refresh( params.getRefresh() ) .importPermissions( params.isImportPermissions() ) .importPermissionsOnCreate( params.isImportPermissionsOnCreate() ) + .versionAttributes( params.getVersionAttributes() ) .binaryBlobStore( this.binaryService ) .indexServiceInternal( this.indexServiceInternal ) .storageService( this.nodeStorageService ) @@ -903,15 +904,19 @@ public void importNodeCommit( final ImportNodeCommitParams params ) } @Override - public NodeCommitEntry commit( final NodeCommitEntry nodeCommitEntry, final RoutableNodeVersionIds routableNodeVersionIds ) + public NodeCommitEntry commit( final CommitNodeParams params ) { verifyContext(); - final NodeCommitEntry commit = - nodeStorageService.commit( nodeCommitEntry, routableNodeVersionIds, InternalContext.from( ContextAccessor.current() ) ); - - refresh( RefreshMode.STORAGE ); + return doCommit( params.getNodeCommitEntry(), params.getNodeVersionIds() ); + } - return commit; + @Override + public NodeCommitEntry commit( final NodeCommitEntry nodeCommitEntry, final RoutableNodeVersionIds routableNodeVersionIds ) + { + verifyContext(); + return doCommit( nodeCommitEntry, routableNodeVersionIds.stream() + .map( RoutableNodeVersionId::getNodeVersionId ) + .collect( NodeVersionIds.collector() ) ); } @Override @@ -922,16 +927,38 @@ public NodeCommitEntry commit( final NodeCommitEntry nodeCommitEntry, final Node final InternalContext context = InternalContext.create( ContextAccessor.current() ).searchPreference( SearchPreference.PRIMARY ).build(); - final NodeBranchEntries branchNodeVersions = nodeStorageService.getBranchNodeVersions( nodeIds, context ); - final RoutableNodeVersionIds routableNodeVersionIds = branchNodeVersions.stream() - .map( branchEntry -> RoutableNodeVersionId.from( branchEntry.getNodeId(), branchEntry.getVersionId() ) ) - .collect( RoutableNodeVersionIds.collector() ); + final NodeVersionIds nodeVersionIds = nodeStorageService.getBranchNodeVersions( nodeIds, context ) + .stream() + .map( NodeBranchEntry::getVersionId ) + .collect( NodeVersionIds.collector() ); + + return doCommit( nodeCommitEntry , nodeVersionIds ); + } + + private NodeCommitEntry doCommit( NodeCommitEntry entry, NodeVersionIds versionIds ) + { + verifyContext(); + + final InternalContext context = + InternalContext.create( ContextAccessor.current() ).searchPreference( SearchPreference.PRIMARY ).build(); - final NodeCommitEntry commitEntry = nodeStorageService.commit( nodeCommitEntry, routableNodeVersionIds, context ); + final NodeCommitEntry commit = nodeStorageService.commit( entry, versionIds, context ); refresh( RefreshMode.STORAGE ); - return commitEntry; + return commit; + } + + @Override + public void addAttributes( final NodeVersionId nodeVersionId, final Attributes attributes ) + { + verifyContext(); + + final InternalContext context = + InternalContext.create( ContextAccessor.current() ).searchPreference( SearchPreference.PRIMARY ).build(); + nodeStorageService.setAttribute( nodeVersionId, attributes, context ); + + refresh( RefreshMode.STORAGE ); } @Override @@ -984,6 +1011,7 @@ private PatchNodeParams convertUpdateParams( final UpdateNodeParams params ) .path( params.getPath() ) .editor( params.getEditor() ) .setBinaryAttachments( params.getBinaryAttachments() ) + .versionAttributes( params.getVersionAttributes() ) .refresh( params.getRefresh() ) .addBranches( Branches.from( ContextAccessor.current().getBranch() ) ) .build(); diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeVersionDiffResult.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeVersionDiffResult.java similarity index 91% rename from modules/core/core-api/src/main/java/com/enonic/xp/node/NodeVersionDiffResult.java rename to modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeVersionDiffResult.java index 1d03b303b28..5bd06cafb78 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeVersionDiffResult.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeVersionDiffResult.java @@ -1,8 +1,9 @@ -package com.enonic.xp.node; +package com.enonic.xp.repo.impl.node; -import com.enonic.xp.annotation.PublicApi; -@PublicApi +import com.enonic.xp.node.NodeId; +import com.enonic.xp.node.NodeIds; + public final class NodeVersionDiffResult { private final NodeIds nodesWithDifferences; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeVersionDiffResultFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeVersionDiffResultFactory.java index 7946ee113c6..47c84195ff2 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeVersionDiffResultFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeVersionDiffResultFactory.java @@ -1,7 +1,6 @@ package com.enonic.xp.repo.impl.node; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeVersionDiffResult; import com.enonic.xp.repo.impl.search.result.SearchHit; import com.enonic.xp.repo.impl.search.result.SearchResult; import com.enonic.xp.repo.impl.version.VersionIndexPath; @@ -24,7 +23,7 @@ public static NodeVersionDiffResult create( final SearchResult result ) for ( final SearchHit hit : result.getHits() ) { - builder.add( NodeId.from( hit.getField( VersionIndexPath.NODE_ID.toString() ).getSingleValue() ) ); + builder.add( NodeId.from( hit.getReturnValues().getStringValue( VersionIndexPath.NODE_ID ) ) ); } return builder.build(); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java index 4f46ddecb8f..de551e498e9 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java @@ -170,6 +170,7 @@ private NodeVersionData patchNodeInBranch( final NodeVersionData patchedNode, fi .nodeId( patchedNode.node().id() ) .timestamp( patchedNode.node().getTimestamp() ) .build() ), branch, l -> { + this.nodeStorageService.push( List.of( NodeBranchEntry.fromNodeVersionMetadata( patchedVersionMetadata ) ), branch, l -> { }, internalContext ); return patchedNode; @@ -198,7 +199,7 @@ private NodeVersionData patchNodeInBranch( final NodeVersionData patchedNode, fi final Node updatedNode = Node.create( editedNode ).timestamp( Instant.now( CLOCK ) ).attachedBinaries( updatedBinaries ).build(); - return this.nodeStorageService.store( StoreNodeParams.newVersion( updatedNode ), internalContext ); + return this.nodeStorageService.store( StoreNodeParams.newVersion( updatedNode, params.getVersionAttributes() ), internalContext ); } } @@ -245,11 +246,6 @@ private Builder() super(); } - private Builder( final AbstractNodeCommand source ) - { - super( source ); - } - public Builder params( final PatchNodeParams params ) { this.params = params; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java index 1da1ac17682..973ea32956e 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java @@ -1,5 +1,6 @@ package com.enonic.xp.repo.impl.node; +import java.time.Instant; import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; @@ -8,17 +9,20 @@ import java.util.Set; import java.util.stream.Collectors; -import com.enonic.xp.branch.Branch; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.context.Context; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.context.ContextBuilder; +import com.enonic.xp.data.PropertyTree; +import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeComparisons; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodeIndexPath; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeQuery; +import com.enonic.xp.node.NodeVersion; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodeResult; import com.enonic.xp.node.PushNodesListener; import com.enonic.xp.node.PushNodesResult; @@ -30,28 +34,30 @@ import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.NodeBranchEntries; import com.enonic.xp.repo.impl.NodeBranchEntry; +import com.enonic.xp.repo.impl.SearchPreference; import com.enonic.xp.repo.impl.SingleRepoSearchSource; import com.enonic.xp.repo.impl.search.NodeSearchService; +import com.enonic.xp.repo.impl.storage.NodeVersionData; +import com.enonic.xp.repo.impl.storage.StoreNodeParams; import com.enonic.xp.security.RoleKeys; import com.enonic.xp.security.acl.AccessControlList; import com.enonic.xp.security.acl.Permission; import com.enonic.xp.security.auth.AuthenticationInfo; +import static com.enonic.xp.repo.impl.node.NodeConstants.CLOCK; + public class PushNodesCommand extends AbstractNodeCommand { - private final Branch target; - - private final NodeIds ids; + private final PushNodeParams params; private final PushNodesListener pushListener; private PushNodesCommand( final Builder builder ) { super( builder ); - this.target = builder.target; - this.ids = builder.ids; - this.pushListener = Objects.requireNonNullElse( builder.pushListener, c -> { + this.params = builder.params; + this.pushListener = Objects.requireNonNullElse( params.getPushListener(), c -> { } ); } @@ -64,16 +70,17 @@ public PushNodesResult execute() { refresh( RefreshMode.ALL ); - final InternalContext internalContext = InternalContext.from( ContextAccessor.current() ); + final InternalContext internalContext = + InternalContext.create( ContextAccessor.current() ).searchPreference( SearchPreference.PRIMARY ).build(); - NodeIds.Builder allIdsBuilder = NodeIds.create().addAll( ids ); + NodeIds.Builder allIdsBuilder = NodeIds.create().addAll( params.getIds() ); - final NodeComparisons comparisons = getNodeComparisons( ids ); + final NodeComparisons comparisons = getNodeComparisons( params.getIds() ); final SingleRepoSearchSource targetSearchSource = SingleRepoSearchSource.from( targetContext() ); for ( NodeComparison comparison : comparisons ) { - if ( comparison.getCompareStatus() == CompareStatus.MOVED ) + if ( comparison.getCompareStatus() == NodeCompareStatus.MOVED ) { final NodeIds childrenIds = NodeIds.from( this.nodeSearchService.query( NodeQuery.create() .query( QueryExpr.from( CompareExpr.like( @@ -82,8 +89,7 @@ public PushNodesResult execute() comparison.getTargetPath() + "/*" ) ) ) ) .size( NodeSearchService.GET_ALL_SIZE_FLAG ) - .build(), targetSearchSource ) - .getIds() ); + .build(), targetSearchSource ).getIds() ); allIdsBuilder.addAll( childrenIds ); } } @@ -94,7 +100,7 @@ public PushNodesResult execute() final NodeBranchEntries nodeBranchEntries = this.nodeStorageService.getBranchNodeVersions( allIds, internalContext ); final PushNodesResult.Builder builder = PushNodesResult.create(); - final List successfulPush = new ArrayList<>(); + List successfulPush = new ArrayList<>(); final List list = nodeBranchEntries.stream().sorted( Comparator.comparing( NodeBranchEntry::getNodePath ) ).collect( Collectors.toList() ); @@ -111,25 +117,28 @@ public PushNodesResult execute() this.nodeStorageService.getNodePermissions( branchEntry.getNodeVersionKey(), internalContext ); if ( !NodePermissionsResolver.userHasPermission( authInfo, Permission.PUBLISH, nodePermissions ) ) { - builder.add( PushNodeResult.failure( branchEntry.getNodeId(), branchEntry.getNodePath(), PushNodeResult.Reason.ACCESS_DENIED) ); + builder.add( + PushNodeResult.failure( branchEntry.getNodeId(), branchEntry.getNodePath(), PushNodeResult.Reason.ACCESS_DENIED ) ); pushListener.nodesPushed( 1 ); continue; } } - final CompareStatus compareStatus = comparison.getCompareStatus(); + final NodeCompareStatus compareStatus = comparison.getCompareStatus(); - if ( compareStatus == CompareStatus.EQUAL ) + if ( compareStatus == NodeCompareStatus.EQUAL ) { - builder.add( PushNodeResult.success( branchEntry.getNodeId(), branchEntry.getVersionId(), branchEntry.getNodePath(), - comparison.getTargetPath() ) ); + final NodeBranchEntry processed = processBeforePush( branchEntry, internalContext ); + successfulPush.add( processed ); alreadyAdded.add( branchEntry.getNodePath() ); - successfulPush.add( branchEntry ); + builder.add( PushNodeResult.success( processed.getNodeId(), processed.getVersionId(), processed.getNodePath(), + comparison.getTargetPath() ) ); + pushListener.nodesPushed( 1 ); continue; } - if ( ( CompareStatus.NEW == compareStatus || CompareStatus.MOVED == compareStatus ) && + if ( ( NodeCompareStatus.NEW == compareStatus || NodeCompareStatus.MOVED == compareStatus ) && targetAlreadyExists( branchEntry.getNodePath(), comparisons ) ) { builder.add( @@ -147,15 +156,17 @@ public PushNodesResult execute() continue; } - builder.add( PushNodeResult.success( branchEntry.getNodeId(), branchEntry.getVersionId(), branchEntry.getNodePath(), comparison.getTargetPath() ) ); - successfulPush.add( branchEntry ); + final NodeBranchEntry processed = processBeforePush( branchEntry, internalContext ); + successfulPush.add( processed ); alreadyAdded.add( branchEntry.getNodePath() ); + builder.add( PushNodeResult.success( processed.getNodeId(), processed.getVersionId(), processed.getNodePath(), + comparison.getTargetPath() ) ); } final PushNodesResult result = builder.build(); + this.nodeStorageService.push( successfulPush, params.getTarget(), pushListener, internalContext ); - this.nodeStorageService.push( successfulPush, target, pushListener, internalContext ); - final InternalContext targetContext = InternalContext.create( internalContext ).branch( target ).build(); + final InternalContext targetContext = InternalContext.create( internalContext ).branch( params.getTarget() ).build(); for ( PushNodeResult pushNodeResult : result.getSuccessful() ) { final NodePath targetPath = pushNodeResult.getTargetPath(); @@ -174,16 +185,42 @@ private NodeComparisons getNodeComparisons( final NodeIds nodeIds ) return CompareNodesCommand.create() .nodeIds( nodeIds ) .storageService( this.nodeStorageService ) - .target( this.target ) + .target( params.getTarget() ) .build() .execute(); } + private NodeBranchEntry processBeforePush( NodeBranchEntry nbe, InternalContext internalContext ) + { + if ( params.getProcessor() == null ) + { + return nbe; + } + final NodeVersion version = this.nodeStorageService.getNodeVersion( nbe.getNodeVersionKey(), internalContext ); + + final PropertyTree processedData = params.getProcessor().process( version.getData(), nbe.getNodePath() ); + if ( processedData.equals( version.getData() ) ) + { + return nbe; + } + + final Node changedNode = Node.create( version ) + .name( nbe.getNodePath().getName() ) + .parentPath( nbe.getNodePath().getParentPath() ) + .data( processedData ) + .timestamp( Instant.now( CLOCK ) ) + .build(); + + final NodeVersionData stored = this.nodeStorageService.store( StoreNodeParams.newVersion( changedNode ), internalContext ); + + return NodeBranchEntry.fromNodeVersionMetadata( stored.nodeVersionMetadata() ); + } + private boolean targetAlreadyExists( final NodePath nodePath, final NodeComparisons comparisons ) { //Checks if a node exist - final NodeBranchEntry parentNodeBranchEntry = - targetContext().callWith( () -> this.nodeStorageService.getBranchNodeVersion( nodePath, InternalContext.from( ContextAccessor.current() ) ) ); + final NodeBranchEntry parentNodeBranchEntry = targetContext().callWith( + () -> this.nodeStorageService.getBranchNodeVersion( nodePath, InternalContext.from( ContextAccessor.current() ) ) ); //If the node does not exist, returns false if ( parentNodeBranchEntry == null ) @@ -193,7 +230,7 @@ private boolean targetAlreadyExists( final NodePath nodePath, final NodeComparis //Else, if the existing node is being moved during the current push, returns false final NodeComparison nodeComparison = comparisons.get( parentNodeBranchEntry.getNodeId() ); - return nodeComparison == null || CompareStatus.MOVED != nodeComparison.getCompareStatus(); + return nodeComparison == null || NodeCompareStatus.MOVED != nodeComparison.getCompareStatus(); } private boolean targetParentExists( final NodePath nodePath ) @@ -210,7 +247,7 @@ private Context targetContext() { final Context context = ContextAccessor.current(); return ContextBuilder.from( context ) - .branch( target ) + .branch( params.getTarget() ) .authInfo( AuthenticationInfo.copyOf( context.getAuthInfo() ).principals( RoleKeys.ADMIN ).build() ) .build(); } @@ -218,32 +255,16 @@ private Context targetContext() public static class Builder extends AbstractNodeCommand.Builder { - private Branch target; - - private NodeIds ids; - - private PushNodesListener pushListener; + private PushNodeParams params; Builder() { super(); } - public Builder target( final Branch target ) - { - this.target = target; - return this; - } - - public Builder ids( final NodeIds nodeIds ) - { - this.ids = nodeIds; - return this; - } - - public Builder pushListener( final PushNodesListener pushListener ) + public Builder params( final PushNodeParams params ) { - this.pushListener = pushListener; + this.params = params; return this; } @@ -257,8 +278,7 @@ public PushNodesCommand build() void validate() { super.validate(); - Objects.requireNonNull( target, "target is required" ); - Objects.requireNonNull( ids, "ids is required" ); + Objects.requireNonNull( params, "params cannon be null" ); } } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java index 3d7e6b933bf..dbc646cec46 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java @@ -80,7 +80,7 @@ private Long getManualOrderValue( ChildOrder childOrder, Long referenceValue ) { final SearchHit hit = searchResult.getHits().getFirst(); return hit.getReturnValues() - .getOptional( NodeIndexPath.MANUAL_ORDER_VALUE.getPath() ) + .getOptional( NodeIndexPath.MANUAL_ORDER_VALUE ) .map( Object::toString ) .map( Long::valueOf ) .orElseThrow( diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveSyncWorkCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveSyncWorkCommand.java index 9b783f61f87..8cc919101f5 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveSyncWorkCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveSyncWorkCommand.java @@ -4,17 +4,13 @@ import java.util.Objects; import java.util.Set; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Stopwatch; - import com.enonic.xp.branch.Branch; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeComparisons; import com.enonic.xp.node.NodeId; @@ -22,7 +18,6 @@ import com.enonic.xp.node.NodeNotFoundException; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodePaths; -import com.enonic.xp.node.NodeVersionDiffResult; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.node.ResolveSyncWorkResult; import com.enonic.xp.repo.impl.InternalContext; @@ -45,14 +40,10 @@ public class ResolveSyncWorkCommand private final ResolveSyncWorkResult.Builder result; - private final Set statusesToStopDependenciesSearch; + private final Set statusesToStopDependenciesSearch; private final Function filter; - private final Function statusFilter; - - private static final Logger LOG = LoggerFactory.getLogger( ResolveSyncWorkCommand.class ); - private ResolveSyncWorkCommand( final Builder builder ) { super( builder ); @@ -73,25 +64,6 @@ private ResolveSyncWorkCommand( final Builder builder ) } this.publishRootNode = publishRootNode; - - this.statusFilter = statusesToStopDependenciesSearch != null ? nodeIds -> { - final NodeIds.Builder filteredNodeIds = NodeIds.create(); - - final NodeComparisons currentLevelNodeComparisons = CompareNodesCommand.create() - .nodeIds( nodeIds ) - .target( target ) - .storageService( this.nodeStorageService ) - .build() - .execute(); - - currentLevelNodeComparisons.getComparisons() - .stream() - .filter( nodeComparison -> !statusesToStopDependenciesSearch.contains( nodeComparison.getCompareStatus() ) ) - .map( NodeComparison::getNodeId ) - .forEach( filteredNodeIds::add ); - - return filteredNodeIds.build(); - } : Function.identity(); } public static Builder create() @@ -109,18 +81,18 @@ public ResolveSyncWorkResult execute() private void getAllPossibleNodesToBePublished() { - final NodeIds.Builder diffAndDependantsBuilder = NodeIds.create(); - final NodeIds initialDiff = getInitialDiff(); - diffAndDependantsBuilder.addAll( initialDiff ); - if ( includeDependencies ) - { - final NodeIds nodeDependencies = getNodeDependencies( initialDiff ); - diffAndDependantsBuilder.addAll( nodeDependencies ); - } + final NodeIds diffAndDependants = + includeDependencies ? NodeIds.create().addAll( getNodeDependencies( initialDiff ) ).addAll( initialDiff ).build() : initialDiff; - final Set comparisons = getFilteredComparisons( diffAndDependantsBuilder ); + final Set comparisons = getComparisons( diffAndDependants ).getComparisons() + .stream() + .filter( comparison -> comparison.getCompareStatus() != NodeCompareStatus.EQUAL && + comparison.getCompareStatus() != NodeCompareStatus.NEW_TARGET ) + .filter( comparison -> !this.processedIds.contains( comparison.getNodeId() ) ) + .filter( comparison -> !this.excludedIds.contains( comparison.getNodeId() ) ) + .collect( Collectors.toSet() ); addNewAndMovedParents( comparisons ); @@ -136,71 +108,55 @@ private NodeIds getInitialDiff() return initialDiff.build(); } - final Stopwatch timer = Stopwatch.createStarted(); - - final NodeVersionDiffResult nodesWithVersionDifference = findNodesWithVersionDifference( this.publishRootNode.path() ); - - LOG.debug( "Diff-query result in " + timer.stop() ); - - final NodeIds nodeIds = nodesWithVersionDifference.getNodesWithDifferences().stream(). - filter( ( nodeId ) -> !this.excludedIds.contains( nodeId ) ). - collect( NodeIds.collector() ); - - return initialDiff.addAll( nodeIds ). - build(); + final NodeVersionDiffResult nodesWithVersionDifference = FindNodesWithVersionDifferenceCommand.create() + .target( target ) + .source( ContextAccessor.current().getBranch() ) + .nodePath( this.publishRootNode.path() ) + .excludes( this.excludedIds ) + .searchService( this.nodeSearchService ) + .storageService( this.nodeStorageService ) + .build() + .execute(); + + nodesWithVersionDifference.getNodesWithDifferences() + .stream() + .filter( Predicate.not( excludedIds::contains ) ) + .forEach( initialDiff::add ); + + return initialDiff.build(); } - private NodeVersionDiffResult findNodesWithVersionDifference( final NodePath nodePath ) + private NodeIds getNodeDependencies( final NodeIds nodeIds ) { - return FindNodesWithVersionDifferenceCommand.create(). - target( target ). - source( ContextAccessor.current().getBranch() ). - nodePath( nodePath ). - excludes( this.excludedIds ). - searchService( this.nodeSearchService ). - storageService( this.nodeStorageService ). - build(). - execute(); - } - - private NodeIds getNodeDependencies( final NodeIds initialDiff ) - { - return FindNodesDependenciesCommand.create( this ).nodeIds( initialDiff ) + final Function statusFilter = statusesToStopDependenciesSearch != null ? n -> getComparisons( n ).getComparisons() + .stream() + .filter( nodeComparison -> !statusesToStopDependenciesSearch.contains( nodeComparison.getCompareStatus() ) ) + .map( NodeComparison::getNodeId ) + .collect( NodeIds.collector() ) : Function.identity(); + + return FindNodesDependenciesCommand.create( this ) + .nodeIds( nodeIds ) .excludedIds( excludedIds ) .filter( filter != null ? statusFilter.compose( filter ) : statusFilter ) - . - build(). - execute(); + .build() + .execute(); } private void addNewAndMovedParents( final Set comparisons ) { - final NodePaths parentPaths = getPathsFromComparisons( comparisons ); - - final NodeIds parentIds = getParentIdsFromPaths( parentPaths ); + final NodeIds parentIds = + getParentIdsForPaths( comparisons.stream().map( NodeComparison::getSourcePath ).collect( Collectors.toSet() ) ); - final NodeIds.Builder filteredParentIdsBuilder = NodeIds.create(); - getFilteredNewAndMovedParentComparisons( parentIds ). - stream(). - map( NodeComparison::getNodeId ). - forEach( filteredParentIdsBuilder::add ); - final NodeIds filteredParentIds = filteredParentIdsBuilder.build(); + final NodeIds filteredParentIds = + filterNewAndMoved( parentIds ).stream().map( NodeComparison::getNodeId ).collect( NodeIds.collector() ); - final NodeIds parentsDependencies = includeDependencies ? getNodeDependencies( filteredParentIds ) : NodeIds.empty(); + final NodeIds parentsAndDependencies = includeDependencies + ? NodeIds.create().addAll( getNodeDependencies( filteredParentIds ) ).addAll( filteredParentIds ).build() + : filteredParentIds; - final NodeComparisons newComparisonsToConsider = CompareNodesCommand.create(). - nodeIds( NodeIds.create(). - addAll( parentsDependencies ). - addAll( filteredParentIds ). - build() ). - target( this.target ). - storageService( this.nodeStorageService ). - build(). - execute(); + final Set newAndMoved = filterNewAndMoved( parentsAndDependencies ); - final Set newAndMoved = getNewAndMoved( newComparisonsToConsider ); - - addToResult( NodeComparisons.create().addAll( newAndMoved ).build() ); + newAndMoved.forEach( this::addToResult ); if ( !newAndMoved.isEmpty() ) { @@ -208,17 +164,33 @@ private void addNewAndMovedParents( final Set comparisons ) } } - private Set getNewAndMoved( final NodeComparisons parentComparisons ) + private NodePaths parentPaths( final Set comparisons ) { - return parentComparisons.getComparisons().stream(). - filter( comparison -> comparison.getCompareStatus().equals( CompareStatus.NEW ) || - comparison.getCompareStatus().equals( CompareStatus.MOVED ) ). - filter( comparison -> !this.processedIds.contains( comparison.getNodeId() ) ). - collect( Collectors.toSet() ); + final NodePaths.Builder parentPathsBuilder = NodePaths.create(); + + for ( final NodePath path : comparisons ) + { + if ( !path.isRoot() ) + { + for ( NodePath parentPath : path.getParentPaths() ) + { + if ( parentPath.isRoot() ) + { + break; + } + + parentPathsBuilder.addNodePath( parentPath ); + } + } + + } + + return parentPathsBuilder.build(); } - private NodeIds getParentIdsFromPaths( final NodePaths parentPaths ) + private NodeIds getParentIdsForPaths( final Set paths ) { + final NodePaths parentPaths = parentPaths( paths ); final NodeIds.Builder parentIdBuilder = NodeIds.create(); final InternalContext internalContext = InternalContext.from( ContextAccessor.current() ); @@ -237,100 +209,32 @@ private NodeIds getParentIdsFromPaths( final NodePaths parentPaths ) return parentIdBuilder.build(); } - private NodePaths getPathsFromComparisons( final Set comparisons ) + private Set filterNewAndMoved( final NodeIds nodeIds ) { - final NodePaths.Builder parentPathsBuilder = NodePaths.create(); - - for ( final NodeComparison comparison : comparisons ) - { - addParentPaths( parentPathsBuilder, comparison.getSourcePath() ); - } - - return parentPathsBuilder.build(); - } - - private Set getFilteredComparisons( final NodeIds.Builder diffAndDependantsBuilder ) - { - final NodeComparisons allNodesComparisons = CompareNodesCommand.create(). - target( this.target ). - nodeIds( diffAndDependantsBuilder.build() ). - storageService( this.nodeStorageService ). - build(). - execute(); - - return allNodesComparisons.getComparisons().stream(). - filter( comparison -> !( nodeNotChanged( comparison ) || nodeNotInSource( comparison ) ) ). - filter( comparison -> !this.processedIds.contains( comparison.getNodeId() ) ). - filter( comparison -> !this.excludedIds.contains( comparison.getNodeId() ) ). - collect( Collectors.toSet() ); - } - - private Set getFilteredNewAndMovedParentComparisons( final NodeIds nodeIds ) - { - final NodeComparisons allNodesComparisons = CompareNodesCommand.create(). - target( this.target ). - nodeIds( nodeIds ). - storageService( this.nodeStorageService ). - build(). - execute(); - - return allNodesComparisons.getComparisons().stream(). - filter( comparison -> nodeMoved( comparison ) || nodeNotInTarget( comparison ) ). - filter( comparison -> !this.processedIds.contains( comparison.getNodeId() ) ). - collect( Collectors.toSet() ); + return getComparisons( nodeIds ).getComparisons() + .stream() + .filter( comparison -> comparison.getCompareStatus() == NodeCompareStatus.MOVED || + comparison.getCompareStatus() == NodeCompareStatus.NEW ) + .filter( comparison -> !this.processedIds.contains( comparison.getNodeId() ) ) + .collect( Collectors.toSet() ); } - private void addParentPaths( final NodePaths.Builder parentPathsBuilder, final NodePath path ) + private NodeComparisons getComparisons( final NodeIds nodeIds ) { - if ( path.isRoot() ) - { - return; - } - - for ( NodePath parentPath : path.getParentPaths() ) - { - if ( parentPath.isRoot() ) - { - return; - } - - parentPathsBuilder.addNodePath( parentPath ); - } + return CompareNodesCommand.create() + .target( this.target ) + .nodeIds( nodeIds ) + .storageService( this.nodeStorageService ) + .build() + .execute(); } - private void addToResult( final NodeComparison comparison ) { this.result.add( comparison ); this.processedIds.add( comparison.getNodeId() ); } - private void addToResult( final NodeComparisons comparisons ) - { - this.result.addAll( comparisons.getComparisons() ); - this.processedIds.addAll( comparisons.getNodeIds().getSet() ); - } - - private boolean nodeMoved( final NodeComparison comparison ) - { - return comparison.getCompareStatus() == CompareStatus.MOVED; - } - - private boolean nodeNotInTarget( final NodeComparison comparison ) - { - return comparison.getCompareStatus() == CompareStatus.NEW; - } - - private boolean nodeNotInSource( final NodeComparison comparison ) - { - return comparison.getCompareStatus() == CompareStatus.NEW_TARGET; - } - - private boolean nodeNotChanged( final NodeComparison comparison ) - { - return comparison.getCompareStatus() == CompareStatus.EQUAL; - } - public static final class Builder extends AbstractNodeCommand.Builder { @@ -344,7 +248,7 @@ public static final class Builder private boolean includeDependencies = true; - private Set statusesToStopDependenciesSearch; + private Set statusesToStopDependenciesSearch; private Function filter; @@ -391,7 +295,7 @@ public Builder filter( final Function filter ) return this; } - public Builder statusesToStopDependenciesSearch( final Set statusesToStopDependenciesSearch ) + public Builder statusesToStopDependenciesSearch( final Set statusesToStopDependenciesSearch ) { this.statusesToStopDependenciesSearch = statusesToStopDependenciesSearch; return this; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SetRootPermissionsCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SetRootPermissionsCommand.java deleted file mode 100644 index 6af00986c6e..00000000000 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SetRootPermissionsCommand.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.enonic.xp.repo.impl.node; - -import java.time.Instant; - -import com.enonic.xp.context.ContextAccessor; -import com.enonic.xp.node.Node; -import com.enonic.xp.node.NodeAccessException; -import com.enonic.xp.node.NodePath; -import com.enonic.xp.repo.impl.InternalContext; -import com.enonic.xp.repo.impl.storage.StoreNodeParams; -import com.enonic.xp.security.acl.AccessControlList; -import com.enonic.xp.security.acl.Permission; - -import static com.enonic.xp.repo.impl.node.NodeConstants.CLOCK; -import static com.enonic.xp.repo.impl.node.NodePermissionsResolver.requireContextUserPermissionOrAdmin; - -public class SetRootPermissionsCommand - extends AbstractNodeCommand -{ - private final AccessControlList permissions; - - private SetRootPermissionsCommand( final Builder builder ) - { - super( builder ); - this.permissions = builder.permissions; - } - - public Node execute() - { - final Node rootNode = doGetById( Node.ROOT_UUID ); - - if ( rootNode == null ) - { - throw new NodeAccessException( ContextAccessor.current().getAuthInfo().getUser(), NodePath.ROOT, Permission.READ ); - } - - requireContextUserPermissionOrAdmin( Permission.WRITE_PERMISSIONS, rootNode ); - - final Node node = Node.create( rootNode ) - .permissions( this.permissions ) - .timestamp( Instant.now( CLOCK ) ) - .build(); - - return this.nodeStorageService.store( StoreNodeParams.newVersion( node ), InternalContext.from( ContextAccessor.current() ) ) - .node(); - } - - public static Builder create() - { - return new Builder(); - } - - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - - public static final class Builder - extends AbstractNodeCommand.Builder - { - private AccessControlList permissions; - - private Builder() - { - } - - private Builder( final AbstractNodeCommand source ) - { - super( source ); - } - - public Builder permissions( final AccessControlList val ) - { - permissions = val; - return this; - } - - public SetRootPermissionsCommand build() - { - return new SetRootPermissionsCommand( this ); - } - } -} diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SortNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SortNodeCommand.java index 3d7f4cde78d..433dab22d0f 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SortNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/SortNodeCommand.java @@ -78,7 +78,7 @@ public SortNodeResult execute() final Node editedNode = Node.create( node ).childOrder( params.getChildOrder() ).data( processedData ).timestamp( Instant.now( CLOCK ) ).build(); Node updatedNode = - this.nodeStorageService.store( StoreNodeParams.newVersion( editedNode ), InternalContext.from( ContextAccessor.current() ) ) + this.nodeStorageService.store( StoreNodeParams.newVersion( editedNode, params.getVersionAttributes() ), InternalContext.from( ContextAccessor.current() ) ) .node(); result.node( updatedNode ); } @@ -245,11 +245,11 @@ public Builder params( SortNodeParams params ) return this; } - @Override void validate() { super.validate(); + Objects.requireNonNull( params, "params cannot be null" ); } public SortNodeCommand build() diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryEntryServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryEntryServiceImpl.java index 4e6a2dc83e2..2e97c777641 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryEntryServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryEntryServiceImpl.java @@ -7,7 +7,6 @@ import com.google.common.io.ByteSource; import com.enonic.xp.branch.Branch; -import com.enonic.xp.branch.Branches; import com.enonic.xp.context.Context; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.context.ContextBuilder; @@ -19,7 +18,6 @@ import com.enonic.xp.node.NodeQuery; import com.enonic.xp.node.PatchNodeParams; import com.enonic.xp.node.RefreshMode; -import com.enonic.xp.node.UpdateNodeParams; import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.NodeBranchEntries; import com.enonic.xp.repo.impl.NodeEvents; @@ -103,7 +101,7 @@ public RepositoryEntry getRepositoryEntry( final RepositoryId repositoryId ) @Override public RepositoryEntry addBranchToRepositoryEntry( final RepositoryId repositoryId, final Branch branch ) { - final UpdateNodeParams updateNodeParams = UpdateNodeParams.create(). + final PatchNodeParams updateNodeParams = PatchNodeParams.create(). id( NodeId.from( repositoryId ) ). editor( RepositoryNodeTranslator.toCreateBranchNodeEditor( branch ) ). refresh( RefreshMode.ALL ). @@ -115,7 +113,7 @@ public RepositoryEntry addBranchToRepositoryEntry( final RepositoryId repository @Override public RepositoryEntry removeBranchFromRepositoryEntry( final RepositoryId repositoryId, final Branch branch ) { - final UpdateNodeParams updateNodeParams = UpdateNodeParams.create(). + final PatchNodeParams updateNodeParams = PatchNodeParams.create(). id( NodeId.from( repositoryId ) ). editor( RepositoryNodeTranslator.toDeleteBranchNodeEditor( branch ) ). refresh( RefreshMode.ALL ). @@ -127,7 +125,7 @@ public RepositoryEntry removeBranchFromRepositoryEntry( final RepositoryId repos @Override public RepositoryEntry updateRepositoryEntry( UpdateRepositoryEntryParams params ) { - final UpdateNodeParams updateNodeParams = UpdateNodeParams.create(). + final PatchNodeParams updateNodeParams = PatchNodeParams.create(). id( NodeId.from( params.getRepositoryId() ) ). editor( RepositoryNodeTranslator.toUpdateRepositoryNodeEditor( params ) ). setBinaryAttachments( params.getAttachments() ). @@ -172,10 +170,10 @@ private void refresh() } ); } - private RepositoryEntry updateRepositoryNode( final UpdateNodeParams updateNodeParams ) + private RepositoryEntry updateRepositoryNode( final PatchNodeParams updateNodeParams ) { final Node updatedNode = createContext().callWith( - () -> PatchNodeCommand.create().params( convertUpdateParams( updateNodeParams ) ).binaryService( this.binaryService ). + () -> PatchNodeCommand.create().params( updateNodeParams ).binaryService( this.binaryService ). indexServiceInternal( this.indexServiceInternal ). storageService( this.nodeStorageService ). searchService( this.nodeSearchService ). @@ -206,16 +204,4 @@ private InternalContext createInternalContext() searchPreference( SearchPreference.PRIMARY ). build(); } - - private PatchNodeParams convertUpdateParams( final UpdateNodeParams params ) - { - return PatchNodeParams.create() - .id( params.getId() ) - .path( params.getPath() ) - .editor( params.getEditor() ) - .setBinaryAttachments( params.getBinaryAttachments() ) - .refresh( params.getRefresh() ) - .addBranches( Branches.from( ContextAccessor.current().getBranch() ) ) - .build(); - } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java index 8d6fcd56294..8f909c792d9 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java @@ -27,7 +27,7 @@ public class NodeSearchServiceImpl private static final ReturnFields VERSION_RETURN_FIELDS = ReturnFields.from( VersionIndexPath.VERSION_ID, VersionIndexPath.NODE_BLOB_KEY, VersionIndexPath.INDEX_CONFIG_BLOB_KEY, VersionIndexPath.ACCESS_CONTROL_BLOB_KEY, VersionIndexPath.BINARY_BLOB_KEYS, VersionIndexPath.TIMESTAMP, - VersionIndexPath.NODE_PATH, VersionIndexPath.NODE_ID, VersionIndexPath.COMMIT_ID ); + VersionIndexPath.NODE_PATH, VersionIndexPath.NODE_ID, VersionIndexPath.COMMIT_ID, VersionIndexPath.ATTRIBUTES ); private static final ReturnFields BRANCH_RETURN_FIELDS = ReturnFields.from( BranchIndexPath.NODE_ID, BranchIndexPath.VERSION_ID, BranchIndexPath.NODE_BLOB_KEY, diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/result/SearchHit.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/result/SearchHit.java index 71bf7f0746b..57b91f88722 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/result/SearchHit.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/result/SearchHit.java @@ -2,9 +2,7 @@ import com.enonic.xp.highlight.HighlightedProperties; import com.enonic.xp.query.QueryExplanation; -import com.enonic.xp.repo.impl.ReturnValue; import com.enonic.xp.repo.impl.ReturnValues; -import com.enonic.xp.repo.impl.index.IndexFieldNameNormalizer; import com.enonic.xp.sortvalues.SortValuesProperty; public class SearchHit @@ -67,16 +65,6 @@ public QueryExplanation getExplanation() return explanation; } - public ReturnValue getField( final String fieldName ) - { - return doGetField( fieldName, false ); - } - - public ReturnValue getField( final String fieldName, final boolean failOnMissing ) - { - return doGetField( fieldName, failOnMissing ); - } - public ReturnValues getReturnValues() { return returnValues; @@ -92,20 +80,6 @@ public SortValuesProperty getSortValues() return sortValues; } - private ReturnValue doGetField( final String fieldName, final boolean failOnMissing ) - { - final String normalizedFieldName = IndexFieldNameNormalizer.normalize( fieldName ); - - final ReturnValue returnValue = returnValues.get( normalizedFieldName ); - - if ( failOnMissing && returnValue == null ) - { - throw new RuntimeException( "Expected field " + normalizedFieldName + " in result not found" ); - } - - return returnValue; - } - @Override public boolean equals( final Object o ) { diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java index aa17a1f6f52..da0e9aa3131 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java @@ -3,6 +3,8 @@ import java.util.Collection; +import com.enonic.xp.node.Attributes; +import com.enonic.xp.node.NodeVersionIds; import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.branch.Branch; import com.enonic.xp.node.Node; @@ -17,11 +19,11 @@ import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.Nodes; import com.enonic.xp.node.PushNodesListener; -import com.enonic.xp.node.RoutableNodeVersionIds; import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.NodeBranchEntries; import com.enonic.xp.repo.impl.NodeBranchEntry; import com.enonic.xp.security.acl.AccessControlList; +import com.enonic.xp.util.GenericValue; public interface NodeStorageService { @@ -37,7 +39,9 @@ public interface NodeStorageService void push( Collection entries, Branch target, PushNodesListener pushListener, InternalContext context ); - NodeCommitEntry commit( NodeCommitEntry entry, RoutableNodeVersionIds routableNodeVersionIds, InternalContext context ); + NodeCommitEntry commit( NodeCommitEntry entry, NodeVersionIds versionIds, InternalContext context ); + + void setAttribute( NodeVersionId versionId, Attributes attributes, InternalContext context ); Node get( NodeId nodeId, InternalContext context ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java index a57b56b3e09..f5dae135b68 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java @@ -14,10 +14,10 @@ import com.enonic.xp.blob.BlobKey; import com.enonic.xp.blob.BlobKeys; -import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.branch.Branch; import com.enonic.xp.node.AttachedBinaries; import com.enonic.xp.node.AttachedBinary; +import com.enonic.xp.node.Attributes; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeCommitId; @@ -27,11 +27,11 @@ import com.enonic.xp.node.NodePaths; import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.NodeVersionIds; +import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.Nodes; import com.enonic.xp.node.PushNodesListener; -import com.enonic.xp.node.RoutableNodeVersionId; -import com.enonic.xp.node.RoutableNodeVersionIds; import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.NodeBranchEntries; import com.enonic.xp.repo.impl.NodeBranchEntry; @@ -88,20 +88,14 @@ public NodeVersionData store( final StoreNodeParams params, final InternalContex .binaryBlobKeys( getBinaryBlobKeys( node.getAttachedBinaries() ) ) .nodePath( node.path() ) .nodeCommitId( params.getNodeCommitId() ) + .attributes( params.getVersionAttributes() ) .timestamp( timestamp ) .build(); - this.versionService.store( nodeVersionMetadata, context ); - - this.branchService.store( NodeBranchEntry.create() - .nodeId( node.id() ) - .nodeVersionId( nodeVersionId ) - .nodeVersionKey( nodeVersionKey ) - .nodePath( node.path() ) - .timestamp( timestamp ) - .build(), context ); final Node newNode = Node.create( node ).timestamp( timestamp ).nodeVersionId( nodeVersionId ).build(); + this.versionService.store( nodeVersionMetadata, context ); + this.branchService.store( NodeBranchEntry.fromNodeVersionMetadata( nodeVersionMetadata ), context ); this.indexDataService.store( newNode, context ); return new NodeVersionData( newNode, nodeVersionMetadata ); @@ -119,8 +113,7 @@ public void push( final Collection entries, final Branch target pushListener.nodesPushed( 1 ); } - final Collection nodeIds = - entries.stream().map( NodeBranchEntry::getNodeId ).collect( Collectors.toList() ); + final Collection nodeIds = entries.stream().map( NodeBranchEntry::getNodeId ).collect( Collectors.toList() ); this.indexDataService.push( IndexPushNodeParams.create().nodeIds( nodeIds ).targetBranch( target ).build(), context ); } @@ -130,26 +123,27 @@ public void storeVersion( final StoreNodeVersionParams params, final InternalCon { final NodeVersionKey nodeVersionKey = this.nodeVersionService.store( params.getNodeVersion(), context ); - this.versionService.store( NodeVersionMetadata.create(). - nodeId( params.getNodeId() ). - nodeVersionId( params.getNodeVersionId() ). - nodeVersionKey( nodeVersionKey ). - binaryBlobKeys( getBinaryBlobKeys( params.getNodeVersion().getAttachedBinaries() ) ). - nodePath( params.getNodePath() ). - nodeCommitId( params.getNodeCommitId() ). - timestamp( params.getTimestamp() ). - build(), context ); + this.versionService.store( NodeVersionMetadata.create() + .nodeId( params.getNodeId() ) + .nodeVersionId( params.getNodeVersionId() ) + .nodeVersionKey( nodeVersionKey ) + .binaryBlobKeys( getBinaryBlobKeys( params.getNodeVersion().getAttachedBinaries() ) ) + .nodePath( params.getNodePath() ) + .nodeCommitId( params.getNodeCommitId() ) + .timestamp( params.getTimestamp() ) + .attributes( params.getAttributes() ) + .build(), context ); } @Override public void storeCommit( final StoreNodeCommitParams params, final InternalContext context ) { - final NodeCommitEntry nodeCommitEntry = NodeCommitEntry.create(). - nodeCommitId( params.getNodeCommitId() ). - message( params.getMessage() ). - committer( params.getCommitter() ). - timestamp( params.getTimestamp() ). - build(); + final NodeCommitEntry nodeCommitEntry = NodeCommitEntry.create() + .nodeCommitId( params.getNodeCommitId() ) + .message( params.getMessage() ) + .committer( params.getCommitter() ) + .timestamp( params.getTimestamp() ) + .build(); this.commitService.store( nodeCommitEntry, context ); } @@ -172,26 +166,56 @@ public void deleteFromIndex( final NodeId nodeId, final InternalContext internal } @Override - public NodeCommitEntry commit( final NodeCommitEntry nodeCommitEntry, final RoutableNodeVersionIds routableNodeVersionIds, - final InternalContext context ) + public NodeCommitEntry commit( final NodeCommitEntry nodeCommitEntry, final NodeVersionIds versionIds, final InternalContext context ) { final NodeCommitId nodeCommitId = new NodeCommitId(); - final NodeCommitEntry updatedCommitEntry = NodeCommitEntry.create( nodeCommitEntry ). - nodeCommitId( nodeCommitId ). - build(); + final NodeCommitEntry updatedCommitEntry = NodeCommitEntry.create( nodeCommitEntry ).nodeCommitId( nodeCommitId ).build(); this.commitService.store( updatedCommitEntry, context ); - for ( RoutableNodeVersionId routableNodeVersionId : routableNodeVersionIds ) + + for ( final NodeVersionId versionId : versionIds ) { - final NodeVersionMetadata existingVersion = - this.versionService.getVersion( routableNodeVersionId.getNodeVersionId(), context ); - final NodeVersionMetadata updatedVersion = NodeVersionMetadata.create( existingVersion ). - nodeCommitId( nodeCommitId ). - build(); + final NodeVersionMetadata existingVersion = this.versionService.getVersion( versionId, context ); + + final NodeVersionMetadata updatedVersion = NodeVersionMetadata.create() + .nodeVersionId( existingVersion.getNodeVersionId() ) + .nodeVersionKey( existingVersion.getNodeVersionKey() ) + .binaryBlobKeys( existingVersion.getBinaryBlobKeys() ) + .nodeId( existingVersion.getNodeId() ) + .nodePath( existingVersion.getNodePath() ) + .timestamp( existingVersion.getTimestamp() ) + .attributes( existingVersion.getAttributes() ) + .nodeCommitId( nodeCommitId ) + .build(); this.versionService.store( updatedVersion, context ); } return updatedCommitEntry; } + @Override + public void setAttribute( final NodeVersionId versionId, Attributes value, final InternalContext context ) + { + final NodeVersionMetadata existingVersion = this.versionService.getVersion( versionId, context ); + + final Attributes attributes = existingVersion.getAttributes(); + final Attributes.Builder builder = Attributes.create(); + if ( attributes != null ) + { + builder.addAll( attributes.list() ); + } + final Attributes newAttrs = builder.addAll( value.list() ).buildKeepingLast(); + final NodeVersionMetadata updatedVersion = NodeVersionMetadata.create() + .nodeVersionId( existingVersion.getNodeVersionId() ) + .nodeVersionKey( existingVersion.getNodeVersionKey() ) + .binaryBlobKeys( existingVersion.getBinaryBlobKeys() ) + .nodeId( existingVersion.getNodeId() ) + .nodePath( existingVersion.getNodePath() ) + .timestamp( existingVersion.getTimestamp() ) + .attributes( newAttrs ) + .nodeCommitId( existingVersion.getNodeCommitId() ) + .build(); + this.versionService.store( updatedVersion, context ); + } + @Override public Node get( final NodeId nodeId, final InternalContext context ) { @@ -204,9 +228,7 @@ public Node get( final NodeId nodeId, final InternalContext context ) final NodeVersion nodeVersion = nodeVersionService.get( nodeBranchEntry.getNodeVersionKey(), context ); - return canRead( nodeVersion.getPermissions(), context ) - ? NodeFactory.create( nodeVersion, nodeBranchEntry ) - : null; + return canRead( nodeVersion.getPermissions(), context ) ? NodeFactory.create( nodeVersion, nodeBranchEntry ) : null; } @Override @@ -221,9 +243,7 @@ public Node get( final NodePath nodePath, final InternalContext context ) final NodeVersion nodeVersion = nodeVersionService.get( nodeBranchEntry.getNodeVersionKey(), context ); - return canRead( nodeVersion.getPermissions(), context ) - ? NodeFactory.create( nodeVersion, nodeBranchEntry ) - : null; + return canRead( nodeVersion.getPermissions(), context ) ? NodeFactory.create( nodeVersion, nodeBranchEntry ) : null; } @Override @@ -240,9 +260,8 @@ public Nodes get( final NodeIds nodeIds, final InternalContext context ) @Override public Nodes get( final NodePaths nodePaths, final InternalContext context ) { - final Stream stream = nodePaths.stream() - .map( nodePath -> this.branchService.get( nodePath, context ) ) - .filter( Objects::nonNull ); + final Stream stream = + nodePaths.stream().map( nodePath -> this.branchService.get( nodePath, context ) ).filter( Objects::nonNull ); return doReturnNodes( stream, context ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeParams.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeParams.java index 5ff76939e32..0848038cfff 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeParams.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeParams.java @@ -2,6 +2,7 @@ import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitId; +import com.enonic.xp.node.Attributes; public class StoreNodeParams { @@ -9,13 +10,16 @@ public class StoreNodeParams private final NodeCommitId nodeCommitId; + private final Attributes versionAttributes; + private final boolean newVersion; - private StoreNodeParams( final Node node, final NodeCommitId nodeCommitId, final boolean newVersion ) + private StoreNodeParams( final Node node, final NodeCommitId nodeCommitId, final boolean newVersion, final Attributes versionAttributes ) { this.node = node; this.nodeCommitId = nodeCommitId; this.newVersion = newVersion; + this.versionAttributes = versionAttributes; } public Node getNode() @@ -28,54 +32,28 @@ public NodeCommitId getNodeCommitId() return nodeCommitId; } + public Attributes getVersionAttributes() + { + return versionAttributes; + } + public boolean isNewVersion() { return newVersion; } - public static Builder create() + public static StoreNodeParams newVersion( final Node node, final Attributes attributes ) { - return new Builder(); + return new StoreNodeParams( node, null, true, attributes ); } public static StoreNodeParams newVersion( final Node node ) { - return new StoreNodeParams( node, null, true ); + return new StoreNodeParams( node, null, true, null ); } - public static final class Builder + public static StoreNodeParams overrideVersion( final Node node, final NodeCommitId nodeCommitId, final Attributes attributes ) { - private Node node; - - private NodeCommitId nodeCommitId; - - private boolean newVersion = true; - - private Builder() - { - } - - public Builder node( final Node node ) - { - this.node = node; - return this; - } - - public Builder nodeCommitId( final NodeCommitId nodeCommitId ) - { - this.nodeCommitId = nodeCommitId; - return this; - } - - public Builder overrideVersion() - { - this.newVersion = false; - return this; - } - - public StoreNodeParams build() - { - return new StoreNodeParams( node, nodeCommitId, newVersion ); - } + return new StoreNodeParams( node, nodeCommitId, false, attributes ); } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeVersionParams.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeVersionParams.java index f14851f5564..32b0f6266d2 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeVersionParams.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/StoreNodeVersionParams.java @@ -7,6 +7,7 @@ import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.Attributes; public final class StoreNodeVersionParams { @@ -22,6 +23,8 @@ public final class StoreNodeVersionParams private final NodeCommitId nodeCommitId; + private final Attributes attributes; + private StoreNodeVersionParams( final Builder builder ) { nodeVersion = builder.nodeVersion; @@ -30,6 +33,7 @@ private StoreNodeVersionParams( final Builder builder ) nodeId = builder.nodeId; nodeVersionId = builder.nodeVersionId; nodeCommitId = builder.nodeCommitId; + attributes = builder.attributes; } public NodeId getNodeId() @@ -62,6 +66,11 @@ public NodeCommitId getNodeCommitId() return nodeCommitId; } + public Attributes getAttributes() + { + return attributes; + } + public static Builder create() { return new Builder(); @@ -70,6 +79,8 @@ public static Builder create() public static final class Builder { + private Attributes attributes; + private NodeVersion nodeVersion; private Instant timestamp; @@ -122,6 +133,12 @@ public Builder nodeCommitId( final NodeCommitId val ) return this; } + public Builder attributes( final Attributes val ) + { + attributes = val; + return this; + } + public StoreNodeVersionParams build() { return new StoreNodeVersionParams( this ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/GenericValueDeserializer.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/GenericValueDeserializer.java new file mode 100644 index 00000000000..3e053057361 --- /dev/null +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/GenericValueDeserializer.java @@ -0,0 +1,85 @@ +package com.enonic.xp.repo.impl.version; + +import java.io.IOException; +import java.io.UncheckedIOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import com.enonic.xp.util.GenericValue; + +class GenericValueDeserializer + extends JsonDeserializer +{ + private static ObjectMapper MAPPER = new ObjectMapper(); + static + { + + SimpleModule module = new SimpleModule(); + module.addDeserializer( GenericValue.class, new GenericValueDeserializer() ); + + MAPPER.registerModule( module ); + } + + static GenericValue deserialize(String json) { + try + { + return MAPPER.readValue( json, GenericValue.class ); + } + catch ( JsonProcessingException e ) + { + throw new UncheckedIOException( e ); + } + } + + + @Override + public GenericValue deserialize( JsonParser p, DeserializationContext ctxt ) + throws IOException + { + JsonToken token = p.currentToken(); + if ( token == null ) + { + token = p.nextToken(); + } + switch ( token ) + { + case VALUE_STRING: + return GenericValue.stringValue( p.getText() ); + case VALUE_NUMBER_INT: + return GenericValue.numberValue( p.getLongValue() ); + case VALUE_NUMBER_FLOAT: + return GenericValue.numberValue( p.getDoubleValue() ); + case VALUE_TRUE: + case VALUE_FALSE: + return GenericValue.booleanValue( p.getBooleanValue() ); + case START_ARRAY: + { + var list = GenericValue.list(); + while ( p.nextToken() != JsonToken.END_ARRAY ) + { + list.add( deserialize( p, ctxt ) ); + } + return list.build(); + } + case START_OBJECT: + { + var obj = GenericValue.object(); + while ( p.nextToken() != JsonToken.END_OBJECT ) + { + String fieldName = p.currentName(); + p.nextToken(); + obj.put( fieldName, deserialize( p, ctxt ) ); + } + return obj.build(); + } + default: + throw ctxt.wrongTokenException( p, GenericValue.class, token, "" ); + } + } +} diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java index 9a1cfbf1b87..af350a56e3f 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java @@ -4,33 +4,31 @@ import com.enonic.xp.blob.BlobKey; import com.enonic.xp.blob.BlobKeys; -import com.enonic.xp.node.NodeVersionKey; +import com.enonic.xp.node.Attributes; import com.enonic.xp.node.NodeCommitId; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.repo.impl.ReturnValue; import com.enonic.xp.repo.impl.ReturnValues; -import com.enonic.xp.repo.impl.storage.GetResult; -class NodeVersionFactory +public class NodeVersionFactory { - public static NodeVersionMetadata create( final GetResult getResult ) + public static NodeVersionMetadata create( final ReturnValues values ) { - final ReturnValues values = getResult.getReturnValues(); - - final String versionId = values.getSingleValue( VersionIndexPath.VERSION_ID.getPath() ).toString(); - final String nodeBlobKey = values.getSingleValue( VersionIndexPath.NODE_BLOB_KEY.getPath() ).toString(); - final String indexConfigBlobKey = values.getSingleValue( VersionIndexPath.INDEX_CONFIG_BLOB_KEY.getPath() ).toString(); - final String accessControlBlobKey = values.getSingleValue( VersionIndexPath.ACCESS_CONTROL_BLOB_KEY.getPath() ).toString(); - final ReturnValue binaryBlobKeysReturnValue = values.get( VersionIndexPath.BINARY_BLOB_KEYS.getPath() ); - final Instant timestamp = Instant.parse( values.getSingleValue( VersionIndexPath.TIMESTAMP.getPath() ).toString() ); - final String id = values.getSingleValue( VersionIndexPath.NODE_ID.getPath() ).toString(); - final String path = values.getSingleValue( VersionIndexPath.NODE_PATH.getPath() ).toString(); - final Object commitId = values.getSingleValue( VersionIndexPath.COMMIT_ID.getPath() ); - - final BlobKeys binaryBlobKeys = toBlobKeys( binaryBlobKeysReturnValue ); + final String versionId = values.getStringValue( VersionIndexPath.VERSION_ID ); + final String nodeBlobKey = values.getStringValue( VersionIndexPath.NODE_BLOB_KEY ); + final String indexConfigBlobKey = values.getStringValue( VersionIndexPath.INDEX_CONFIG_BLOB_KEY ); + final String accessControlBlobKey = values.getStringValue( VersionIndexPath.ACCESS_CONTROL_BLOB_KEY ); + final Instant timestamp = Instant.parse( values.getStringValue( VersionIndexPath.TIMESTAMP ) ); + final String id = values.getStringValue( VersionIndexPath.NODE_ID ); + final String path = values.getStringValue( VersionIndexPath.NODE_PATH ); + final NodeCommitId commitId = + values.getOptional( VersionIndexPath.COMMIT_ID ).map( Object::toString ).map( NodeCommitId::from ).orElse( null ); + final ReturnValue attributes = values.get( VersionIndexPath.ATTRIBUTES.getPath() ); + final BlobKeys binaryBlobKeys = toBlobKeys( values.get( VersionIndexPath.BINARY_BLOB_KEYS.getPath() ) ); return NodeVersionMetadata.create() .nodeId( NodeId.from( id ) ) @@ -43,7 +41,8 @@ public static NodeVersionMetadata create( final GetResult getResult ) .accessControlBlobKey( BlobKey.from( accessControlBlobKey ) ) .build() ) .binaryBlobKeys( binaryBlobKeys ) - .nodeCommitId( commitId == null ? null : NodeCommitId.from( commitId ) ) + .nodeCommitId( commitId ) + .attributes( stringToAttributes( attributes ) ) .build(); } @@ -54,4 +53,13 @@ private static BlobKeys toBlobKeys( final ReturnValue returnValue ) .map( value -> BlobKey.from( value.toString() ) ) .collect( BlobKeys.collector() ) : BlobKeys.empty(); } + + private static Attributes stringToAttributes( ReturnValue val ) + { + return val == null + ? null + : Attributes.create() + .addAll( val.getValues().stream().map( Object::toString ).map( GenericValueDeserializer::deserialize ).toList() ) + .build(); + } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java index 035d6183cbd..fe22061c6dc 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java @@ -22,4 +22,5 @@ public class VersionIndexPath public static final IndexPath COMMIT_ID = IndexPath.from( "commitid" ); + public static final IndexPath ATTRIBUTES = IndexPath.from( "attributes" ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java index 6735664c1b6..7d485faeaf4 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java @@ -19,7 +19,6 @@ import com.enonic.xp.repo.impl.storage.StorageDao; import com.enonic.xp.repo.impl.storage.StoreRequest; import com.enonic.xp.repo.impl.storage.StoreStorageName; -import com.enonic.xp.repo.impl.version.storage.VersionStorageDocFactory; import com.enonic.xp.repository.RepositoryId; @Component @@ -58,11 +57,6 @@ public void delete( final NodeVersionId nodeVersionId, final InternalContext con @Override public NodeVersionMetadata getVersion( final NodeVersionId nodeVersionId, final InternalContext context ) - { - return doGetById( nodeVersionId, context ); - } - - private NodeVersionMetadata doGetById( final NodeVersionId nodeVersionId, final InternalContext context ) { final GetByIdRequest getByIdRequest = GetByIdRequest.create() .id( nodeVersionId.toString() ) @@ -78,7 +72,7 @@ private NodeVersionMetadata doGetById( final NodeVersionId nodeVersionId, final return null; } - return NodeVersionFactory.create( getResult ); + return NodeVersionFactory.create( getResult.getReturnValues() ); } private StorageSource createStorageSettings( final RepositoryId repositoryId ) diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionStorageDocFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionStorageDocFactory.java new file mode 100644 index 00000000000..f303d005847 --- /dev/null +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionStorageDocFactory.java @@ -0,0 +1,73 @@ +package com.enonic.xp.repo.impl.version; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import com.enonic.xp.node.Attributes; +import com.enonic.xp.node.NodeVersionMetadata; +import com.enonic.xp.repo.impl.StorageSource; +import com.enonic.xp.repo.impl.storage.StaticStorageType; +import com.enonic.xp.repo.impl.storage.StorageData; +import com.enonic.xp.repo.impl.storage.StoreRequest; +import com.enonic.xp.repo.impl.storage.StoreStorageName; +import com.enonic.xp.repository.RepositoryId; +import com.enonic.xp.util.GenericValue; + +public class VersionStorageDocFactory +{ + public static StoreRequest create( final NodeVersionMetadata nodeVersion, final RepositoryId repositoryId ) + { + final StorageData.Builder data = StorageData.create() + .add( VersionIndexPath.VERSION_ID.getPath(), nodeVersion.getNodeVersionId().toString() ) + .add( VersionIndexPath.NODE_BLOB_KEY.getPath(), nodeVersion.getNodeVersionKey().getNodeBlobKey().toString() ) + .add( VersionIndexPath.INDEX_CONFIG_BLOB_KEY.getPath(), nodeVersion.getNodeVersionKey().getIndexConfigBlobKey().toString() ) + .add( VersionIndexPath.ACCESS_CONTROL_BLOB_KEY.getPath(), nodeVersion.getNodeVersionKey().getAccessControlBlobKey().toString() ) + .add( VersionIndexPath.BINARY_BLOB_KEYS.getPath(), nodeVersion.getBinaryBlobKeys() ) + .add( VersionIndexPath.NODE_ID.getPath(), nodeVersion.getNodeId().toString() ) + .add( VersionIndexPath.TIMESTAMP.getPath(), nodeVersion.getTimestamp() ) + .add( VersionIndexPath.NODE_PATH.getPath(), nodeVersion.getNodePath().toString() ); + + if ( nodeVersion.getNodeCommitId() != null ) + { + data.add( VersionIndexPath.COMMIT_ID.getPath(), nodeVersion.getNodeCommitId().toString() ); + } + + if ( nodeVersion.getAttributes() != null ) + { + data.add( VersionIndexPath.ATTRIBUTES.getPath(), attributesToString( nodeVersion.getAttributes() ) ); + } + + return StoreRequest.create() + .nodePath( nodeVersion.getNodePath() ) + .id( nodeVersion.getNodeVersionId().toString() ) + .settings( StorageSource.create() + .storageName( StoreStorageName.from( repositoryId ) ) + .storageType( StaticStorageType.VERSION ) + .build() ) + .data( data.build() ) + .build(); + } + + private static List attributesToString( final Attributes attributes ) + { + ObjectMapper mapper = new ObjectMapper(); + + var result = new ArrayList(); + try + { + for ( GenericValue p : attributes.list() ) + { + result.add( mapper.writeValueAsString( p.rawJava() ) ); + } + } + catch ( JsonProcessingException e ) + { + throw new RuntimeException( e ); + } + return result; + } + +} diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionQueryResultFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionQueryResultFactory.java index 5bca28323af..09c38942d7f 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionQueryResultFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionQueryResultFactory.java @@ -1,24 +1,10 @@ package com.enonic.xp.repo.impl.version.search; -import java.time.Instant; - -import com.enonic.xp.blob.BlobKey; -import com.enonic.xp.blob.BlobKeys; -import com.enonic.xp.node.NodeVersionKey; -import com.enonic.xp.index.IndexPath; -import com.enonic.xp.node.NodeCommitId; -import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodePath; -import com.enonic.xp.node.NodeVersionId; -import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.NodeVersionMetadatas; import com.enonic.xp.node.NodeVersionQueryResult; -import com.enonic.xp.repo.impl.ReturnValue; import com.enonic.xp.repo.impl.search.result.SearchHit; import com.enonic.xp.repo.impl.search.result.SearchResult; -import com.enonic.xp.repo.impl.version.VersionIndexPath; - -import static com.google.common.base.Strings.isNullOrEmpty; +import com.enonic.xp.repo.impl.version.NodeVersionFactory; public class NodeVersionQueryResultFactory { @@ -28,67 +14,9 @@ public static NodeVersionQueryResult create( final SearchResult searchResult ) .totalHits( searchResult.getTotalHits() ) .entityVersions( searchResult.getHits() .stream() - .map( NodeVersionQueryResultFactory::createVersionEntry ) + .map( SearchHit::getReturnValues ) + .map( NodeVersionFactory::create ) .collect( NodeVersionMetadatas.collector() ) ) .build(); } - - private static NodeVersionMetadata createVersionEntry( final SearchHit hit ) - { - final String timestamp = getStringValue( hit, VersionIndexPath.TIMESTAMP, true ); - - final String versionId = getStringValue( hit, VersionIndexPath.VERSION_ID, true ); - - final String nodeBlobKey = getStringValue( hit, VersionIndexPath.NODE_BLOB_KEY, true ); - - final String indexConfigBlobKey = getStringValue( hit, VersionIndexPath.INDEX_CONFIG_BLOB_KEY, true ); - - final String accessControlBlobKey = getStringValue( hit, VersionIndexPath.ACCESS_CONTROL_BLOB_KEY, true ); - - final ReturnValue binaryBlobKeyReturnValue = hit.getField( VersionIndexPath.BINARY_BLOB_KEYS.getPath(), false ); - - final String nodePath = getStringValue( hit, VersionIndexPath.NODE_PATH, true ); - - final String nodeId = getStringValue( hit, VersionIndexPath.NODE_ID, true ); - - final String commitId = getStringValue( hit, VersionIndexPath.COMMIT_ID, false ); - - final BlobKeys binaryBlobKeys = toBlobKeys( binaryBlobKeyReturnValue ); - - return NodeVersionMetadata.create() - .nodeVersionId( NodeVersionId.from( versionId ) ) - .nodeVersionKey( NodeVersionKey.create() - .nodeBlobKey( BlobKey.from( nodeBlobKey ) ) - .indexConfigBlobKey( BlobKey.from( indexConfigBlobKey ) ) - .accessControlBlobKey( BlobKey.from( accessControlBlobKey ) ) - .build() ) - .binaryBlobKeys( binaryBlobKeys ) - .timestamp( isNullOrEmpty( timestamp ) ? null : Instant.parse( timestamp ) ) - .nodePath( new NodePath( nodePath ) ) - .nodeId( NodeId.from( nodeId ) ) - .nodeCommitId( isNullOrEmpty( commitId ) ? null : NodeCommitId.from( commitId ) ) - .build(); - } - - private static BlobKeys toBlobKeys( final ReturnValue returnValue ) - { - return returnValue != null ? returnValue.getValues() - .stream() - .map( value -> BlobKey.from( value.toString() ) ) - .collect( BlobKeys.collector() ) : BlobKeys.empty(); - } - - private static String getStringValue( final SearchHit hit, final IndexPath indexPath, final boolean required ) - { - final ReturnValue field = hit.getField( indexPath.getPath(), required ); - - if ( field == null ) - { - return null; - } - - return field.getSingleValue().toString(); - } - - } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/storage/VersionStorageDocFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/storage/VersionStorageDocFactory.java deleted file mode 100644 index e0fc4ca5246..00000000000 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/storage/VersionStorageDocFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.enonic.xp.repo.impl.version.storage; - -import com.enonic.xp.node.NodeVersionMetadata; -import com.enonic.xp.repo.impl.StorageSource; -import com.enonic.xp.repo.impl.storage.StaticStorageType; -import com.enonic.xp.repo.impl.storage.StorageData; -import com.enonic.xp.repo.impl.storage.StoreRequest; -import com.enonic.xp.repo.impl.storage.StoreStorageName; -import com.enonic.xp.repo.impl.version.VersionIndexPath; -import com.enonic.xp.repository.RepositoryId; - -public class VersionStorageDocFactory -{ - public static StoreRequest create( final NodeVersionMetadata nodeVersion, final RepositoryId repositoryId ) - { - final StorageData.Builder data = StorageData.create(). - add( VersionIndexPath.VERSION_ID.getPath(), nodeVersion.getNodeVersionId().toString() ). - add( VersionIndexPath.NODE_BLOB_KEY.getPath(), nodeVersion.getNodeVersionKey().getNodeBlobKey().toString() ). - add( VersionIndexPath.INDEX_CONFIG_BLOB_KEY.getPath(), nodeVersion.getNodeVersionKey().getIndexConfigBlobKey().toString() ). - add( VersionIndexPath.ACCESS_CONTROL_BLOB_KEY.getPath(), nodeVersion.getNodeVersionKey().getAccessControlBlobKey().toString() ). - add( VersionIndexPath.BINARY_BLOB_KEYS.getPath(), nodeVersion.getBinaryBlobKeys() ). - add( VersionIndexPath.NODE_ID.getPath(), nodeVersion.getNodeId().toString() ). - add( VersionIndexPath.TIMESTAMP.getPath(), nodeVersion.getTimestamp() ). - add( VersionIndexPath.NODE_PATH.getPath(), nodeVersion.getNodePath().toString() ); - - if ( nodeVersion.getNodeCommitId() != null) { - data.add( VersionIndexPath.COMMIT_ID.getPath(), nodeVersion.getNodeCommitId().toString() ); - } - - return StoreRequest.create(). - nodePath( nodeVersion.getNodePath() ). - id( nodeVersion.getNodeVersionId().toString() ). - settings( StorageSource.create(). - storageName( StoreStorageName.from( repositoryId ) ). - storageType( StaticStorageType.VERSION ). - build() ). - data( data.build() ). - build(); - } -} diff --git a/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizerTest.java b/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizerTest.java index 87f5aaa1219..49388cf5d83 100644 --- a/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizerTest.java +++ b/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/index/IndexFieldNameNormalizerTest.java @@ -1,21 +1,16 @@ package com.enonic.xp.repo.impl.index; -import java.util.List; - import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; class IndexFieldNameNormalizerTest { @Test - void normalize_collection() + void normalize() { - final String[] normalizedPaths = IndexFieldNameNormalizer.normalize( List.of("VaLue1", "ValuE2", "VALue3") ); - - for ( final String path : normalizedPaths ) - { - assertTrue( path.equals( "value1" ) || path.equals( "value2" ) || path.equals( "value3" ) ); - } + assertEquals( "value1", IndexFieldNameNormalizer.normalize( "VaLue1" ) ); + assertEquals( "value2", IndexFieldNameNormalizer.normalize( "ValuE2" ) ); + assertEquals( "value3", IndexFieldNameNormalizer.normalize( "VALue3" ) ); } } diff --git a/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java b/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java index 422366b98fc..d533d2ec6b2 100644 --- a/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java +++ b/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java @@ -13,6 +13,7 @@ import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersionMetadata; +import com.enonic.xp.repo.impl.NodeBranchEntry; import com.enonic.xp.repo.impl.index.IndexServiceInternal; import com.enonic.xp.repo.impl.search.NodeSearchService; import com.enonic.xp.repo.impl.storage.NodeStorageService; @@ -59,7 +60,8 @@ void setUp() when( indexServiceInternal.indicesExists( any() ) ).thenReturn( true ); final Node mockNode = Node.create().id( NodeId.from( "1" ) ).parentPath( NodePath.ROOT ).build(); - when( nodeStorageService.store( any(), any() ) ).thenReturn( new NodeVersionData( mockNode, mock( NodeVersionMetadata.class ) ) ); + when( nodeStorageService.store( any(), any() ) ).thenReturn( + new NodeVersionData( mockNode, mock( NodeVersionMetadata.class ) ) ); } @Test diff --git a/modules/core/core-schema/src/test/java/com/enonic/xp/core/impl/form/FormDefaultValuesProcessorImplTest.java b/modules/core/core-schema/src/test/java/com/enonic/xp/core/impl/form/FormDefaultValuesProcessorImplTest.java index 5ec8af897cd..218b299a1ef 100644 --- a/modules/core/core-schema/src/test/java/com/enonic/xp/core/impl/form/FormDefaultValuesProcessorImplTest.java +++ b/modules/core/core-schema/src/test/java/com/enonic/xp/core/impl/form/FormDefaultValuesProcessorImplTest.java @@ -294,7 +294,7 @@ void testOptionSetWithDefaultValueAndMinOccurrencesMoreThanZero() Property checkOptionSet_1 = data.getProperty( "checkOptionSet", i ); assertEquals( "option_2", checkOptionSet_1.getSet().getString( "_selected" ) ); - PropertySet propertySet = checkOptionSet_1.getSet().getPropertySet( "option_2" ); + PropertySet propertySet = checkOptionSet_1.getSet().getSet( "option_2" ); for ( int j = 0; j < 3; j++ ) { assertEquals( "Default Value", propertySet.getString( "testInput", j ) ); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/AbstractNodeTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/AbstractNodeTest.java index dbba0a06da2..eca6847b84f 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/AbstractNodeTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/AbstractNodeTest.java @@ -26,11 +26,13 @@ import com.enonic.xp.home.HomeDirSupport; import com.enonic.xp.impl.scheduler.SchedulerRepoInitializer; import com.enonic.xp.internal.blobstore.MemoryBlobStore; +import com.enonic.xp.node.CommitNodeParams; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.CreateRootNodeParams; import com.enonic.xp.node.FindNodesByParentParams; import com.enonic.xp.node.FindNodesByParentResult; import com.enonic.xp.node.FindNodesByQueryResult; +import com.enonic.xp.node.MoveNodeParams; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeId; @@ -38,8 +40,10 @@ import com.enonic.xp.node.NodeName; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeQuery; +import com.enonic.xp.node.NodeVersionIds; import com.enonic.xp.node.Nodes; import com.enonic.xp.node.PatchNodeParams; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodesResult; import com.enonic.xp.node.UpdateNodeParams; import com.enonic.xp.query.parser.QueryParser; @@ -370,15 +374,15 @@ protected Node createNode( final NodePath parent, final String name ) build() ); } - protected NodeCommitEntry commit( NodeIds nodeIds ) + protected NodeCommitEntry commit( Node node ) { - final NodeCommitEntry nodeCommitEntry = NodeCommitEntry.create(). - message( "commit" ). - build(); - return nodeService.commit( nodeCommitEntry, nodeIds ); + final NodeCommitEntry nodeCommitEntry = NodeCommitEntry.create().message( "commit" ).build(); + return nodeService.commit( CommitNodeParams.create() + .nodeCommitEntry( nodeCommitEntry ) + .nodeVersionIds( NodeVersionIds.from( node.getNodeVersionId() ) ) + .build() ); } - protected Node createNodeSkipVerification( final CreateNodeParams createNodeParams ) { return CreateNodeCommand.create() @@ -455,7 +459,7 @@ protected void printContentRepoIndex() protected PushNodesResult pushNodes( final Branch target, final NodeId... nodeIds ) { - return PushNodesCommand.create().ids( NodeIds.from( nodeIds ) ).target( target ). + return PushNodesCommand.create().params( PushNodeParams.create().ids( NodeIds.from( nodeIds ) ).target( target ).build() ). indexServiceInternal( this.indexServiceInternal ). storageService( this.storageService ). searchService( this.searchService ). @@ -479,8 +483,7 @@ protected NodeIds doDeleteNode( final NodeId nodeId ) protected void renameNode( final NodeId nodeId, final String newName ) { MoveNodeCommand.create() - .id( nodeId ) - .newNodeName( NodeName.from( newName ) ) + .params( MoveNodeParams.create().nodeId( nodeId ).newName( NodeName.from( newName ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) @@ -491,8 +494,7 @@ protected void renameNode( final NodeId nodeId, final String newName ) protected Node moveNode( final NodeId nodeId, final NodePath newParent ) { return MoveNodeCommand.create() - .id( nodeId ) - .newParent( newParent ) + .params( MoveNodeParams.create().nodeId( nodeId ).newParentPath( newParent ).build() ) .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java index 7ed3419fe21..43e3634db7e 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java @@ -643,10 +643,10 @@ protected void assertVersions( final ContentId contentId, final int expected ) if ( lastModified != null ) { - assertFalse( next.getModified().isAfter( lastModified ) ); + assertFalse( next.getChangedTime().isAfter( lastModified ) ); } - lastModified = next.getModified(); + lastModified = next.getChangedTime(); } } diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_applyPermissions.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_applyPermissions.java index 07b062f70ed..bc2ca2ccecc 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_applyPermissions.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_applyPermissions.java @@ -7,6 +7,7 @@ import com.enonic.xp.audit.LogAuditLogParams; import com.enonic.xp.content.ApplyContentPermissionsParams; import com.enonic.xp.content.ApplyContentPermissionsResult; +import com.enonic.xp.content.ApplyContentPermissionsScope; import com.enonic.xp.content.ApplyPermissionsListener; import com.enonic.xp.content.Content; import com.enonic.xp.content.ContentId; @@ -16,7 +17,6 @@ import com.enonic.xp.content.PushContentParams; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.data.PropertyTree; -import com.enonic.xp.node.ApplyPermissionsScope; import com.enonic.xp.node.NodeNotFoundException; import com.enonic.xp.schema.content.ContentTypeName; import com.enonic.xp.security.acl.AccessControlEntry; @@ -101,7 +101,7 @@ void no_rights() final ApplyContentPermissionsParams applyParams = ApplyContentPermissionsParams.create() .contentId( content.getId() ) - .applyPermissionsScope( ApplyPermissionsScope.TREE ) + .applyPermissionsScope( ApplyContentPermissionsScope.TREE ) .applyContentPermissionsListener( listener ) .build(); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_archive.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_archive.java index c5a2d89c70a..798e94cc268 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_archive.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_archive.java @@ -294,8 +294,7 @@ void archive_with_message() assertTrue( iterator.hasNext() ); ContentVersion version = iterator.next(); - assertNotNull( version.getPublishInfo().getTimestamp() ); - assertEquals( archiveMessage, version.getPublishInfo().getMessage() ); + assertEquals( "Archive test message", version.getComment() ); } private static final class TestListener diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_getNearestSite.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_getNearestSite.java index 193f4d1997a..1a12279dc85 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_getNearestSite.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_getNearestSite.java @@ -126,10 +126,8 @@ void testPublishInfo() final Content site = createSite(); this.contentService.publish( PushContentParams.create() .contentIds( ContentIds.from( site.getId() ) ) - .contentPublishInfo( ContentPublishInfo.create() - .from( Instant.parse( "2022-12-01T14:00:00.668487800Z" ) ) - .to( Instant.parse( "2099-12-03T14:00:00.669487800Z" ) ) - .build() ) + .publishFrom( Instant.parse( "2022-12-01T14:00:00.668487800Z" ) ) + .publishTo( Instant.parse( "2099-12-03T14:00:00.669487800Z" ) ) .build() ); final Content publishedContent = ctxMaster().callWith( () -> this.contentService.getById( site.getId() ) ); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java index 955e8367a06..acdd8465a84 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java @@ -42,7 +42,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.atMostOnce; @@ -407,9 +406,7 @@ void publish_with_message() assertTrue( iterator.hasNext() ); ContentVersion version = iterator.next(); - assertNotNull( version.getPublishInfo().getTimestamp() ); - assertEquals( "user:system:test-user", version.getPublishInfo().getPublisher().toString() ); - assertEquals( "My message", version.getPublishInfo().getMessage() ); + assertEquals( "My message", version.getComment() ); } @Test @@ -426,9 +423,8 @@ void publish_with_message_no_message() assertTrue( iterator.hasNext() ); ContentVersion version = iterator.next(); - assertNotNull( version.getPublishInfo().getTimestamp() ); - assertEquals( "user:system:test-user", version.getPublishInfo().getPublisher().toString() ); - assertNull( version.getPublishInfo().getMessage() ); + assertEquals( "user:system:test-user", version.getPublishedBy().toString() ); + assertEquals( "", version.getComment() ); } @Test diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish_update_publishedTime.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish_update_publishedTime.java index 4a4806c6a5f..f008fd2741a 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish_update_publishedTime.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish_update_publishedTime.java @@ -117,8 +117,7 @@ void set_published_from_now_keeps_published_to() this.contentService.publish( PushContentParams.create() .contentIds( ContentIds.from( content.getId() ) ) - .contentPublishInfo( - ContentPublishInfo.create().to( Instant.now().plus( 1, ChronoUnit.DAYS ) ).build() ) + .publishTo( Instant.now().plus( 1, ChronoUnit.DAYS ) ) .build() ); final ContentPublishInfo publishInfo = this.contentService.getById( content.getId() ).getPublishInfo(); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java index 8176088ed18..978b6c231ef 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java @@ -1,39 +1,22 @@ package com.enonic.xp.core.content; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - import org.junit.jupiter.api.Test; import com.enonic.xp.archive.ArchiveContentParams; import com.enonic.xp.archive.RestoreContentParams; -import com.enonic.xp.branch.Branches; -import com.enonic.xp.content.ActiveContentVersionEntry; import com.enonic.xp.content.Content; -import com.enonic.xp.content.ContentConstants; -import com.enonic.xp.content.ContentIds; import com.enonic.xp.content.ContentPath; import com.enonic.xp.content.ContentVersion; -import com.enonic.xp.content.ContentVersionPublishInfo; import com.enonic.xp.content.CreateContentParams; import com.enonic.xp.content.FindContentVersionsParams; import com.enonic.xp.content.FindContentVersionsResult; -import com.enonic.xp.content.GetActiveContentVersionsParams; -import com.enonic.xp.content.GetActiveContentVersionsResult; -import com.enonic.xp.content.PushContentParams; -import com.enonic.xp.content.UnpublishContentParams; import com.enonic.xp.content.UpdateContentParams; -import com.enonic.xp.content.WorkflowCheckState; -import com.enonic.xp.content.WorkflowInfo; -import com.enonic.xp.content.WorkflowState; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.schema.content.ContentTypeName; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; class ContentServiceImplTest_versions @@ -67,114 +50,6 @@ void get_versions() assertEquals( 2, result.getTotalHits() ); } - @Test - void get_active_versions() - { - final Content content = this.contentService.create( CreateContentParams.create(). - contentData( new PropertyTree() ). - displayName( "This is my test content" ). - parent( ContentPath.ROOT ). - name( "myContent" ). - type( ContentTypeName.folder() ). - build() ); - - this.contentService.publish( PushContentParams.create(). - contentIds( ContentIds.from( content.getId() ) ). - build() ); - - // Two versions, since publish adds one version - assertVersions( content.getId(), 2 ); - - final UpdateContentParams updateContentParams = new UpdateContentParams(); - updateContentParams.contentId( content.getId() ). - editor( edit -> { - edit.displayName = "new display name"; - } ); - - this.contentService.update( updateContentParams ); - - assertVersions( content.getId(), 3 ); - - final GetActiveContentVersionsResult activeVersions = - this.contentService.getActiveVersions( GetActiveContentVersionsParams.create(). - contentId( content.getId() ). - branches( Branches.from( ContentConstants.BRANCH_DRAFT, ContentConstants.BRANCH_MASTER ) ). - build() ); - - final List activeContentVersions = activeVersions.getActiveContentVersions(); - - assertEquals( 2, activeContentVersions.size() ); - - final Iterator iterator = activeContentVersions.iterator(); - - assertNotSame( iterator.next().getContentVersion(), iterator.next().getContentVersion() ); - } - - @Test - void version_workflow_info() - { - final Map checks = - Map.of( "checkName1", WorkflowCheckState.APPROVED, "checkName2", WorkflowCheckState.PENDING ); - - final WorkflowInfo workflowInfo = WorkflowInfo.create(). - state( WorkflowState.IN_PROGRESS ). - checks( checks ). - build(); - - final Content content = this.contentService.create( CreateContentParams.create(). - contentData( new PropertyTree() ). - displayName( "This is my test content" ). - parent( ContentPath.ROOT ). - name( "myContent" ). - type( ContentTypeName.folder() ). - workflowInfo( workflowInfo ). - build() ); - - final FindContentVersionsResult versions = this.contentService.getVersions( FindContentVersionsParams.create(). - contentId( content.getId() ). - build() ); - - final ContentVersion contentVersion = versions.getContentVersions().iterator().next(); - final WorkflowInfo retrievedWorkflowInfo = contentVersion.getWorkflowInfo(); - - assertEquals( WorkflowState.IN_PROGRESS, retrievedWorkflowInfo.getState() ); - assertEquals( WorkflowCheckState.APPROVED, retrievedWorkflowInfo.getChecks().get( "checkName1" ) ); - assertEquals( WorkflowCheckState.PENDING, retrievedWorkflowInfo.getChecks().get( "checkName2" ) ); - } - - @Test - void get_published_versions() - { - final Content content = this.contentService.create( CreateContentParams.create(). - contentData( new PropertyTree() ). - displayName( "content" ). - parent( ContentPath.ROOT ). - name( "myContent" ). - type( ContentTypeName.folder() ). - build() ); - - this.contentService.publish( PushContentParams.create(). - contentIds( ContentIds.from( content.getId() ) ). - build() ); - - this.contentService.unpublish( UnpublishContentParams.create(). - contentIds( ContentIds.from( content.getId() ) ). - build() ); - - final FindContentVersionsResult result = this.contentService.getVersions( FindContentVersionsParams.create(). - contentId( content.getId() ). - build() ); - - assertEquals( 3, result.getContentVersions().getSize() ); - assertEquals( 3, result.getTotalHits() ); - - final Iterator versions = result.getContentVersions().iterator(); - - assertNotNull( versions.next().getPublishInfo() ); - assertNotNull( versions.next().getPublishInfo() ); - assertNull( versions.next().getPublishInfo() ); - } - @Test void get_archived_versions() { @@ -197,8 +72,8 @@ void get_archived_versions() assertEquals( 3, result.getTotalHits() ); assertThat( result.getContentVersions() ).elements( 0, 1 ) - .extracting( v -> v.getPublishInfo().getType() ) - .containsExactly( ContentVersionPublishInfo.CommitType.RESTORED, ContentVersionPublishInfo.CommitType.ARCHIVED ); + .extracting( ContentVersion::getChange ) + .containsExactly( "content.restore", "content.archive" ); } } diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/DumpServiceImplTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/DumpServiceImplTest.java index 53ddf46fbf9..68d3bf7e921 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/DumpServiceImplTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/DumpServiceImplTest.java @@ -65,6 +65,7 @@ import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.NodeVersionQuery; import com.enonic.xp.node.NodeVersionQueryResult; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.node.UpdateNodeParams; import com.enonic.xp.repo.impl.InternalContext; @@ -406,7 +407,8 @@ void versions() void same_version_in_different_branches_not_duplicated() { final Node node = createNode( NodePath.ROOT, "myNode" ); - this.nodeService.push( NodeIds.from( node.id() ), WS_OTHER ); + final NodeIds ids = NodeIds.from( node.id() ); + this.nodeService.push( PushNodeParams.create().ids( ids ).target( WS_OTHER ).build() ); refresh(); final NodeVersionQueryResult versionsBeforeDump = @@ -432,7 +434,8 @@ void different_versions_in_different_branches_not_duplicated() { final Node node = createNode( NodePath.ROOT, "myNode" ); updateNode( node ); - this.nodeService.push( NodeIds.from( node.id() ), WS_OTHER ); + final NodeIds ids = NodeIds.from( node.id() ); + this.nodeService.push( PushNodeParams.create().ids( ids ).target( WS_OTHER ).build() ); updateNode( node ); updateNode( node ); refresh(); @@ -453,7 +456,8 @@ void different_versions_in_different_branches_not_duplicated() void active_versions_after_load() { final Node node = createNode( NodePath.ROOT, "myNode" ); - this.nodeService.push( NodeIds.from( node.id() ), WS_OTHER ); + final NodeIds ids = NodeIds.from( node.id() ); + this.nodeService.push( PushNodeParams.create().ids( ids ).target( WS_OTHER ).build() ); updateNode( node ); refresh(); @@ -477,7 +481,8 @@ void active_versions_after_load() void active_versions_in_versions_list() { final Node node = createNode( NodePath.ROOT, "myNode" ); - this.nodeService.push( NodeIds.from( node.id() ), WS_OTHER ); + final NodeIds ids = NodeIds.from( node.id() ); + this.nodeService.push( PushNodeParams.create().ids( ids ).target( WS_OTHER ).build() ); updateNode( node ); refresh(); @@ -504,7 +509,8 @@ void version_ids_should_stay_the_same_if_no_changes() renameNode( node.id(), "renamed" ); - this.nodeService.push( NodeIds.from( node.id() ), WS_OTHER ); + final NodeIds ids = NodeIds.from( node.id() ); + this.nodeService.push( PushNodeParams.create().ids( ids ).target( WS_OTHER ).build() ); updateNode( node ); refresh(); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/RepoDumperLoadTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/RepoDumperLoadTest.java index dbc2bbea968..a811f4d41a8 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/RepoDumperLoadTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/dump/RepoDumperLoadTest.java @@ -7,7 +7,6 @@ import com.enonic.xp.core.AbstractNodeTest; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.Node; -import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; import com.enonic.xp.repo.impl.dump.RepoDumper; import com.enonic.xp.repo.impl.node.NodeHelper; @@ -36,7 +35,7 @@ void load() parent( NodePath.ROOT ). build() ); // commit every node, so number of commits is also greater than elasticsearch can return in a single query - commit( NodeIds.from( node.id() ) ); + commit( node ); } refresh(); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/index/IndexServiceImplTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/index/IndexServiceImplTest.java index 69385590520..e8728221cdb 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/index/IndexServiceImplTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/index/IndexServiceImplTest.java @@ -23,6 +23,7 @@ import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeQuery; import com.enonic.xp.node.Nodes; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.query.parser.QueryParser; import com.enonic.xp.repo.impl.node.FindNodesByQueryCommand; @@ -117,9 +118,7 @@ void reindex_other_branch() refresh( RefreshMode.ALL ). build() ); - PushNodesCommand.create(). - ids( NodeIds.from( node.id() ) ). - target( WS_OTHER ). + PushNodesCommand.create().params( PushNodeParams.create().ids( NodeIds.from( node.id() ) ).target( WS_OTHER ).build() ). indexServiceInternal( this.indexServiceInternal ). storageService( this.storageService ). searchService( this.searchService ). diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodeCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodeCommandTest.java index e535dfc209a..0e90ac043cc 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodeCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodeCommandTest.java @@ -3,16 +3,17 @@ import org.junit.jupiter.api.Test; import com.enonic.xp.branch.Branch; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.core.AbstractNodeTest; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.PatchNodeParams; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodesResult; import com.enonic.xp.repo.impl.node.CompareNodeCommand; import com.enonic.xp.repo.impl.node.DeleteNodeCommand; @@ -37,7 +38,7 @@ void status_new() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.NEW, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.NEW, comparison.getCompareStatus() ); } @Test @@ -52,7 +53,7 @@ void status_new_target() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.NEW_TARGET, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.NEW_TARGET, comparison.getCompareStatus() ); } @Test @@ -68,7 +69,7 @@ void status_capital_node_id() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.NEW_TARGET, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.NEW_TARGET, comparison.getCompareStatus() ); } @Test @@ -97,7 +98,7 @@ void status_deleted_stage_yields_new_in_target() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.NEW_TARGET, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.NEW_TARGET, comparison.getCompareStatus() ); } @@ -115,7 +116,7 @@ void status_equal() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.EQUAL, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.EQUAL, comparison.getCompareStatus() ); } @Test @@ -136,7 +137,7 @@ void status_newer() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.NEWER, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.NEWER, comparison.getCompareStatus() ); } @Test @@ -157,7 +158,7 @@ void status_older() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.OLDER, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.OLDER, comparison.getCompareStatus() ); } @@ -183,7 +184,7 @@ void status_moved_source() final NodeComparison comparison = ctxDefault().callWith( () -> doCompare( WS_OTHER, createdNode ) ); - assertEquals( CompareStatus.MOVED, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.MOVED, comparison.getCompareStatus() ); } @@ -213,9 +214,7 @@ private Node doUpdateNode( final Node createdNode ) private PushNodesResult doPushNode( final Branch branch, final Node createdNode ) { - return PushNodesCommand.create(). - ids( NodeIds.from( createdNode.id() ) ). - target( branch ). + return PushNodesCommand.create().params( PushNodeParams.create().ids( NodeIds.from( createdNode.id() ) ).target( branch ).build() ). indexServiceInternal( this.indexServiceInternal ). storageService( this.storageService ). searchService( this.searchService ). diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodesCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodesCommandTest.java index a93b992ca06..098ad50a3aa 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodesCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/CompareNodesCommandTest.java @@ -1,18 +1,21 @@ package com.enonic.xp.core.node; +import java.util.List; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.core.AbstractNodeTest; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeCompareStatus; +import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeComparisons; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; import com.enonic.xp.repo.impl.node.CompareNodesCommand; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; class CompareNodesCommandTest extends AbstractNodeTest @@ -54,8 +57,7 @@ void compare_nodes() build(). execute(); - assertEquals( 1, result.getWithStatus( CompareStatus.NEW_TARGET ).size() ); - assertEquals( 1, result.getWithStatus( CompareStatus.NEW ).size() ); - assertEquals( 1, result.getWithStatus( CompareStatus.EQUAL ).size() ); + assertThat( result.getComparisons() ).map( NodeComparison::getCompareStatus ) + .containsOnlyOnceElementsOf( List.of( NodeCompareStatus.NEW_TARGET, NodeCompareStatus.NEW, NodeCompareStatus.EQUAL ) ); } } diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/DuplicateNodeCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/DuplicateNodeCommandTest.java index ff6b4f8cb03..05878efdd45 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/DuplicateNodeCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/DuplicateNodeCommandTest.java @@ -31,7 +31,7 @@ import com.enonic.xp.node.ReorderChildNodeParams; import com.enonic.xp.node.SortNodeParams; import com.enonic.xp.repo.impl.node.DuplicateNodeCommand; -import com.enonic.xp.repo.impl.node.DuplicateNodeResult; +import com.enonic.xp.node.DuplicateNodeResult; import com.enonic.xp.repo.impl.node.SortNodeCommand; import com.enonic.xp.util.BinaryReference; import com.enonic.xp.util.Reference; @@ -96,7 +96,7 @@ void with_children() final DuplicateNodeResult result = duplicateNode( node ); assertDuplicatedTree( node.path(), node, result.getNode() ); - assertEquals( "my-child", result.getChildren().get( 0 ).name().toString() ); + assertEquals( "my-child", result.getChildren().first().name().toString() ); verify( duplicateNodeListener, times( 2 ) ).nodesDuplicated( anyInt() ); } @@ -119,7 +119,7 @@ void references_outside_tree() final DuplicateNodeResult result = duplicateNode( node1 ); assertDuplicatedTree( node1.path(), node1, result.getNode() ); - assertEquals( 1, result.getChildren().size() ); + assertEquals( 1, result.getChildren().getSize() ); } @Test diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesDependenciesCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesDependenciesCommandTest.java index 556f1262d12..8de577d1aa6 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesDependenciesCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesDependenciesCommandTest.java @@ -3,12 +3,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.core.AbstractNodeTest; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparisons; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; @@ -73,7 +73,7 @@ void several_layers_of_dependencies_stopped_by_status() build(). execute(); nodeIds.stream(). - filter( nodeId -> !CompareStatus.EQUAL.equals( currentLevelNodeComparisons.get( nodeId ).getCompareStatus() ) ). + filter( nodeId -> !NodeCompareStatus.EQUAL.equals( currentLevelNodeComparisons.get( nodeId ).getCompareStatus() ) ). forEach( filteredNodeIds::add ); return filteredNodeIds.build(); } ). diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesWithVersionDifferenceCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesWithVersionDifferenceCommandTest.java index d346957d0ac..ee192ebfd88 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesWithVersionDifferenceCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/FindNodesWithVersionDifferenceCommandTest.java @@ -11,8 +11,9 @@ import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; -import com.enonic.xp.node.NodeVersionDiffResult; +import com.enonic.xp.repo.impl.node.NodeVersionDiffResult; import com.enonic.xp.node.PatchNodeParams; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodesResult; import com.enonic.xp.repo.impl.node.FindNodesWithVersionDifferenceCommand; import com.enonic.xp.repo.impl.node.PatchNodeCommand; @@ -345,9 +346,7 @@ private Node doUpdateNode( final Node node ) private PushNodesResult doPushNode( final Branch target, final Node createdNode ) { - return PushNodesCommand.create(). - ids( NodeIds.from( createdNode.id() ) ). - target( target ). + return PushNodesCommand.create().params( PushNodeParams.create().ids( NodeIds.from( createdNode.id() ) ).target( target ).build() ). indexServiceInternal( this.indexServiceInternal ). storageService( this.storageService ). searchService( this.searchService ). diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ImportNodeCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ImportNodeCommandTest.java index 679164c1945..ccc80238c49 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ImportNodeCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ImportNodeCommandTest.java @@ -5,13 +5,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import com.enonic.xp.content.CompareStatus; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.context.ContextBuilder; import com.enonic.xp.core.AbstractNodeTest; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.node.ImportNodeResult; import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; @@ -80,7 +80,7 @@ void created_nodes_with_id_and_timestamp_should_be_equal() build(). execute(); - assertEquals( CompareStatus.EQUAL, comparison.getCompareStatus() ); + assertEquals( NodeCompareStatus.EQUAL, comparison.getCompareStatus() ); } @Test diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/MoveNodeCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/MoveNodeCommandTest.java index f2002b84d1c..62523f03d6e 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/MoveNodeCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/MoveNodeCommandTest.java @@ -7,6 +7,7 @@ import com.enonic.xp.index.ChildOrder; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.MoveNodeException; +import com.enonic.xp.node.MoveNodeParams; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeAccessException; import com.enonic.xp.node.NodeAlreadyExistAtPathException; @@ -39,7 +40,6 @@ void setUp() this.createDefaultRootNode(); } - @Test void timestamp_updated() { @@ -52,9 +52,11 @@ void timestamp_updated() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( node.id() ) - .newNodeName( NodeName.from( "mynode2" ) ) - .newParent( node.parentPath() ) + .params( MoveNodeParams.create() + .nodeId( node.id() ) + .newParentPath( node.parentPath() ) + .newName( NodeName.from( "mynode2" ) ) + .build() ) .build() .execute(); @@ -73,9 +75,11 @@ void new_name_only() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( node.id() ) - .newNodeName( NodeName.from( "mynode2" ) ) - .newParent( node.parentPath() ) + .params( MoveNodeParams.create() + .nodeId( node.id() ) + .newParentPath( node.parentPath() ) + .newName( NodeName.from( "mynode2" ) ) + .build() ) .build() .execute(); @@ -85,7 +89,6 @@ void new_name_only() assertEquals( "mynode2", movedNode.name().toString() ); } - @Test void move_to_child_as_self_not_allowed() { @@ -96,9 +99,8 @@ void move_to_child_as_self_not_allowed() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( node.id() ) - .newNodeName( NodeName.from( "mynode2" ) ) - .newParent( node.path() ) + .params( + MoveNodeParams.create().nodeId( node.id() ).newParentPath( node.path() ).newName( NodeName.from( "mynode2" ) ).build() ) .build() .execute() ); } @@ -116,14 +118,12 @@ void move_to_child_of_own_child_not_allowed() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( node.id() ) - .newNodeName( NodeName.from( "mynode2" ) ) - .newParent( child.path() ) + .params( + MoveNodeParams.create().nodeId( node.id() ).newParentPath( child.path() ).newName( NodeName.from( "mynode2" ) ).build() ) .build() .execute() ); } - @Test void move_node_already_exists() { @@ -139,9 +139,8 @@ void move_node_already_exists() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( node.id() ) - .newNodeName( NodeName.from( "mynode" ) ) - .newParent( newParent.path() ) + .params( + MoveNodeParams.create().nodeId( node.id() ).newParentPath( newParent.path() ).newName( NodeName.from( "mynode" ) ).build() ) .build() .execute() ); } @@ -159,8 +158,10 @@ void move_to_new_parent() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( node.id() ) - .newParent( newParent.path() ) + .params( MoveNodeParams.create() + .nodeId( node.id() ) + .newParentPath( newParent.path() ) + .build() ) .build() .execute(); @@ -181,11 +182,8 @@ void move_with_children() AccessControlEntry.create().principal( TEST_DEFAULT_USER.getKey() ).allowAll().build() ) ) .build() ); - final Node child1 = createNode( CreateNodeParams.create() - .name( "child1" ) - .parent( parent.path() ) - .setNodeId( NodeId.from( "child1" ) ) - .build() ); + final Node child1 = + createNode( CreateNodeParams.create().name( "child1" ).parent( parent.path() ).setNodeId( NodeId.from( "child1" ) ).build() ); final Node child1_1 = createNode( CreateNodeParams.create().name( "child1_1" ).parent( child1.path() ).setNodeId( NodeId.from( "child1_1" ) ).build() ); @@ -203,9 +201,7 @@ void move_with_children() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( child1.id() ) - .newParent( newParent.path() ) - .refresh( RefreshMode.ALL ) + .params( MoveNodeParams.create().nodeId( child1.id() ).newParentPath( newParent.path() ).refresh( RefreshMode.ALL ).build() ) .build() .execute() .getMovedNodes() @@ -245,11 +241,8 @@ void move_with_processed_data() AccessControlEntry.create().principal( TEST_DEFAULT_USER.getKey() ).allowAll().build() ) ) .build() ); - final Node child1 = createNode( CreateNodeParams.create() - .name( "child1" ) - .parent( parent.path() ) - .setNodeId( NodeId.from( "child1" ) ) - .build() ); + final Node child1 = + createNode( CreateNodeParams.create().name( "child1" ).parent( parent.path() ).setNodeId( NodeId.from( "child1" ) ).build() ); final Node child1_1 = createNode( CreateNodeParams.create().name( "child1_1" ).parent( child1.path() ).setNodeId( NodeId.from( "child1_1" ) ).build() ); @@ -264,12 +257,15 @@ void move_with_processed_data() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .refresh( RefreshMode.ALL ) - .id( child1.id() ) - .newParent( newParent.path() ).processor( ( data, path ) -> { - data.addString( "field", "value" ); - return data; - } ) + .params( MoveNodeParams.create() + .nodeId( child1.id() ) + .newParentPath( newParent.path() ) + .refresh( RefreshMode.ALL ) + .processor( ( data, path ) -> { + data.addString( "field", "value" ); + return data; + } ) + .build() ) .build() .execute() .getMovedNodes() @@ -297,7 +293,7 @@ void move_with_processed_data() @Test void move_without_permissions() { - final Node cannonMoveNode = createNode( CreateNodeParams.create() + final Node cannotMoveNode = createNode( CreateNodeParams.create() .name( "mynode" ) .parent( NodePath.ROOT ) .setNodeId( NodeId.from( "mynode" ) ) @@ -344,8 +340,7 @@ void move_without_permissions() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( cannonMoveNode.id() ) - .newParent( canMoveIntoNode.path() ) + .params( MoveNodeParams.create().nodeId( cannotMoveNode.id() ).newParentPath( canMoveIntoNode.path() ).build() ) .build()::execute ); // Tests the check of the CREATE right on the new parent @@ -353,8 +348,7 @@ void move_without_permissions() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( canMoveNode.id() ) - .newParent( cannotMoveIntoNode.path() ) + .params( MoveNodeParams.create().nodeId( canMoveNode.id() ).newParentPath( cannotMoveIntoNode.path() ).build() ) .build()::execute ); } @@ -394,8 +388,7 @@ void move_with_hidden_node() .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( nodeToMove.id() ) - .newParent( newParent.path() ) + .params( MoveNodeParams.create().nodeId( nodeToMove.id() ).newParentPath( newParent.path() ).build() ) .build() .execute(); @@ -441,8 +434,7 @@ private void doMoveNode( final NodePath newParent, final NodeId nodeId ) .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) - .id( nodeId ) - .newParent( newParent ) + .params( MoveNodeParams.create().nodeId( nodeId ).newParentPath( newParent ).build() ) .build() .execute(); } @@ -453,5 +445,4 @@ private NodeVersionQueryResult getVersions( final Node node ) return FindNodeVersionsCommand.create().query( query ).searchService( this.searchService ).build().execute(); } - } diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/NodeServiceImplTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/NodeServiceImplTest.java index ee67d2b3e4f..01cc3dd8d29 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/NodeServiceImplTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/NodeServiceImplTest.java @@ -23,6 +23,7 @@ import com.enonic.xp.event.Event; import com.enonic.xp.index.ChildOrder; import com.enonic.xp.node.ApplyNodePermissionsParams; +import com.enonic.xp.node.CommitNodeParams; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.DeleteNodeParams; import com.enonic.xp.node.DeleteNodeResult; @@ -45,14 +46,13 @@ import com.enonic.xp.node.NodeNotFoundException; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeQuery; +import com.enonic.xp.node.NodeVersionIds; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.NodeVersionMetadatas; import com.enonic.xp.node.OperationNotPermittedException; import com.enonic.xp.node.PatchNodeParams; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.node.ReorderChildNodeParams; -import com.enonic.xp.node.RoutableNodeVersionId; -import com.enonic.xp.node.RoutableNodeVersionIds; import com.enonic.xp.node.SearchTarget; import com.enonic.xp.node.SearchTargets; import com.enonic.xp.node.SortNodeParams; @@ -199,7 +199,7 @@ void test_duplicate_binary() .attachBinary( binaryRef1, ByteSource.wrap( binarySource.getBytes() ) ) .build() ); - final Node duplicatedNode = this.nodeService.duplicate( DuplicateNodeParams.create().nodeId( node.id() ).build() ); + final Node duplicatedNode = this.nodeService.duplicate( DuplicateNodeParams.create().nodeId( node.id() ).build() ).getNode(); assertNotEquals( node, duplicatedNode ); assertEquals( node.getAttachedBinaries(), duplicatedNode.getAttachedBinaries() ); @@ -221,7 +221,7 @@ void test_duplicate_with_children() this.nodeService.refresh( RefreshMode.SEARCH ); - final Node duplicatedNode = this.nodeService.duplicate( DuplicateNodeParams.create().nodeId( node_1.id() ).build() ); + final Node duplicatedNode = this.nodeService.duplicate( DuplicateNodeParams.create().nodeId( node_1.id() ).build() ).getNode(); final NodeId node_1_2_dup_id = this.nodeService.findByParent( FindNodesByParentParams.create().parentId( duplicatedNode.id() ).build() ).getNodeIds().first(); @@ -254,7 +254,7 @@ void test_duplicate_without_children() this.nodeService.refresh( RefreshMode.SEARCH ); final Node duplicatedNode = - this.nodeService.duplicate( DuplicateNodeParams.create().includeChildren( false ).nodeId( node_1.id() ).build() ); + this.nodeService.duplicate( DuplicateNodeParams.create().includeChildren( false ).nodeId( node_1.id() ).build() ).getNode(); final Long childrenNumber = this.nodeService.findByParent( FindNodesByParentParams.create().parentId( duplicatedNode.id() ).build() ).getTotalHits(); @@ -287,7 +287,7 @@ void testDuplicateWithCustomParams() originalData.setString( "extraProp", "extraPropValue" ); return originalData; } ) - .build() ); + .build() ).getNode(); assertEquals( "duplicated-of-child-1", duplicatedNode.name().toString() ); assertEquals( node_1_2.path() + "/duplicated-of-child-1", duplicatedNode.path().toString() ); @@ -363,9 +363,12 @@ void test_commit() //Call commit with the node version ID of the first version final NodeCommitEntry commitEntry2 = NodeCommitEntry.create().message( "Commit message 2" ).build(); - final RoutableNodeVersionId routableNodeVersionId = RoutableNodeVersionId.from( nodeId, firstVersionMetadata2.getNodeVersionId() ); final NodeCommitEntry returnedCommitEntry2 = - nodeService.commit( commitEntry, RoutableNodeVersionIds.from( routableNodeVersionId ) ); + nodeService.commit( CommitNodeParams.create() + .nodeCommitEntry( commitEntry ) + .nodeVersionIds( NodeVersionIds.from( firstVersionMetadata2.getNodeVersionId() ) ) + .build() ); + nodeService.refresh( RefreshMode.STORAGE ); //Check that only the first version has been impacted diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandPerformanceTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandPerformanceTest.java index c3dc4aac56b..d57962f8f46 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandPerformanceTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandPerformanceTest.java @@ -12,6 +12,7 @@ import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodePath; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodesResult; import com.enonic.xp.node.ResolveSyncWorkResult; import com.enonic.xp.repo.impl.node.PushNodesCommand; @@ -48,8 +49,7 @@ void testReferencePerformance() final Stopwatch started = Stopwatch.createStarted(); final PushNodesResult result = PushNodesCommand.create() - .ids( syncWork.getNodeComparisons().getNodeIds() ) - .target( WS_OTHER ) + .params( PushNodeParams.create().ids( syncWork.getNodeComparisons().getNodeIds() ).target( WS_OTHER ).build() ) .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandTest.java index f03f28d385c..bff0d97adab 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/PushNodesCommandTest.java @@ -15,6 +15,7 @@ import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeQuery; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodeResult; import com.enonic.xp.node.PushNodesResult; import com.enonic.xp.node.RefreshMode; @@ -454,8 +455,7 @@ void push_more_than_1024_nodes_at_once() final Stopwatch started = Stopwatch.createStarted(); final PushNodesResult result = PushNodesCommand.create() - .ids( syncWork.getNodeComparisons().getNodeIds() ) - .target( WS_OTHER ) + .params( PushNodeParams.create().ids( syncWork.getNodeComparisons().getNodeIds() ).target( WS_OTHER ).build() ) .indexServiceInternal( this.indexServiceInternal ) .storageService( this.storageService ) .searchService( this.searchService ) diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/RenameNodeCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/RenameNodeCommandTest.java index 57a8a2d66a6..5c299b748dd 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/RenameNodeCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/RenameNodeCommandTest.java @@ -5,6 +5,7 @@ import com.enonic.xp.core.AbstractNodeTest; import com.enonic.xp.node.CreateNodeParams; +import com.enonic.xp.node.MoveNodeParams; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeAlreadyExistAtPathException; import com.enonic.xp.node.NodeName; @@ -28,14 +29,10 @@ void setUp() @Test void rename() { - final Node createdNode = createNode( CreateNodeParams.create(). - name( "my-node" ). - parent( NodePath.ROOT ). - build() ); + final Node createdNode = createNode( CreateNodeParams.create().name( "my-node" ).parent( NodePath.ROOT ).build() ); MoveNodeCommand.create() - .id( createdNode.id() ) - .newNodeName( NodeName.from( "my-node-edited" ) ) + .params( MoveNodeParams.create().nodeId( createdNode.id() ).newName( NodeName.from( "my-node-edited" ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) @@ -50,14 +47,10 @@ void rename() @Test void rename_to_same() { - final Node createdNode = createNode( CreateNodeParams.create(). - name( "my-node" ). - parent( NodePath.ROOT ). - build() ); + final Node createdNode = createNode( CreateNodeParams.create().name( "my-node" ).parent( NodePath.ROOT ).build() ); final MoveNodeCommand command = MoveNodeCommand.create() - .id( createdNode.id() ) - .newNodeName( NodeName.from( "my-node" ) ) + .params( MoveNodeParams.create().nodeId( createdNode.id() ).newName( NodeName.from( "my-node" ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) @@ -69,19 +62,12 @@ void rename_to_same() @Test void rename_to_existing_fails() { - final Node createdNode = createNode( CreateNodeParams.create(). - name( "my-node" ). - parent( NodePath.ROOT ). - build() ); + final Node createdNode = createNode( CreateNodeParams.create().name( "my-node" ).parent( NodePath.ROOT ).build() ); - createNode( CreateNodeParams.create(). - name( "my-node-existing" ). - parent( NodePath.ROOT ). - build() ); + createNode( CreateNodeParams.create().name( "my-node-existing" ).parent( NodePath.ROOT ).build() ); final MoveNodeCommand command = MoveNodeCommand.create() - .id( createdNode.id() ) - .newNodeName( NodeName.from( "my-node-existing" ) ) + .params( MoveNodeParams.create().nodeId( createdNode.id() ).newName( NodeName.from( "my-node-existing" ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) @@ -93,16 +79,12 @@ void rename_to_existing_fails() @Test void timestamp_updated() { - final Node createdNode = createNode( CreateNodeParams.create(). - name( "my-node" ). - parent( NodePath.ROOT ). - build() ); + final Node createdNode = createNode( CreateNodeParams.create().name( "my-node" ).parent( NodePath.ROOT ).build() ); final Node beforeRename = getNodeById( createdNode.id() ); MoveNodeCommand.create() - .id( createdNode.id() ) - .newNodeName( NodeName.from( "my-node-edited" ) ) + .params( MoveNodeParams.create().nodeId( createdNode.id() ).newName( NodeName.from( "my-node-edited" ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) @@ -118,39 +100,20 @@ void timestamp_updated() @Test void rename_with_children() { - final Node createdNode = createNode( CreateNodeParams.create(). - name( "my-node" ). - parent( NodePath.ROOT ). - build() ); - - final Node child1_1 = createNode( CreateNodeParams.create(). - name( "child1_1" ). - parent( createdNode.path() ). - build() ); - - final Node child1_2 = createNode( CreateNodeParams.create(). - name( "child1_2" ). - parent( createdNode.path() ). - build() ); - - final Node child1_1_1 = createNode( CreateNodeParams.create(). - name( "child1_1_1" ). - parent( child1_1.path() ). - build() ); - - final Node child1_2_1 = createNode( CreateNodeParams.create(). - name( "child1_2_1" ). - parent( child1_2.path() ). - build() ); - - final Node child1_2_2 = createNode( CreateNodeParams.create(). - name( "child1_2_2" ). - parent( child1_2.path() ). - build() ); + final Node createdNode = createNode( CreateNodeParams.create().name( "my-node" ).parent( NodePath.ROOT ).build() ); + + final Node child1_1 = createNode( CreateNodeParams.create().name( "child1_1" ).parent( createdNode.path() ).build() ); + + final Node child1_2 = createNode( CreateNodeParams.create().name( "child1_2" ).parent( createdNode.path() ).build() ); + + final Node child1_1_1 = createNode( CreateNodeParams.create().name( "child1_1_1" ).parent( child1_1.path() ).build() ); + + final Node child1_2_1 = createNode( CreateNodeParams.create().name( "child1_2_1" ).parent( child1_2.path() ).build() ); + + final Node child1_2_2 = createNode( CreateNodeParams.create().name( "child1_2_2" ).parent( child1_2.path() ).build() ); MoveNodeCommand.create() - .id( createdNode.id() ) - .newNodeName( NodeName.from( "my-node-edited" ) ) + .params( MoveNodeParams.create().nodeId( createdNode.id() ).newName( NodeName.from( "my-node-edited" ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) @@ -179,23 +142,18 @@ void rename_with_children() @Test void rename_then_create_with_same_name() { - final CreateNodeParams createNodeNamedMyNodeParams = CreateNodeParams.create(). - name( "my-node" ). - parent( NodePath.ROOT ). - build(); + final CreateNodeParams createNodeNamedMyNodeParams = CreateNodeParams.create().name( "my-node" ).parent( NodePath.ROOT ).build(); final Node createdNode = createNode( createNodeNamedMyNodeParams ); MoveNodeCommand.create() - .id( createdNode.id() ) - .newNodeName( NodeName.from( "my-node-edited" ) ) + .params( MoveNodeParams.create().nodeId( createdNode.id() ).newName( NodeName.from( "my-node-edited" ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) .build() .execute(); - createNode( createNodeNamedMyNodeParams ); } @@ -203,8 +161,7 @@ void rename_then_create_with_same_name() void cannot_rename_root_node() { assertThrows( OperationNotPermittedException.class, () -> MoveNodeCommand.create() - .id( Node.ROOT_UUID ) - .newNodeName( NodeName.from( "my-node-edited" ) ) + .params( MoveNodeParams.create().nodeId( Node.ROOT_UUID ).newName( NodeName.from( "my-node-edited" ) ).build() ) .indexServiceInternal( this.indexServiceInternal ) .searchService( this.searchService ) .storageService( this.storageService ) diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ResolveSyncWorkCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ResolveSyncWorkCommandTest.java index f49be1d3a8b..4ad61efe8d6 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ResolveSyncWorkCommandTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/ResolveSyncWorkCommandTest.java @@ -14,6 +14,7 @@ import com.enonic.xp.index.ChildOrder; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.DuplicateNodeParams; +import com.enonic.xp.node.MoveNodeParams; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; @@ -150,8 +151,8 @@ void resolveDependenciesOfMovedNodes() final ResolveSyncWorkResult resultChildrenIncluded = resolveSyncWorkResult( node1_1_1_1.id(), true ); final ResolveSyncWorkResult resultChildrenNotIncluded = resolveSyncWorkResult( node1_1_1_1.id(), false ); - assertEquals( resultChildrenIncluded.getSize(), 4 ); - assertEquals( resultChildrenNotIncluded.getSize(), 4 ); + assertEquals( 4, resultChildrenIncluded.getSize() ); + assertEquals( 4, resultChildrenNotIncluded.getSize() ); } /** @@ -284,19 +285,6 @@ void resolveDependenciesOfMovedNodes3() assertEquals( 1, resultChildrenNotIncluded.getSize() ); } - private void moveNode( Node moveMe, NodePath to ) - { - MoveNodeCommand.create(). - indexServiceInternal( this.indexServiceInternal ). - storageService( this.storageService ). - searchService( this.searchService ). - id( moveMe.id() ). - newNodeName( NodeName.from( moveMe.name() + "_new" ) ). - newParent( to ). - build(). - execute(); - } - @Test void include_referred_nodes() { @@ -1269,15 +1257,32 @@ private void updateNode( final String nodeId ) private void moveNode( final String nodeId, final NodePath newParent, final String newName ) { - MoveNodeCommand.create(). - indexServiceInternal( this.indexServiceInternal ). - storageService( this.storageService ). - searchService( this.searchService ). - id( NodeId.from( nodeId ) ). - newNodeName( NodeName.from( newName ) ). - newParent( newParent ). - build(). - execute(); + MoveNodeCommand.create() + .indexServiceInternal( this.indexServiceInternal ) + .storageService( this.storageService ) + .searchService( this.searchService ) + .params( MoveNodeParams.create() + .nodeId( NodeId.from( nodeId ) ) + .newParentPath( newParent ) + .newName( NodeName.from( newName ) ) + .build() ) + .build() + .execute(); + } + + private void moveNode( Node moveMe, NodePath to ) + { + MoveNodeCommand.create() + .indexServiceInternal( this.indexServiceInternal ) + .storageService( this.storageService ) + .searchService( this.searchService ) + .params( MoveNodeParams.create() + .nodeId( moveMe.id() ) + .newParentPath( to ) + .newName( NodeName.from( moveMe.name() + "_new" ) ) + .build() ) + .build() + .execute(); } diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/SetRootPermissionsCommandTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/SetRootPermissionsCommandTest.java deleted file mode 100644 index de916498073..00000000000 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/node/SetRootPermissionsCommandTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.enonic.xp.core.node; - -import org.junit.jupiter.api.Test; - -import com.enonic.xp.context.Context; -import com.enonic.xp.context.ContextAccessor; -import com.enonic.xp.context.ContextBuilder; -import com.enonic.xp.core.AbstractNodeTest; -import com.enonic.xp.node.Node; -import com.enonic.xp.node.NodeAccessException; -import com.enonic.xp.repo.impl.node.SetRootPermissionsCommand; -import com.enonic.xp.security.PrincipalKey; -import com.enonic.xp.security.acl.AccessControlEntry; -import com.enonic.xp.security.acl.AccessControlList; -import com.enonic.xp.security.acl.Permission; -import com.enonic.xp.security.auth.AuthenticationInfo; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class SetRootPermissionsCommandTest - extends AbstractNodeTest -{ - - @Test - void test_update_permissions() - { - assertNotNull( getNode( Node.ROOT_UUID ) ); - assertNull( anonymousContext().callWith( () -> getNode( Node.ROOT_UUID ) ) ); - - SetRootPermissionsCommand.create(). - indexServiceInternal( this.indexServiceInternal ). - searchService( this.searchService ). - storageService( this.storageService ). - permissions( AccessControlList.create(). - add( AccessControlEntry.create(). - principal( PrincipalKey.ofAnonymous() ). - allow( Permission.READ ). - build() ). - build() ). - build(). - execute(); - - assertNotNull( anonymousContext().callWith( () -> getNode( Node.ROOT_UUID ) ) ); - } - - @Test - void update_without_permission() - { - assertThrows(NodeAccessException.class, () -> anonymousContext().callWith( () -> SetRootPermissionsCommand.create(). - indexServiceInternal( this.indexServiceInternal ). - searchService( this.searchService ). - storageService( this.storageService ). - permissions( AccessControlList.create(). - add( AccessControlEntry.create(). - principal( PrincipalKey.ofAnonymous() ). - allow( Permission.READ ). - build() ). - build() ). - build(). - execute() )); - } - - private Context anonymousContext() - { - return ContextBuilder.from( ContextAccessor.current() ). - authInfo( AuthenticationInfo.unAuthenticated() ). - build(); - } - - -} diff --git a/modules/lib/lib-auditlog/src/test/java/com/enonic/xp/lib/audit/BaseAuditLogHandlerTest.java b/modules/lib/lib-auditlog/src/test/java/com/enonic/xp/lib/audit/BaseAuditLogHandlerTest.java index e5eef4a6ca8..1edc9007bd4 100644 --- a/modules/lib/lib-auditlog/src/test/java/com/enonic/xp/lib/audit/BaseAuditLogHandlerTest.java +++ b/modules/lib/lib-auditlog/src/test/java/com/enonic/xp/lib/audit/BaseAuditLogHandlerTest.java @@ -1,6 +1,7 @@ package com.enonic.xp.lib.audit; import java.time.Instant; +import java.util.Objects; import org.mockito.Mockito; @@ -9,6 +10,7 @@ import com.enonic.xp.audit.AuditLogService; import com.enonic.xp.audit.LogAuditLogParams; import com.enonic.xp.form.PropertyTreeMarshallerService; +import com.enonic.xp.security.PrincipalKey; import com.enonic.xp.testing.ScriptTestSupport; public abstract class BaseAuditLogHandlerTest @@ -37,7 +39,7 @@ protected AuditLog.Builder auditLogBuilder( LogAuditLogParams p ) type( p.getType() ). time( Instant.ofEpochMilli( 1565599442767L ) ). source( p.getSource() ). - user( p.getUser() ). + user( Objects.requireNonNullElse( p.getUser(), PrincipalKey.ofAnonymous()) ). objectUris( p.getObjectUris() ). data( p.getData() ); } diff --git a/modules/lib/lib-auth/src/main/java/com/enonic/xp/lib/auth/ModifyProfileHandler.java b/modules/lib/lib-auth/src/main/java/com/enonic/xp/lib/auth/ModifyProfileHandler.java index ce37c55860c..189d809b95b 100644 --- a/modules/lib/lib-auth/src/main/java/com/enonic/xp/lib/auth/ModifyProfileHandler.java +++ b/modules/lib/lib-auth/src/main/java/com/enonic/xp/lib/auth/ModifyProfileHandler.java @@ -95,7 +95,7 @@ private void updateUser( final EditableUser target, final ScriptValue value ) { if ( scope != null ) { - target.profile.removeProperty( scope ); + target.profile.removeProperties( scope ); } return; } diff --git a/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/ApplyPermissionsHandler.java b/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/ApplyPermissionsHandler.java index aabae0e7fb5..9dfe05977da 100644 --- a/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/ApplyPermissionsHandler.java +++ b/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/ApplyPermissionsHandler.java @@ -8,13 +8,13 @@ import org.slf4j.LoggerFactory; import com.enonic.xp.content.ApplyContentPermissionsParams; +import com.enonic.xp.content.ApplyContentPermissionsScope; import com.enonic.xp.content.Content; import com.enonic.xp.content.ContentId; import com.enonic.xp.content.ContentNotFoundException; import com.enonic.xp.content.ContentPath; import com.enonic.xp.content.ContentService; import com.enonic.xp.lib.content.mapper.ApplyPermissionsResultMapper; -import com.enonic.xp.node.ApplyPermissionsScope; import com.enonic.xp.script.ScriptValue; import com.enonic.xp.script.bean.BeanContext; import com.enonic.xp.script.bean.ScriptBean; @@ -35,7 +35,7 @@ public final class ApplyPermissionsHandler private String key; - private ApplyPermissionsScope scope; + private ApplyContentPermissionsScope scope; private AccessControlList permissions = AccessControlList.empty(); @@ -50,7 +50,7 @@ public void setKey( final String key ) public void setScope( final String scope ) { - this.scope = scope != null ? ApplyPermissionsScope.valueOf( scope ) : null; + this.scope = scope != null ? ApplyContentPermissionsScope.valueOf( scope ) : null; } public void setPermissions( final ScriptValue permissions ) diff --git a/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/PublishContentHandler.java b/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/PublishContentHandler.java index 388a67e96d8..5890bad1e8b 100644 --- a/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/PublishContentHandler.java +++ b/modules/lib/lib-content/src/main/java/com/enonic/xp/lib/content/PublishContentHandler.java @@ -84,11 +84,8 @@ private PublishContentResultMapper publishContent() { final Object from = this.contentPublishInfo.get( "from" ); final Object to = this.contentPublishInfo.get( "to" ); - final ContentPublishInfo contentPublishInfo = ContentPublishInfo.create(). - from( from == null ? null : Instant.parse( (String) from ) ). - to( to == null ? null : Instant.parse( (String) to ) ). - build(); - builder.contentPublishInfo( contentPublishInfo ); + builder.publishFrom( from == null ? null : Instant.parse( (String) from ) ); + builder.publishTo( to == null ? null : Instant.parse( (String) to ) ); } if ( this.excludeDescendantsOf != null ) { diff --git a/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/ApplyPermissionsHandlerTest.java b/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/ApplyPermissionsHandlerTest.java index c1e32650b10..eca1dc1d682 100644 --- a/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/ApplyPermissionsHandlerTest.java +++ b/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/ApplyPermissionsHandlerTest.java @@ -9,9 +9,9 @@ import com.enonic.xp.content.ApplyContentPermissionsParams; import com.enonic.xp.content.ApplyContentPermissionsResult; +import com.enonic.xp.content.ApplyContentPermissionsScope; import com.enonic.xp.content.Content; import com.enonic.xp.content.ContentNotFoundException; -import com.enonic.xp.node.ApplyPermissionsScope; import com.enonic.xp.security.Principal; import com.enonic.xp.security.PrincipalKey; import com.enonic.xp.security.RoleKeys; @@ -175,6 +175,6 @@ void testTreeScope() verify( contentService ).applyPermissions( paramsCaptor.capture() ); - assertEquals( ApplyPermissionsScope.TREE, paramsCaptor.getValue().getScope() ); + assertEquals( ApplyContentPermissionsScope.TREE, paramsCaptor.getValue().getScope() ); } } diff --git a/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/PublishContentHandlerTest.java b/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/PublishContentHandlerTest.java index 45151ad699c..3e27cd9e705 100644 --- a/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/PublishContentHandlerTest.java +++ b/modules/lib/lib-content/src/test/java/com/enonic/xp/lib/content/PublishContentHandlerTest.java @@ -61,9 +61,13 @@ private static PublishContentResult exampleResult() exampleContent( PUB_ID_3, "content3", "Content 3", "/mysite/page3", "myfield", "Hello x 3" ) ); Contents failed = Contents.from( exampleContent( FAIL_ID, "badcontent", "Bad bad Content", "/mysite/fail", "myop", "Publish" ) ); - return PublishContentResult.create().setPushed( published.getIds() ). - setFailed( failed.getIds() ). - build(); + final PublishContentResult.Builder builder = PublishContentResult.create(); + published.getIds().stream().map( PublishContentResult.Result::success ).forEach( builder::add ); + failed.getIds() + .stream() + .map( c -> new PublishContentResult.Result( c, PublishContentResult.Reason.INVALID ) ) + .forEach( builder::add ); + return builder.build(); } @Test @@ -115,9 +119,10 @@ void publishWithoutChildrenOrDependencies() { Contents published = Contents.from( exampleContent( PUB_ID_3, "mycontent", "My Content", "/mysite/somepage", "myfield", "Hello World" ) ); - PublishContentResult exampleResult = PublishContentResult.create(). - setPushed( published.getIds() ). - build(); + final PublishContentResult.Builder builder = PublishContentResult.create(); + published.getIds().stream().map( PublishContentResult.Result::success ).forEach( builder::add ); + + PublishContentResult exampleResult = builder.build(); final ArgumentCaptor captor = ArgumentCaptor.forClass( PushContentParams.class ); when( this.contentService.publish( captor.capture() ) ).thenReturn( exampleResult ); diff --git a/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/DuplicateNodeHandler.java b/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/DuplicateNodeHandler.java index cb716f9b9f5..fc8304104d9 100644 --- a/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/DuplicateNodeHandler.java +++ b/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/DuplicateNodeHandler.java @@ -48,7 +48,7 @@ public Object execute() .includeChildren( this.includeChildren ) .dataProcessor( this.dataProcessor ) .refresh( this.refresh ) - .build() ) ); + .build() ).getNode() ); } public static final class Builder diff --git a/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/PushNodeHandler.java b/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/PushNodeHandler.java index 564fd5ae76f..d5e8370a5e4 100644 --- a/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/PushNodeHandler.java +++ b/modules/lib/lib-node/src/main/java/com/enonic/xp/lib/node/PushNodeHandler.java @@ -5,6 +5,7 @@ import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodeNotFoundException; +import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.PushNodesResult; import com.enonic.xp.node.ResolveSyncWorkResult; import com.enonic.xp.node.SyncWorkResolverParams; @@ -51,7 +52,8 @@ public Object execute() toBePushed.addAll( getNodeIds() ); } - final PushNodesResult push = this.nodeService.push( toBePushed.build(), targetBranch ); + final NodeIds ids = toBePushed.build(); + final PushNodesResult push = this.nodeService.push( PushNodeParams.create().ids( ids ).target( targetBranch ).build() ); return new PushNodesResultMapper( push ); } diff --git a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DeleteNodeHandlerTest.java b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DeleteNodeHandlerTest.java index a548515000f..9727d999eb8 100644 --- a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DeleteNodeHandlerTest.java +++ b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DeleteNodeHandlerTest.java @@ -7,8 +7,8 @@ import com.enonic.xp.content.ContentConstants; import com.enonic.xp.node.DeleteNodeResult; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; +import com.enonic.xp.node.NodeVersionId; import com.enonic.xp.repository.Repository; import com.enonic.xp.repository.RepositoryId; @@ -21,10 +21,11 @@ class DeleteNodeHandlerTest { private void mockGetNode() { - when( this.nodeService.delete( any() ) ).thenReturn( DeleteNodeResult.create().nodeIds( NodeIds.empty() ).build() ); + when( this.nodeService.delete( any() ) ).thenReturn( DeleteNodeResult.create().build() ); final DeleteNodeResult result = DeleteNodeResult.create() - .nodeIds( NodeIds.from(NodeId.from( "nodeId" ), NodeId.from( "aSubNodeId" ) ) ) + .add( new DeleteNodeResult.Result( NodeId.from( "nodeId" ), NodeVersionId.from( "nodeVersionId" ) ) ) + .add( new DeleteNodeResult.Result( NodeId.from( "aSubNodeId" ), NodeVersionId.from( "aSubNodeVersionId" ) ) ) .build(); doReturn( result ).when( this.nodeService ) .delete( ArgumentMatchers.argThat( argument -> NodeId.from( "nodeId" ).equals( argument.getNodeId() ) ) ); diff --git a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DiffBranchesHandlerTest.java b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DiffBranchesHandlerTest.java index 178b0ef7a92..e409c45d6f7 100644 --- a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DiffBranchesHandlerTest.java +++ b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DiffBranchesHandlerTest.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import com.enonic.xp.content.CompareStatus; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; @@ -18,15 +18,15 @@ void testExample1() { Mockito.when( nodeService.resolveSyncWork( Mockito.isA( SyncWorkResolverParams.class ) ) ). thenReturn( ResolveSyncWorkResult.create(). - add( createNodeComparison( "a", "a", CompareStatus.NEW ) ). - add( createNodeComparison( "b" , "b", CompareStatus.MOVED ) ). - add( createNodeComparison( "c" , "c", CompareStatus.OLDER ) ). + add( createNodeComparison( "a", "a", NodeCompareStatus.NEW ) ). + add( createNodeComparison( "b" , "b", NodeCompareStatus.MOVED ) ). + add( createNodeComparison( "c" , "c", NodeCompareStatus.OLDER ) ). build() ); runScript( "/lib/xp/examples/node/diff-1.js" ); } - private NodeComparison createNodeComparison( String a, String b, CompareStatus status ) + private NodeComparison createNodeComparison( String a, String b, NodeCompareStatus status ) { return new NodeComparison( NodeId.from( a ), new NodePath( "/" + a ), NodeId.from( b ), new NodePath( "/" + b ), status ); diff --git a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DuplicateNodeHandlerTest.java b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DuplicateNodeHandlerTest.java index 2087480e2b4..e8227ac94b7 100644 --- a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DuplicateNodeHandlerTest.java +++ b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/DuplicateNodeHandlerTest.java @@ -6,6 +6,7 @@ import com.enonic.xp.data.PropertySet; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.node.DuplicateNodeParams; +import com.enonic.xp.node.DuplicateNodeResult; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; @@ -41,7 +42,7 @@ void testExample() final ArgumentCaptor captor = ArgumentCaptor.forClass( DuplicateNodeParams.class ); - when( nodeService.duplicate( captor.capture() ) ).thenReturn( node ); + when( nodeService.duplicate( captor.capture() ) ).thenReturn( DuplicateNodeResult.create().node( node ).build() ); runScript( "/lib/xp/examples/node/duplicate.js" ); diff --git a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/PushNodeHandlerTest.java b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/PushNodeHandlerTest.java index 9269f493fb2..b9dbd68e019 100644 --- a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/PushNodeHandlerTest.java +++ b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/PushNodeHandlerTest.java @@ -3,11 +3,9 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import com.enonic.xp.branch.Branch; -import com.enonic.xp.content.CompareStatus; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersionId; import com.enonic.xp.node.PushNodeResult; @@ -15,7 +13,7 @@ import com.enonic.xp.node.ResolveSyncWorkResult; import com.enonic.xp.node.SyncWorkResolverParams; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; class PushNodeHandlerTest @@ -24,7 +22,7 @@ class PushNodeHandlerTest @Test void testExample1() { - when( nodeService.push( eq( NodeIds.from( "a" ) ), eq( Branch.from( "otherBranch" ) ) ) ) + when( nodeService.push( any() ) ) .thenReturn( PushNodesResult.create().add( createPushNodeResult( "a", "/a") ).build() ); runScript( "/lib/xp/examples/node/push-1.js" ); @@ -45,7 +43,7 @@ void testExample2() add( createNodeComparison("c", "c") ). build() ); - when( nodeService.push( Mockito.isA( NodeIds.class ), eq( Branch.from( "otherBranch" ) ) ) ). + when( nodeService.push( any() ) ). thenReturn( PushNodesResult.create() .add( createPushNodeResult( "a", "/b") ) .add( createPushNodeResult( "b", "/b") ) @@ -66,7 +64,7 @@ void testExample3() add( createNodeComparison("c" ,"c") ). build() ); - when( nodeService.push( Mockito.isA( NodeIds.class ), eq( Branch.from( "otherBranch" ) ) ) ). + when( nodeService.push( any() ) ). thenReturn( PushNodesResult.create() .add( createPushNodeResult( "a", "/a") ) .add( createPushNodeResult( "d", "/d") ) @@ -85,11 +83,7 @@ void testExampleWithChildren() add( createNodeComparison("c", "c") ). build() ); - when( nodeService.push( eq( NodeIds.create(). - add( NodeId.from( "a" ) ). - add( NodeId.from( "b" ) ). - add( NodeId.from( "c" ) ). - build() ), eq( Branch.from( "otherBranch" ) ) ) ). + when( nodeService.push( any() ) ). thenReturn( PushNodesResult.create() .add( createPushNodeResult( "a", "/a") ) .add( createPushNodeResult( "b", "/b") ) @@ -102,7 +96,7 @@ void testExampleWithChildren() private NodeComparison createNodeComparison( String a, String b ) { return new NodeComparison( NodeId.from( a ), new NodePath( "/" + a ), NodeId.from( b ), new NodePath( "/" + b ), - CompareStatus.NEW ); + NodeCompareStatus.NEW ); } private static PushNodeResult createNodePushResultFailed( String a, PushNodeResult.Reason reason ) diff --git a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/mapper/ResolveSyncWorkResultMapperTest.java b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/mapper/ResolveSyncWorkResultMapperTest.java index 3c44dcac253..5a0e39b4e1f 100644 --- a/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/mapper/ResolveSyncWorkResultMapperTest.java +++ b/modules/lib/lib-node/src/test/java/com/enonic/xp/lib/node/mapper/ResolveSyncWorkResultMapperTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; -import com.enonic.xp.content.CompareStatus; +import com.enonic.xp.node.NodeCompareStatus; import com.enonic.xp.node.NodeComparison; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; @@ -15,15 +15,15 @@ class ResolveSyncWorkResultMapperTest void full() { final ResolveSyncWorkResult result = ResolveSyncWorkResult.create(). - add( createNodeComparison( "a", "a", CompareStatus.NEW ) ). - add( createNodeComparison( "b" , "b", CompareStatus.MOVED ) ). - add( createNodeComparison( "c" , "c", CompareStatus.NEWER ) ). + add( createNodeComparison( "a", "a", NodeCompareStatus.NEW ) ). + add( createNodeComparison( "b" , "b", NodeCompareStatus.MOVED ) ). + add( createNodeComparison( "c" , "c", NodeCompareStatus.NEWER ) ). build(); JsonAssert.assertMapper( getClass(), "resolveSyncWork/full.json", new ResolveSyncWorkResultMapper( result ) ); } - private NodeComparison createNodeComparison( String a, String b, CompareStatus status ) + private NodeComparison createNodeComparison( String a, String b, NodeCompareStatus status ) { return new NodeComparison( NodeId.from( a ), new NodePath( "/" + a ), NodeId.from( b ), new NodePath( "/" + b ), status ); diff --git a/modules/lib/lib-project/src/main/java/com/enonic/xp/lib/project/command/ApplyProjectReadAccessCommand.java b/modules/lib/lib-project/src/main/java/com/enonic/xp/lib/project/command/ApplyProjectReadAccessCommand.java index fe169a5e48d..d8bab92f10b 100644 --- a/modules/lib/lib-project/src/main/java/com/enonic/xp/lib/project/command/ApplyProjectReadAccessCommand.java +++ b/modules/lib/lib-project/src/main/java/com/enonic/xp/lib/project/command/ApplyProjectReadAccessCommand.java @@ -1,9 +1,9 @@ package com.enonic.xp.lib.project.command; import com.enonic.xp.content.ApplyContentPermissionsParams; +import com.enonic.xp.content.ApplyContentPermissionsScope; import com.enonic.xp.content.Content; import com.enonic.xp.content.ContentPath; -import com.enonic.xp.node.ApplyPermissionsScope; import com.enonic.xp.security.RoleKeys; import com.enonic.xp.security.acl.AccessControlEntry; import com.enonic.xp.security.acl.AccessControlList; @@ -38,9 +38,11 @@ private Boolean doExecute() ? doAddEveryonePermissions( contentRoot.getPermissions() ) : doRemoveEveryonePermissions( contentRoot.getPermissions() ); - contentService.applyPermissions( ApplyContentPermissionsParams.create(). - permissions( newList ).contentId( contentRoot.getId() ).applyPermissionsScope( ApplyPermissionsScope.TREE ). - build() ); + contentService.applyPermissions( ApplyContentPermissionsParams.create() + .permissions( newList ) + .contentId( contentRoot.getId() ) + .applyPermissionsScope( ApplyContentPermissionsScope.TREE ) + .build() ); return GetProjectReadAccessCommand.create(). contentService( this.contentService ). From 24b093463f147c6325d511ca7f131ba77c6d9c2e Mon Sep 17 00:00:00 2001 From: rymsha Date: Thu, 30 Oct 2025 08:48:32 +0100 Subject: [PATCH 2/8] wip --- .../com/enonic/xp/content/ContentVersion.java | 21 +++++++++++++++++++ .../ApplyContentPermissionsCommand.java | 15 +++++-------- .../GetContentByIdAndVersionIdCommand.java | 2 +- .../node/ApplyNodePermissionsCommand.java | 14 ++----------- .../impl/node/CheckNodeExistsCommand.java | 2 +- .../xp/repo/impl/node/CreateNodeCommand.java | 2 +- .../repo/impl/node/CreateRootNodeCommand.java | 6 +++--- .../impl/node/FindNodeIdsByParentCommand.java | 12 +---------- .../FindNodesByMultiRepoQueryCommand.java | 10 --------- .../impl/node/FindNodesByQueryCommand.java | 10 --------- .../node/FindNodesDependenciesCommand.java | 2 +- .../node/GetActiveNodeVersionsCommand.java | 12 +---------- .../impl/node/GetBinaryByVersionCommand.java | 3 +-- .../xp/repo/impl/node/GetNodeByIdCommand.java | 2 +- .../repo/impl/node/GetNodeByPathCommand.java | 3 +-- .../repo/impl/node/GetNodesByIdsCommand.java | 10 --------- .../impl/node/GetNodesByPathsCommand.java | 11 ---------- .../xp/repo/impl/node/PatchNodeCommand.java | 11 ++-------- .../xp/repo/impl/node/PushNodesCommand.java | 2 +- .../node/ResolveInsertOrderValueCommand.java | 2 +- .../vacuum/segment/SegmentVacuumCommand.java | 2 +- .../version/search/NodeVersionDiffQuery.java | 2 +- .../enonic/xp/portal/macro/MacroContext.java | 2 +- 23 files changed, 47 insertions(+), 111 deletions(-) diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java index 0c5c6abfb1d..2d5181c4c91 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java @@ -2,6 +2,7 @@ import java.time.Instant; import java.util.List; +import java.util.Objects; import com.enonic.xp.annotation.PublicApi; import com.enonic.xp.security.PrincipalKey; @@ -135,6 +136,26 @@ public Attributes getAttributes() return attributes; } + @Override + public boolean equals( final Object o ) + { + return o instanceof final ContentVersion that && Objects.equals( id, that.id ) && Objects.equals( path, that.path ) && + Objects.equals( timestamp, that.timestamp ) && Objects.equals( change, that.change ) && + Objects.equals( changeFields, that.changeFields ) && Objects.equals( changedTime, that.changedTime ) && + Objects.equals( changedBy, that.changedBy ) && Objects.equals( publishedTime, that.publishedTime ) && + Objects.equals( publishedBy, that.publishedBy ) && Objects.equals( publishedFrom, that.publishedFrom ) && + Objects.equals( publishedTo, that.publishedTo ) && Objects.equals( unpublishedTime, that.unpublishedTime ) && + Objects.equals( unpublishedBy, that.unpublishedBy ) && Objects.equals( comment, that.comment ) && + Objects.equals( attributes, that.attributes ); + } + + @Override + public int hashCode() + { + return Objects.hash( id, path, timestamp, change, changeFields, changedTime, changedBy, publishedTime, publishedBy, publishedFrom, + publishedTo, unpublishedTime, unpublishedBy, comment, attributes ); + } + public static Builder create() { return new Builder(); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java index 64b7c0262a5..617f238a3d7 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ApplyContentPermissionsCommand.java @@ -1,5 +1,7 @@ package com.enonic.xp.core.impl.content; +import java.util.Objects; + import com.enonic.xp.branch.Branches; import com.enonic.xp.content.ApplyContentPermissionsParams; import com.enonic.xp.content.ApplyContentPermissionsResult; @@ -12,7 +14,6 @@ import com.enonic.xp.node.ApplyNodePermissionsResult; import com.enonic.xp.node.ApplyPermissionsScope; import com.enonic.xp.node.CommitNodeParams; -import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeVersionIds; @@ -74,18 +75,12 @@ private void commitResult( final ApplyNodePermissionsResult result ) final NodeVersionIds versionIdsToCommit = result.getResults() .entrySet() .stream() - .flatMap( Collection::stream ) - .filter( branchResult -> ContentConstants.BRANCH_MASTER.equals( branchResult.branch() ) ) - .map( ApplyNodePermissionsResult.BranchResult::node ) - .filter( Objects::nonNull ) - .map( Node::getNodeVersionId ) - .collect( NodeVersionIds.collector() ); .flatMap( entry -> entry.getValue() .stream() .filter( br -> ContentConstants.BRANCH_MASTER.equals( br.branch() ) ) - .filter( br -> br.nodeVersionId() != null ) - .map( br -> RoutableNodeVersionId.from( entry.getKey(), br.nodeVersionId() ) ) ) - .collect( RoutableNodeVersionIds.collector() ); + .map( ApplyNodePermissionsResult.BranchResult::nodeVersionId ) + .filter( Objects::nonNull ) ) + .collect( NodeVersionIds.collector() ); if ( !versionIdsToCommit.isEmpty() ) { diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetContentByIdAndVersionIdCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetContentByIdAndVersionIdCommand.java index 3cdd639fc38..13bd05992cd 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetContentByIdAndVersionIdCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/GetContentByIdAndVersionIdCommand.java @@ -62,7 +62,7 @@ public static class Builder private ContentVersionId versionId; - public Builder() + private Builder() { super(); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java index fc3748c30e1..7a88fc11b55 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ApplyNodePermissionsCommand.java @@ -68,7 +68,7 @@ public static Builder create() return new Builder(); } - public static Builder create( AbstractNodeCommand source ) + static Builder create( AbstractNodeCommand source ) { return new Builder( source ); } @@ -205,17 +205,7 @@ private NodeVersionData updatePermissionsInBranch( final NodeId nodeId, final No return NodeHelper.runAsAdmin( () -> { if ( updatedVersionData != null ) { - this.nodeStorageService.push( List.of( NodeBranchEntry.fromNodeVersionMetadata( updatedVersionMetadata ) ), branch, l -> { - this.nodeStorageService.push( List.of( NodeBranchEntry.create() - .nodeVersionId( updatedVersionData.node().getNodeVersionId() ) - .nodePath( updatedVersionData.node().path() ) - .nodeVersionKey( - updatedVersionData.metadata().getNodeVersionKey() ) - .nodeId( updatedVersionData.node().id() ) - .timestamp( updatedVersionData.metadata().getTimestamp() ) - .build() ), branch, l -> { - }, targetContext ); - + this.nodeStorageService.push( List.of( NodeBranchEntry.fromNodeVersionMetadata( updatedVersionData.metadata() ) ), branch, l -> {}, targetContext); return updatedVersionData; } else diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CheckNodeExistsCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CheckNodeExistsCommand.java index 560796301ea..dc7b7bac613 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CheckNodeExistsCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CheckNodeExistsCommand.java @@ -31,7 +31,7 @@ public static Builder create() return new Builder(); } - public static Builder create( AbstractNodeCommand source ) + static Builder create( AbstractNodeCommand source ) { return new Builder( source ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java index f17bb9a4389..d68b1cd2351 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateNodeCommand.java @@ -55,7 +55,7 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) + static Builder create( final AbstractNodeCommand source ) { return new Builder( source ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateRootNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateRootNodeCommand.java index 46359df1ae0..ccd223aa022 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateRootNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/CreateRootNodeCommand.java @@ -23,7 +23,7 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) + static Builder create( final AbstractNodeCommand source ) { return new Builder( source ); } @@ -44,12 +44,12 @@ public static class Builder { private CreateRootNodeParams params; - public Builder() + private Builder() { super(); } - public Builder( final AbstractNodeCommand source ) + private Builder( final AbstractNodeCommand source ) { super( source ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodeIdsByParentCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodeIdsByParentCommand.java index f5502136b56..2c51f37961d 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodeIdsByParentCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodeIdsByParentCommand.java @@ -57,11 +57,6 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - public FindNodesByParentResult execute() { NodePath parentPath = getParentPath(); @@ -166,16 +161,11 @@ public static class Builder private boolean recursive; - public Builder() + private Builder() { super(); } - public Builder( final AbstractNodeCommand source ) - { - super( source ); - } - public FindNodeIdsByParentCommand build() { this.validate(); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByMultiRepoQueryCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByMultiRepoQueryCommand.java index 4d9042e694b..30eadfe875d 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByMultiRepoQueryCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByMultiRepoQueryCommand.java @@ -26,11 +26,6 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - public FindNodesByMultiRepoQueryResult execute() { final SearchTargets searchTargets = query.getSearchTargets(); @@ -61,11 +56,6 @@ private Builder() super(); } - private Builder( final AbstractNodeCommand source ) - { - super( source ); - } - public Builder query( MultiRepoNodeQuery query ) { this.query = query; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryCommand.java index e79276b408e..09917d1f0ac 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesByQueryCommand.java @@ -28,11 +28,6 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - public FindNodesByQueryResult execute() { final SearchResult result = @@ -53,11 +48,6 @@ private Builder() super(); } - private Builder( final AbstractNodeCommand source ) - { - super( source ); - } - public Builder query( NodeQuery query ) { this.query = query; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java index bc6d269ddb7..c430ee5443b 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java @@ -41,7 +41,7 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) + static Builder create( final AbstractNodeCommand source ) { return new Builder( source ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetActiveNodeVersionsCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetActiveNodeVersionsCommand.java index d7958ae8716..ce79b3cb42a 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetActiveNodeVersionsCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetActiveNodeVersionsCommand.java @@ -24,11 +24,6 @@ private GetActiveNodeVersionsCommand( final Builder builder ) this.nodeId = builder.nodeId; } - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - public static Builder create() { return new Builder(); @@ -58,12 +53,7 @@ public static final class Builder private NodeId nodeId; - public Builder( final AbstractNodeCommand source ) - { - super( source ); - } - - public Builder() + private Builder() { } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetBinaryByVersionCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetBinaryByVersionCommand.java index 7a1985be05a..11a1bf15819 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetBinaryByVersionCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetBinaryByVersionCommand.java @@ -54,8 +54,7 @@ public static class Builder private NodeId nodeId; - - public Builder() + private Builder() { super(); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByIdCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByIdCommand.java index 56be34244c2..60ce34a0f62 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByIdCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByIdCommand.java @@ -28,7 +28,7 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) + static Builder create( final AbstractNodeCommand source ) { return new Builder( source ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByPathCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByPathCommand.java index 09d47905fb4..d062a12be68 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByPathCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodeByPathCommand.java @@ -28,12 +28,11 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) + static Builder create( final AbstractNodeCommand source ) { return new Builder( source ); } - public static final class Builder extends AbstractNodeCommand.Builder { diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByIdsCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByIdsCommand.java index 7966ef6c8d5..5c52a486035 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByIdsCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByIdsCommand.java @@ -23,11 +23,6 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - public Nodes execute() { return this.nodeStorageService.get( ids, InternalContext.from( ContextAccessor.current() ) ); @@ -43,11 +38,6 @@ private Builder() super(); } - private Builder( final AbstractNodeCommand source ) - { - super( source ); - } - public Builder ids( NodeIds ids ) { this.ids = ids; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByPathsCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByPathsCommand.java index cd5e45c5d15..c2e7e39a060 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByPathsCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/GetNodesByPathsCommand.java @@ -28,12 +28,6 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) - { - return new Builder( source ); - } - - public static final class Builder extends AbstractNodeCommand.Builder { @@ -43,11 +37,6 @@ private Builder() { } - private Builder( final AbstractNodeCommand source ) - { - super( source ); - } - public Builder paths( NodePaths paths ) { this.paths = paths; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java index de551e498e9..fb4a46548c3 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PatchNodeCommand.java @@ -98,7 +98,7 @@ private void verifyPermissions() { Permission requiredPermission; - if ( firstBranch.equals( branch ) || + if ( branch.equals( firstBranch ) || !activeNodeMap.get( firstBranch ).getNodeVersionId().equals( persistedNode.getNodeVersionId() ) ) { requiredPermission = Permission.MODIFY; @@ -163,14 +163,7 @@ private NodeVersionData patchNodeInBranch( final NodeVersionData patchedNode, fi if ( patchedNode != null ) { - this.nodeStorageService.push( List.of( NodeBranchEntry.create() - .nodeVersionId( patchedNode.node().getNodeVersionId() ) - .nodePath( patchedNode.node().path() ) - .nodeVersionKey( patchedNode.metadata().getNodeVersionKey() ) - .nodeId( patchedNode.node().id() ) - .timestamp( patchedNode.node().getTimestamp() ) - .build() ), branch, l -> { - this.nodeStorageService.push( List.of( NodeBranchEntry.fromNodeVersionMetadata( patchedVersionMetadata ) ), branch, l -> { + this.nodeStorageService.push( List.of( NodeBranchEntry.fromNodeVersionMetadata( patchedNode.metadata() ) ), branch, l -> { }, internalContext ); return patchedNode; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java index 973ea32956e..3408735acee 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/PushNodesCommand.java @@ -213,7 +213,7 @@ private NodeBranchEntry processBeforePush( NodeBranchEntry nbe, InternalContext final NodeVersionData stored = this.nodeStorageService.store( StoreNodeParams.newVersion( changedNode ), internalContext ); - return NodeBranchEntry.fromNodeVersionMetadata( stored.nodeVersionMetadata() ); + return NodeBranchEntry.fromNodeVersionMetadata( stored.metadata() ); } private boolean targetAlreadyExists( final NodePath nodePath, final NodeComparisons comparisons ) diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java index dbc646cec46..885e6bf33cd 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/ResolveInsertOrderValueCommand.java @@ -93,7 +93,7 @@ public static Builder create() return new Builder(); } - public static Builder create( final AbstractNodeCommand source ) + static Builder create( final AbstractNodeCommand source ) { return new Builder( source ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/vacuum/segment/SegmentVacuumCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/vacuum/segment/SegmentVacuumCommand.java index d9e62723c78..d2c8be3d3a3 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/vacuum/segment/SegmentVacuumCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/vacuum/segment/SegmentVacuumCommand.java @@ -144,7 +144,7 @@ public static final class Builder private VacuumTaskParams params; - public Builder() + private Builder() { } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java index d8ec8feec82..6b9ad7af2f6 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java @@ -62,7 +62,7 @@ public static class Builder private final NodePaths.Builder excludes = NodePaths.create(); - public Builder() + private Builder() { super(); } diff --git a/modules/portal/portal-api/src/main/java/com/enonic/xp/portal/macro/MacroContext.java b/modules/portal/portal-api/src/main/java/com/enonic/xp/portal/macro/MacroContext.java index f9cf685ccb9..4ba627eeb38 100644 --- a/modules/portal/portal-api/src/main/java/com/enonic/xp/portal/macro/MacroContext.java +++ b/modules/portal/portal-api/src/main/java/com/enonic/xp/portal/macro/MacroContext.java @@ -120,7 +120,7 @@ public static class Builder private String document; - public Builder() + private Builder() { this.paramsBuilder = ImmutableListMultimap.builder(); } From 148dc1dcfc05d8888f0d917688a7551b9f6d1b96 Mon Sep 17 00:00:00 2001 From: rymsha Date: Thu, 30 Oct 2025 14:16:10 +0100 Subject: [PATCH 3/8] wip --- .../impl/content/ContentAttributesHelper.java | 2 +- .../com/enonic/xp/repo/impl/ReturnValues.java | 10 ++----- .../impl/branch/storage/BranchIndexPath.java | 5 +++- .../branch/storage/BranchServiceImpl.java | 5 +--- .../storage/NodeBranchVersionFactory.java | 1 + .../repo/impl/commit/CommitServiceImpl.java | 3 +- .../impl/commit/storage/CommitIndexPath.java | 5 ++++ .../SearchRequestBuilderFactory.java | 2 +- .../query/ElasticsearchQuery.java | 4 +-- .../translator/factory/DiffQueryFactory.java | 2 +- .../node/FindNodesDependenciesCommand.java | 2 +- ...FindNodesWithVersionDifferenceCommand.java | 3 ++ .../impl/search/NodeSearchServiceImpl.java | 24 ++++++--------- .../repo/impl/storage/IndexDataService.java | 3 -- .../impl/storage/IndexDataServiceImpl.java | 29 ------------------- .../repo/impl/version/NodeVersionFactory.java | 4 +-- .../repo/impl/version/VersionIndexPath.java | 6 ++++ .../repo/impl/version/VersionServiceImpl.java | 5 +--- .../version/search/NodeVersionDiffQuery.java | 16 ++++++++++ .../mapping/default/version-mapping.json | 5 ++++ 20 files changed, 62 insertions(+), 74 deletions(-) diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java index 533a0ea8077..4d3862078c2 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java @@ -28,7 +28,7 @@ public class ContentAttributesHelper public static final String IMPORT_KEY = "content.import"; - public static final String UPDATE_KEY = "content.publish"; + public static final String UPDATE_KEY = "content.update"; public static final String PERMISSIONS_KEY = "content.permissions"; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java index 6800cf2d363..b7219ed6399 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/ReturnValues.java @@ -41,14 +41,9 @@ public Optional getOptional( final IndexPath key ) return returnValue == null ? Optional.empty() : Optional.of( returnValue.getSingleValue() ); } - public ReturnValue get( final String key ) + public ReturnValue get( final IndexPath key ) { - return this.returnValues.get( key ); - } - - public Map getReturnValues() - { - return returnValues; + return this.returnValues.get( key.getPath() ); } public static final class Builder @@ -90,5 +85,4 @@ public ReturnValues build() return new ReturnValues( this ); } } - } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchIndexPath.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchIndexPath.java index 50dd3e0f284..c321f5f4f63 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchIndexPath.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchIndexPath.java @@ -22,5 +22,8 @@ public class BranchIndexPath public static final IndexPath PATH = IndexPath.from( "path" ); - public static final IndexPath REFERENCES = IndexPath.from( "references" ); + public static IndexPath[] entryFields() + { + return new IndexPath[]{PATH, VERSION_ID, NODE_BLOB_KEY, INDEX_CONFIG_BLOB_KEY, ACCESS_CONTROL_BLOB_KEY, TIMESTAMP, NODE_ID}; + } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchServiceImpl.java index e5eb61dad38..f030e728d36 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/BranchServiceImpl.java @@ -44,10 +44,7 @@ public class BranchServiceImpl implements BranchService { - private static final ReturnFields BRANCH_RETURN_FIELDS = - ReturnFields.from( BranchIndexPath.NODE_ID, BranchIndexPath.VERSION_ID, BranchIndexPath.NODE_BLOB_KEY, - BranchIndexPath.INDEX_CONFIG_BLOB_KEY, BranchIndexPath.ACCESS_CONTROL_BLOB_KEY, BranchIndexPath.STATE, - BranchIndexPath.PATH, BranchIndexPath.TIMESTAMP, BranchIndexPath.REFERENCES ); + private static final ReturnFields BRANCH_RETURN_FIELDS = ReturnFields.from( BranchIndexPath.entryFields() ); private final Cache cache = CacheBuilder.newBuilder().maximumSize( 100000 ).expireAfterWrite( Duration.ofMinutes( 10 ) ).build(); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java index 573c3c39ffb..20e00d68c84 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/branch/storage/NodeBranchVersionFactory.java @@ -8,6 +8,7 @@ import com.enonic.xp.node.NodeVersionId; import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.repo.impl.NodeBranchEntry; +import com.enonic.xp.repo.impl.ReturnFields; import com.enonic.xp.repo.impl.ReturnValues; public class NodeBranchVersionFactory diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/CommitServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/CommitServiceImpl.java index 3c4975a7acb..5a3b64f4f4e 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/CommitServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/CommitServiceImpl.java @@ -23,8 +23,7 @@ public class CommitServiceImpl implements CommitService { - private static final ReturnFields COMMIT_RETURN_FIELDS = - ReturnFields.from( CommitIndexPath.COMMIT_ID, CommitIndexPath.MESSAGE, CommitIndexPath.TIMESTAMP, CommitIndexPath.COMMITTER ); + private static final ReturnFields COMMIT_RETURN_FIELDS = ReturnFields.from( CommitIndexPath.entryFields() ); private final StorageDao storageDao; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/CommitIndexPath.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/CommitIndexPath.java index f6f98e00007..e1a337ac5fa 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/CommitIndexPath.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/commit/storage/CommitIndexPath.java @@ -11,4 +11,9 @@ public class CommitIndexPath public static final IndexPath TIMESTAMP = IndexPath.from( "timestamp" ); public static final IndexPath COMMITTER = IndexPath.from( "committer" ); + + public static IndexPath[] entryFields() + { + return new IndexPath[]{COMMIT_ID, MESSAGE, TIMESTAMP, COMMITTER}; + } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/SearchRequestBuilderFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/SearchRequestBuilderFactory.java index e1400389f1e..6735be2bb8f 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/SearchRequestBuilderFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/SearchRequestBuilderFactory.java @@ -78,7 +78,7 @@ private SearchRequestBuilder initRequestBuilder() .setFrom( query.getFrom() ) .setPreference( Objects.requireNonNullElse( query.getSearchPreference(), SearchPreference.LOCAL ).getName() ); - if ( query.getReturnFields() != null && query.getReturnFields().isNotEmpty() ) + if ( query.getReturnFields().isNotEmpty() ) { searchRequestBuilder.addFields( query.getReturnFields().getReturnFieldNames() ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/ElasticsearchQuery.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/ElasticsearchQuery.java index 16ba1df6a3f..05ce9699830 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/ElasticsearchQuery.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/ElasticsearchQuery.java @@ -66,7 +66,7 @@ private ElasticsearchQuery( final Builder builder ) this.aggregations = ImmutableList.copyOf( builder.aggregations ); this.suggestions = ImmutableList.copyOf( builder.suggestions ); this.highlight = builder.highlight; - this.returnFields = builder.returnFields; + this.returnFields = Objects.requireNonNullElse( builder.returnFields, ReturnFields.empty() ); this.searchOptimizer = builder.searchOptimizer; this.explain = builder.explain; this.searchPreference = builder.searchPreference; @@ -191,7 +191,7 @@ public static class Builder private ElasticHighlightQuery highlight = ElasticHighlightQuery.empty(); - private ReturnFields returnFields = ReturnFields.empty(); + private ReturnFields returnFields; private SearchOptimizer searchOptimizer = SearchOptimizer.DEFAULT; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/translator/factory/DiffQueryFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/translator/factory/DiffQueryFactory.java index d3b95ac82f5..234bd640632 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/translator/factory/DiffQueryFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/elasticsearch/query/translator/factory/DiffQueryFactory.java @@ -118,7 +118,7 @@ private HasChildQueryBuilder isInBranch( final Branch source ) private TermQueryBuilder createWsConstraint( final Branch branch ) { - return new TermQueryBuilder( BranchIndexPath.BRANCH_NAME.toString(), branch ); + return new TermQueryBuilder( BranchIndexPath.BRANCH_NAME.getPath(), branch ); } public static final class Builder diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java index c430ee5443b..92da73ecee8 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesDependenciesCommand.java @@ -102,7 +102,7 @@ private NodeIds getNodeIdsFromReferenceReturnValues( final SearchResult result ) final NodeIds.Builder builder = NodeIds.create(); for ( SearchHit hit : result.getHits() ) { - final ReturnValue returnValue = hit.getReturnValues().get( NodeIndexPath.REFERENCE.getPath() ); + final ReturnValue returnValue = hit.getReturnValues().get( NodeIndexPath.REFERENCE ); if ( returnValue == null || returnValue.getValues().isEmpty() ) { diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java index e55d51b8dbd..835bfd7a30a 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/FindNodesWithVersionDifferenceCommand.java @@ -7,9 +7,11 @@ import com.enonic.xp.node.NodePaths; import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.NodeBranchEntry; +import com.enonic.xp.repo.impl.ReturnFields; import com.enonic.xp.repo.impl.search.NodeSearchService; import com.enonic.xp.repo.impl.search.result.SearchResult; import com.enonic.xp.repo.impl.storage.NodeStorageService; +import com.enonic.xp.repo.impl.version.VersionIndexPath; import com.enonic.xp.repo.impl.version.search.NodeVersionDiffQuery; public class FindNodesWithVersionDifferenceCommand @@ -59,6 +61,7 @@ public NodeVersionDiffResult execute() .target( target ) .nodePath( nodePath ) .excludes( excludeEntries ) + .returnFields( ReturnFields.from( VersionIndexPath.NODE_ID ) ) .size( NodeSearchService.GET_ALL_SIZE_FLAG ) .batchSize( BATCH_SIZE ) .build(), context.getRepositoryId() ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java index 8f909c792d9..dc275ca7e5c 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/search/NodeSearchServiceImpl.java @@ -24,18 +24,11 @@ public class NodeSearchServiceImpl implements NodeSearchService { - private static final ReturnFields VERSION_RETURN_FIELDS = - ReturnFields.from( VersionIndexPath.VERSION_ID, VersionIndexPath.NODE_BLOB_KEY, VersionIndexPath.INDEX_CONFIG_BLOB_KEY, - VersionIndexPath.ACCESS_CONTROL_BLOB_KEY, VersionIndexPath.BINARY_BLOB_KEYS, VersionIndexPath.TIMESTAMP, - VersionIndexPath.NODE_PATH, VersionIndexPath.NODE_ID, VersionIndexPath.COMMIT_ID, VersionIndexPath.ATTRIBUTES ); + private static final ReturnFields VERSION_RETURN_FIELDS = ReturnFields.from( VersionIndexPath.entryFields() ); - private static final ReturnFields BRANCH_RETURN_FIELDS = - ReturnFields.from( BranchIndexPath.NODE_ID, BranchIndexPath.VERSION_ID, BranchIndexPath.NODE_BLOB_KEY, - BranchIndexPath.INDEX_CONFIG_BLOB_KEY, BranchIndexPath.ACCESS_CONTROL_BLOB_KEY, BranchIndexPath.STATE, - BranchIndexPath.PATH, BranchIndexPath.TIMESTAMP ); + private static final ReturnFields BRANCH_RETURN_FIELDS = ReturnFields.from( BranchIndexPath.entryFields() ); - private static final ReturnFields COMMIT_RETURN_FIELDS = - ReturnFields.from( CommitIndexPath.COMMIT_ID, CommitIndexPath.MESSAGE, CommitIndexPath.COMMITTER, CommitIndexPath.TIMESTAMP ); + private static final ReturnFields COMMIT_RETURN_FIELDS = ReturnFields.from( CommitIndexPath.entryFields() ); private SearchDao searchDao; @@ -59,10 +52,11 @@ public SearchResult query( final NodeQuery query, ReturnFields returnFields, fin private SearchResult doQuery( final NodeQuery query, final ReturnFields returnFields, final SearchSource source ) { - final SearchRequest searchRequest = SearchRequest.create(). - searchSource( source ). - query( query ).returnFields( query.isWithPath() ? returnFields.add( NodeIndexPath.PATH ) : returnFields ). - build(); + final SearchRequest searchRequest = SearchRequest.create() + .searchSource( source ) + .query( query ) + .returnFields( query.isWithPath() ? returnFields.add( NodeIndexPath.PATH ) : returnFields ) + .build(); return searchDao.search( searchRequest ); } @@ -108,7 +102,7 @@ public SearchResult query( final NodeVersionDiffQuery query, final RepositoryId { final SearchRequest searchRequest = SearchRequest.create() .searchSource( SingleRepoStorageSource.create( repositoryId, StaticStorageType.VERSION ) ) - .returnFields( VERSION_RETURN_FIELDS ) + .returnFields( query.getReturnFields() ) .query( query ) .build(); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataService.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataService.java index 2127bbfbcf7..23f9c2dd42b 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataService.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataService.java @@ -4,7 +4,6 @@ import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeIds; import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.ReturnFields; import com.enonic.xp.repo.impl.ReturnValues; @@ -13,8 +12,6 @@ public interface IndexDataService { ReturnValues get( NodeId nodeId, ReturnFields returnFields, InternalContext context ); - ReturnValues get( NodeIds nodeIds, ReturnFields returnFields, InternalContext context ); - void delete( Collection nodeIds, InternalContext context ); void store( Node node, InternalContext context ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataServiceImpl.java index 7984cc9a762..854244a7784 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/IndexDataServiceImpl.java @@ -1,7 +1,6 @@ package com.enonic.xp.repo.impl.storage; import java.util.Collection; -import java.util.List; import java.util.stream.Collectors; import org.osgi.service.component.annotations.Activate; @@ -10,7 +9,6 @@ import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeIds; import com.enonic.xp.repo.impl.InternalContext; import com.enonic.xp.repo.impl.ReturnFields; import com.enonic.xp.repo.impl.ReturnValues; @@ -53,33 +51,6 @@ private GetByIdRequest createGetByIdRequest( final NodeId nodeId, final ReturnFi .build(); } - @Override - public ReturnValues get( final NodeIds nodeIds, final ReturnFields returnFields, final InternalContext context ) - { - final GetByIdsRequest getByIdsRequest = new GetByIdsRequest( context.getSearchPreference() ); - - for ( final NodeId nodeId : nodeIds ) - { - getByIdsRequest.add( createGetByIdRequest( nodeId, returnFields, context ) ); - } - - final List result = storageDao.getByIds( getByIdsRequest ); - - final ReturnValues.Builder allResultValues = ReturnValues.create(); - - for ( GetResult getResult : result ) - { - final ReturnValues returnValues = getResult.getReturnValues(); - - for ( final String key : returnValues.getReturnValues().keySet() ) - { - allResultValues.add( key, returnValues.get( key ).getValues() ); - } - } - - return allResultValues.build(); - } - @Override public void delete( final Collection nodeIds, final InternalContext context ) { diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java index af350a56e3f..7b4012a2a38 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/NodeVersionFactory.java @@ -27,8 +27,8 @@ public static NodeVersionMetadata create( final ReturnValues values ) final String path = values.getStringValue( VersionIndexPath.NODE_PATH ); final NodeCommitId commitId = values.getOptional( VersionIndexPath.COMMIT_ID ).map( Object::toString ).map( NodeCommitId::from ).orElse( null ); - final ReturnValue attributes = values.get( VersionIndexPath.ATTRIBUTES.getPath() ); - final BlobKeys binaryBlobKeys = toBlobKeys( values.get( VersionIndexPath.BINARY_BLOB_KEYS.getPath() ) ); + final ReturnValue attributes = values.get( VersionIndexPath.ATTRIBUTES ); + final BlobKeys binaryBlobKeys = toBlobKeys( values.get( VersionIndexPath.BINARY_BLOB_KEYS ) ); return NodeVersionMetadata.create() .nodeId( NodeId.from( id ) ) diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java index fe22061c6dc..bc852e83cf3 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionIndexPath.java @@ -23,4 +23,10 @@ public class VersionIndexPath public static final IndexPath COMMIT_ID = IndexPath.from( "commitid" ); public static final IndexPath ATTRIBUTES = IndexPath.from( "attributes" ); + + public static IndexPath[] entryFields() + { + return new IndexPath[]{VERSION_ID, NODE_BLOB_KEY, INDEX_CONFIG_BLOB_KEY, ACCESS_CONTROL_BLOB_KEY, BINARY_BLOB_KEYS, NODE_ID, + TIMESTAMP, NODE_PATH, COMMIT_ID, ATTRIBUTES}; + } } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java index 7d485faeaf4..884bcb6be15 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/VersionServiceImpl.java @@ -25,10 +25,7 @@ public class VersionServiceImpl implements VersionService { - private static final ReturnFields VERSION_RETURN_FIELDS = - ReturnFields.from( VersionIndexPath.VERSION_ID, VersionIndexPath.NODE_BLOB_KEY, VersionIndexPath.INDEX_CONFIG_BLOB_KEY, - VersionIndexPath.ACCESS_CONTROL_BLOB_KEY, VersionIndexPath.BINARY_BLOB_KEYS, VersionIndexPath.TIMESTAMP, - VersionIndexPath.NODE_PATH, VersionIndexPath.NODE_ID, VersionIndexPath.COMMIT_ID ); + private static final ReturnFields VERSION_RETURN_FIELDS = ReturnFields.from( VersionIndexPath.entryFields() ); private final StorageDao storageDao; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java index 6b9ad7af2f6..a3ddf45e307 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/version/search/NodeVersionDiffQuery.java @@ -4,6 +4,7 @@ import com.enonic.xp.node.AbstractQuery; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodePaths; +import com.enonic.xp.repo.impl.ReturnFields; public class NodeVersionDiffQuery extends AbstractQuery @@ -16,6 +17,8 @@ public class NodeVersionDiffQuery private final NodePaths excludes; + private final ReturnFields returnFields; + private NodeVersionDiffQuery( Builder builder ) { super( builder ); @@ -23,6 +26,7 @@ private NodeVersionDiffQuery( Builder builder ) this.target = builder.target; this.nodePath = builder.nodePath; this.excludes = builder.excludes.build(); + this.returnFields = builder.returnFields; } public Branch getSource() @@ -45,6 +49,11 @@ public NodePaths getExcludes() return excludes; } + public ReturnFields getReturnFields() + { + return returnFields; + } + public static Builder create() { return new Builder(); @@ -61,6 +70,7 @@ public static class Builder private final NodePaths.Builder excludes = NodePaths.create(); + private ReturnFields returnFields; private Builder() { @@ -91,6 +101,12 @@ public Builder excludes( final NodePaths excludes ) return this; } + public Builder returnFields( final ReturnFields returnFields ) + { + this.returnFields = returnFields; + return this; + } + public NodeVersionDiffQuery build() { return new NodeVersionDiffQuery( this ); diff --git a/modules/core/core-repo/src/main/resources/com/enonic/xp/repo/impl/repository/index/mapping/default/version-mapping.json b/modules/core/core-repo/src/main/resources/com/enonic/xp/repo/impl/repository/index/mapping/default/version-mapping.json index 134602ed9f7..f1e004f7ec2 100644 --- a/modules/core/core-repo/src/main/resources/com/enonic/xp/repo/impl/repository/index/mapping/default/version-mapping.json +++ b/modules/core/core-repo/src/main/resources/com/enonic/xp/repo/impl/repository/index/mapping/default/version-mapping.json @@ -54,6 +54,11 @@ "type": "string", "store": false, "index": "not_analyzed" + }, + "attributes": { + "type": "string", + "store": false, + "index": "no" } } } From aa734a57ac4ecce87624648aeb7db77d303063a6 Mon Sep 17 00:00:00 2001 From: rymsha Date: Thu, 30 Oct 2025 16:16:33 +0100 Subject: [PATCH 4/8] wip --- .../com/enonic/xp/content/ContentVersion.java | 220 +++--------------- .../enonic/xp/content/ContentVersionTest.java | 11 +- .../xp/content/ContentVersionsTest.java | 12 +- .../FindContentVersionsResultTest.java | 8 +- .../impl/content/ContentAttributesHelper.java | 10 +- .../content/FindContentVersionsCommand.java | 49 +--- .../ContentServiceImplTest_versions.java | 6 +- 7 files changed, 55 insertions(+), 261 deletions(-) diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java index 2d5181c4c91..5021f0c3082 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java @@ -2,77 +2,45 @@ import java.time.Instant; import java.util.List; -import java.util.Objects; + +import com.google.common.collect.ImmutableList; import com.enonic.xp.annotation.PublicApi; import com.enonic.xp.security.PrincipalKey; -import com.enonic.xp.node.Attributes; @PublicApi public final class ContentVersion { - private final ContentVersionId id; + private final ContentVersionId versionId; + + private final ContentId contentId; private final ContentPath path; private final Instant timestamp; - private final String change; - - private final List changeFields; - - private final Instant changedTime; - - private final PrincipalKey changedBy; - - private final Instant publishedTime; - - private final PrincipalKey publishedBy; - - private final Instant publishedFrom; - - private final Instant publishedTo; - - private final Instant unpublishedTime; - - private final PrincipalKey unpublishedBy; - private final String comment; - private final Attributes attributes; + private final List changes; private ContentVersion( Builder builder ) { - this.id = builder.id; + this.versionId = builder.versionId; + this.contentId = builder.contentId; this.path = builder.path; this.timestamp = builder.timestamp; - this.change = builder.change; - this.changeFields = builder.changeFields == null ? List.of() : List.copyOf( builder.changeFields ); - this.changedBy = builder.modifiedBy; - this.changedTime = builder.modifiedTime; this.comment = builder.comment; - this.publishedTime = builder.published; - this.publishedBy = builder.publishedBy; - this.publishedFrom = builder.publishedFrom; - this.publishedTo = builder.publishedTo; - this.unpublishedTime = builder.unpublished; - this.unpublishedBy = builder.unpublishedBy; - this.attributes = builder.attributes; + this.changes = builder.changes.build(); } - public PrincipalKey getChangedBy() + public ContentVersionId getVersionId() { - return changedBy; + return versionId; } - public Instant getChangedTime() + public ContentId getContentId() { - return changedTime; - } - - public String getComment() - { - return comment; + return contentId; } public Instant getTimestamp() @@ -80,9 +48,9 @@ public Instant getTimestamp() return timestamp; } - public ContentVersionId getId() + public String getComment() { - return id; + return comment; } public ContentPath getPath() @@ -90,70 +58,9 @@ public ContentPath getPath() return path; } - public String getChange() - { - return change; - } - - public List getChangeFields() - { - return changeFields; - } - - public Instant getPublishedTime() - { - return publishedTime; - } - - public PrincipalKey getPublishedBy() - { - return publishedBy; - } - - public Instant getPublishedFrom() - { - return publishedFrom; - } - - public Instant getPublishedTo() - { - return publishedTo; - } - - public Instant getUnpublishedTime() - { - return unpublishedTime; - } - - public PrincipalKey getUnpublishedBy() - { - return unpublishedBy; - } - - @Deprecated - public Attributes getAttributes() - { - return attributes; - } - - @Override - public boolean equals( final Object o ) + public List getChanges() { - return o instanceof final ContentVersion that && Objects.equals( id, that.id ) && Objects.equals( path, that.path ) && - Objects.equals( timestamp, that.timestamp ) && Objects.equals( change, that.change ) && - Objects.equals( changeFields, that.changeFields ) && Objects.equals( changedTime, that.changedTime ) && - Objects.equals( changedBy, that.changedBy ) && Objects.equals( publishedTime, that.publishedTime ) && - Objects.equals( publishedBy, that.publishedBy ) && Objects.equals( publishedFrom, that.publishedFrom ) && - Objects.equals( publishedTo, that.publishedTo ) && Objects.equals( unpublishedTime, that.unpublishedTime ) && - Objects.equals( unpublishedBy, that.unpublishedBy ) && Objects.equals( comment, that.comment ) && - Objects.equals( attributes, that.attributes ); - } - - @Override - public int hashCode() - { - return Objects.hash( id, path, timestamp, change, changeFields, changedTime, changedBy, publishedTime, publishedBy, publishedFrom, - publishedTo, unpublishedTime, unpublishedBy, comment, attributes ); + return changes; } public static Builder create() @@ -163,49 +70,31 @@ public static Builder create() public static final class Builder { - private PrincipalKey modifiedBy; - private ContentPath path; - private String change; - - private List changeFields; - - private Instant modifiedTime; - private Instant timestamp; private String comment; - private ContentVersionId id; - - private Instant published; + private ContentVersionId versionId; - private PrincipalKey publishedBy; + private ContentId contentId; - private Instant publishedFrom; - - private Instant publishedTo; - - private Instant unpublished; - - private PrincipalKey unpublishedBy; - - private Attributes attributes; + private final ImmutableList.Builder changes = ImmutableList.builder(); private Builder() { } - public Builder id( final ContentVersionId id ) + public Builder versionId( final ContentVersionId id ) { - this.id = id; + this.versionId = id; return this; } - public Builder changedBy( final PrincipalKey modifier ) + public Builder contentId( final ContentId contentId ) { - this.modifiedBy = modifier; + this.contentId = contentId; return this; } @@ -215,12 +104,6 @@ public Builder path( final ContentPath path ) return this; } - public Builder modified( final Instant modified ) - { - this.modifiedTime = modified; - return this; - } - public Builder timestamp( final Instant timestamp ) { this.timestamp = timestamp; @@ -233,56 +116,9 @@ public Builder comment( final String comment ) return this; } - public Builder publishedFrom( final Instant publishedFrom ) - { - this.publishedFrom = publishedFrom; - return this; - } - - public Builder publishedTo( final Instant publishedTo ) + public Builder addChange( Change change ) { - this.publishedTo = publishedTo; - return this; - } - - public Builder published( final Instant published ) - { - this.published = published; - return this; - } - - public Builder publishedBy( final PrincipalKey publishedBy ) - { - this.publishedBy = publishedBy; - return this; - } - - public Builder unpublished( final Instant unpublished ) - { - this.unpublished = unpublished; - return this; - } - - public Builder unpublishedBy( final PrincipalKey unpublishedBy ) - { - this.unpublishedBy = unpublishedBy; - return this; - } - - public Builder change( final String change) { - this.change = change; - return this; - } - - public Builder changeFields( final List changeFields) { - this.changeFields = changeFields; - return this; - } - - @Deprecated - public Builder attributes( final Attributes attributes ) - { - this.attributes = attributes; + changes.add( change ); return this; } @@ -291,4 +127,8 @@ public ContentVersion build() return new ContentVersion( this ); } } + + public record Change(String operation, List fields, PrincipalKey user, Instant opTime) + { + } } diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java index 0ac1c82b5e8..e9c3c71d458 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionTest.java @@ -6,8 +6,6 @@ import nl.jqno.equalsverifier.EqualsVerifier; -import com.enonic.xp.security.PrincipalKey; - import static org.junit.jupiter.api.Assertions.assertEquals; class ContentVersionTest @@ -15,23 +13,18 @@ class ContentVersionTest @Test void testBuilder() { - final Instant now1 = Instant.now(); final Instant now2 = Instant.now(); final ContentVersion version = ContentVersion.create() - .id( ContentVersionId.from( "a" ) ) + .versionId( ContentVersionId.from( "a" ) ) .path( ContentPath.from( ContentPath.ROOT, "a" ) ) - .modified( now1 ) .timestamp( now2 ) - .changedBy( PrincipalKey.ofAnonymous() ) .comment( "comment" ) .build(); - assertEquals( ContentVersionId.from( "a" ), version.getId() ); - assertEquals( now1, version.getChangedTime() ); + assertEquals( ContentVersionId.from( "a" ), version.getVersionId() ); assertEquals( now2, version.getTimestamp() ); assertEquals( "comment", version.getComment() ); - assertEquals( PrincipalKey.ofAnonymous(), version.getChangedBy() ); assertEquals( "/a", version.getPath().toString() ); } diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java index bb264e80ec0..583e05bf8df 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java @@ -16,19 +16,15 @@ void testBuilder() final Instant now1 = Instant.now(); - final ContentVersion version1 = ContentVersion.create(). - id( ContentVersionId.from( "a" ) ). - modified( now1 ). - timestamp( now1 ).changedBy( PrincipalKey.ofAnonymous() ). + final ContentVersion version1 = ContentVersion.create().versionId( ContentVersionId.from( "a" ) ). + timestamp( now1 ). comment( "comment" ). build(); final Instant now2 = now1.plusMillis( 1000 ); - final ContentVersion version2 = ContentVersion.create(). - id( ContentVersionId.from( "b" ) ). - modified( now2 ). - timestamp( now2 ).changedBy( PrincipalKey.ofAnonymous() ). + final ContentVersion version2 = ContentVersion.create().versionId( ContentVersionId.from( "b" ) ). + timestamp( now2 ). comment( "comment" ). build(); diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java index b2317c626d8..02219fc9e27 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java @@ -1,7 +1,5 @@ package com.enonic.xp.content; -import java.time.Instant; - import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -11,11 +9,7 @@ class FindContentVersionsResultTest @Test void sameVersion() { - final Instant now = Instant.now(); - - final ContentVersion version = ContentVersion.create(). - id( ContentVersionId.from( "a" ) ). - modified( now ). + final ContentVersion version = ContentVersion.create().versionId( ContentVersionId.from( "a" ) ). build(); final ContentVersions contentVersions = ContentVersions.create(). diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java index 4d3862078c2..001f78c6daf 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/ContentAttributesHelper.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.function.Function; import com.enonic.xp.content.Content; @@ -46,10 +45,6 @@ public class ContentAttributesHelper public static final String UNPUBLISH_KEY = "content.unpublish"; - public static final Set CHANGE_KEYS = - Set.of( CREATE_KEY, DUPLICATE_KEY, IMPORT_KEY, UPDATE_KEY, PERMISSIONS_KEY, MOVE_KEY, SORT_KEY, PATCH_KEY, ARCHIVE_KEY, - RESTORE_KEY ); - private static final Clock MILLIS_CLOCK = Clock.tick( Clock.systemUTC(), Duration.ofMillis( 1 ) ); private static final Map> FIELD_GETTERS = @@ -93,6 +88,11 @@ public static Instant getOpTime( final GenericValue attribute ) return Instant.parse( attribute.property( ContentAttributesHelper.OPTIME_PROPERTY ).asString() ); } + public static String getKey( final GenericValue attribute ) + { + return attribute.property( Attributes.KEY_PROPERTY ).asString(); + } + public static PrincipalKey getUser( final GenericValue attribute ) { return PrincipalKey.from( attribute.property( ContentAttributesHelper.USER_PROPERTY ).asString() ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java index bb67e55c64e..1a2c640b46a 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java @@ -4,19 +4,14 @@ import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentId; -import com.enonic.xp.content.ContentPropertyNames; -import com.enonic.xp.content.ContentPublishInfo; import com.enonic.xp.content.ContentVersion; import com.enonic.xp.content.ContentVersionId; import com.enonic.xp.content.ContentVersions; import com.enonic.xp.content.FindContentVersionsResult; -import com.enonic.xp.core.impl.content.serializer.PublishInfoSerializer; -import com.enonic.xp.data.PropertyTree; import com.enonic.xp.node.Attributes; import com.enonic.xp.node.GetNodeVersionsParams; import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeId; -import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.NodeVersionQueryResult; import com.enonic.xp.util.GenericValue; @@ -47,7 +42,6 @@ public static Builder create() public FindContentVersionsResult execute() { - final NodeVersionQueryResult nodeVersionQueryResult = nodeService.findVersions( GetNodeVersionsParams.create().nodeId( NodeId.from( this.contentId ) ).from( this.from ).size( this.size ).build() ); @@ -69,46 +63,20 @@ public ContentVersion createVersion( final NodeVersionMetadata nodeVersionMetada final Attributes attributes = nodeVersionMetadata.getAttributes(); final ContentVersion.Builder builder = ContentVersion.create() - .id( ContentVersionId.from( nodeVersionMetadata.getNodeVersionId().toString() ) ) + .contentId( ContentId.from( nodeVersionMetadata.getNodeId() ) ) + .versionId( ContentVersionId.from( nodeVersionMetadata.getNodeVersionId().toString() ) ) .path( ContentNodeHelper.translateNodePathToContentPath( nodeVersionMetadata.getNodePath() ) ) - .timestamp( nodeVersionMetadata.getTimestamp() ) - .attributes( attributes ); + .timestamp( nodeVersionMetadata.getTimestamp() ); if ( attributes != null ) { - final GenericValue publishAttr = attributes.get( ContentAttributesHelper.PUBLISH_KEY ); - final GenericValue unpublishAttr = attributes.get( ContentAttributesHelper.UNPUBLISH_KEY ); - if ( publishAttr != null || unpublishAttr != null ) - { - final NodeVersion nodeVersion = nodeService.getByNodeVersionKey( nodeVersionMetadata.getNodeVersionKey() ); - final PropertyTree data = nodeVersion.getData(); - - final ContentPublishInfo publishInfo = PublishInfoSerializer.serialize( data.getSet( ContentPropertyNames.PUBLISH_INFO ) ); - if ( publishAttr != null ) - { - builder.published( ContentAttributesHelper.getOpTime( publishAttr ) ); - builder.publishedBy( ContentAttributesHelper.getUser( publishAttr ) ); - } - - builder.publishedFrom( publishInfo.getFrom() ); - builder.publishedTo( publishInfo.getTo() ); - - if ( unpublishAttr != null ) - { - builder.unpublished( ContentAttributesHelper.getOpTime( unpublishAttr ) ); - builder.unpublishedBy( ContentAttributesHelper.getUser( unpublishAttr ) ); - } - } - attributes.list() .stream() - .filter( v -> ContentAttributesHelper.CHANGE_KEYS.contains( v.property( Attributes.KEY_PROPERTY ).asString() ) ) - .reduce( ( first, second ) -> second ) - .ifPresent( changeAttr -> { - builder.changedBy( ContentAttributesHelper.getUser( changeAttr ) ); - builder.changeFields( changeAttr.optional( "fields" ).map( GenericValue::asStringList ).orElse( List.of() ) ); - builder.change( changeAttr.property( Attributes.KEY_PROPERTY ).asString() ); - } ); + .filter( v -> ContentAttributesHelper.getKey( v ).startsWith( "content." ) ) + .map( v -> new ContentVersion.Change( ContentAttributesHelper.getKey( v ), + v.optional( "fields" ).map( GenericValue::asStringList ).orElse( List.of() ), + ContentAttributesHelper.getUser( v ), ContentAttributesHelper.getOpTime( v ) ) ) + .forEach( builder::addChange ); } if ( nodeVersionMetadata.getNodeCommitId() != null ) @@ -144,7 +112,6 @@ else if ( message.startsWith( ContentConstants.ARCHIVE_COMMIT_PREFIX + ContentCo public static final class Builder extends AbstractContentCommand.Builder - { private ContentId contentId; diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java index 978b6c231ef..ee6bfca5dad 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java @@ -1,5 +1,8 @@ package com.enonic.xp.core.content; +import java.util.List; +import java.util.function.Function; + import org.junit.jupiter.api.Test; import com.enonic.xp.archive.ArchiveContentParams; @@ -72,7 +75,8 @@ void get_archived_versions() assertEquals( 3, result.getTotalHits() ); assertThat( result.getContentVersions() ).elements( 0, 1 ) - .extracting( ContentVersion::getChange ) + .extracting( ContentVersion::getChanges ) + .map( cs -> cs.stream().map( ContentVersion.Change::operation ).findFirst().orElseThrow() ) .containsExactly( "content.restore", "content.archive" ); } } From e12a470a79c8d60dd5e2a0c6bafeaf0c75f403a3 Mon Sep 17 00:00:00 2001 From: rymsha Date: Thu, 30 Oct 2025 16:23:58 +0100 Subject: [PATCH 5/8] wip --- .../com/enonic/xp/content/ContentVersion.java | 16 ++++++++++++++++ .../core/content/AbstractContentServiceTest.java | 4 ++-- .../content/ContentServiceImplTest_publish.java | 1 - 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java index 5021f0c3082..00b1ebd4cc5 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersion.java @@ -2,6 +2,7 @@ import java.time.Instant; import java.util.List; +import java.util.Objects; import com.google.common.collect.ImmutableList; @@ -63,6 +64,21 @@ public List getChanges() return changes; } + @Override + public boolean equals( final Object o ) + { + return o instanceof final ContentVersion that && Objects.equals( versionId, that.versionId ) && + Objects.equals( contentId, that.contentId ) && Objects.equals( path, that.path ) && + Objects.equals( timestamp, that.timestamp ) && Objects.equals( comment, that.comment ) && + Objects.equals( changes, that.changes ); + } + + @Override + public int hashCode() + { + return Objects.hash( versionId, contentId, path, timestamp, comment, changes ); + } + public static Builder create() { return new Builder(); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java index 43e3634db7e..d74d7946c18 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java @@ -643,10 +643,10 @@ protected void assertVersions( final ContentId contentId, final int expected ) if ( lastModified != null ) { - assertFalse( next.getChangedTime().isAfter( lastModified ) ); + assertFalse( next.getTimestamp().isAfter( lastModified ) ); } - lastModified = next.getChangedTime(); + lastModified = next.getTimestamp(); } } diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java index acdd8465a84..370075827ce 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java @@ -423,7 +423,6 @@ void publish_with_message_no_message() assertTrue( iterator.hasNext() ); ContentVersion version = iterator.next(); - assertEquals( "user:system:test-user", version.getPublishedBy().toString() ); assertEquals( "", version.getComment() ); } From 6c764299f89391619a33d6587f8bdf4bfb2e4e83 Mon Sep 17 00:00:00 2001 From: rymsha Date: Fri, 31 Oct 2025 09:47:20 +0100 Subject: [PATCH 6/8] wip --- .../enonic/xp/content/ContentVersions.java | 26 ++++++++++-- .../com/enonic/xp/node/AbstractQuery.java | 19 ++------- .../java/com/enonic/xp/node/Attributes.java | 2 +- .../xp/content/ContentVersionsTest.java | 40 +++++++++++-------- .../FindContentVersionsResultTest.java | 13 ++---- .../content/FindContentVersionsCommand.java | 11 ++--- .../xp/repo/impl/node/NodeServiceImpl.java | 3 +- .../repo/impl/storage/NodeStorageService.java | 9 ++--- .../impl/storage/NodeStorageServiceImpl.java | 2 +- .../ContentServiceImplTest_publish.java | 3 +- 10 files changed, 67 insertions(+), 61 deletions(-) diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java index 41a64332a27..6fc54e89471 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentVersions.java @@ -1,5 +1,8 @@ package com.enonic.xp.content; +import java.util.stream.Collector; +import java.util.stream.Collectors; + import com.google.common.collect.ImmutableList; import com.enonic.xp.annotation.PublicApi; @@ -9,6 +12,8 @@ public final class ContentVersions extends AbstractImmutableEntityList { + private static final ContentVersions EMPTY = new ContentVersions( ImmutableList.of() ); + private ContentVersions( final ImmutableList list ) { super( list ); @@ -19,9 +24,24 @@ public static Builder create() return new Builder(); } + public static Collector collector() + { + return Collectors.collectingAndThen( ImmutableList.toImmutableList(), ContentVersions::fromInternal ); + } + + public static ContentVersions from( final ContentVersion... items ) + { + return fromInternal( ImmutableList.copyOf( items ) ); + } + + private static ContentVersions fromInternal( final ImmutableList list ) + { + return list.isEmpty() ? EMPTY : new ContentVersions( list ); + } + public static final class Builder { - private final ImmutableList.Builder contentVersions = ImmutableList.builder(); + private final ImmutableList.Builder builder = ImmutableList.builder(); private Builder() { @@ -29,13 +49,13 @@ private Builder() public Builder add( final ContentVersion contentVersion ) { - this.contentVersions.add( contentVersion ); + this.builder.add( contentVersion ); return this; } public ContentVersions build() { - return new ContentVersions( this.contentVersions.build() ); + return fromInternal( builder.build() ); } } } diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/AbstractQuery.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/AbstractQuery.java index de8aaebe055..ba4eb47e1d2 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/AbstractQuery.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/AbstractQuery.java @@ -55,27 +55,16 @@ protected AbstractQuery( Builder builder ) this.aggregationQueries = builder.aggregationQueries.build(); this.suggestionQueries = builder.suggestionQueries.build(); this.highlight = builder.highlight; - this.orderBys = setOrderExpressions( builder ); + this.orderBys = ImmutableList.builder() + .addAll( builder.query != null ? builder.query.getOrderList() : List.of() ) + .addAll( builder.orderBys ) + .build(); this.postFilters = builder.postFilters.build(); this.queryFilters = builder.queryFilters.build(); this.searchOptimizer = builder.searchOptimizer; this.explain = builder.explain; } - private ImmutableList setOrderExpressions( final Builder builder ) - { - final List orderBys = new ArrayList<>(); - - if ( query != null ) - { - orderBys.addAll( query.getOrderList() ); - } - - orderBys.addAll( builder.orderBys ); - - return ImmutableList.copyOf( orderBys ); - } - @Override public List getOrderBys() { diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java index 140966746fc..57b62a2f62e 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/Attributes.java @@ -52,7 +52,7 @@ public Builder addAll( final Iterable values ) public Attributes build() { - return new Attributes( builder.build() ); + return new Attributes( builder.buildOrThrow() ); } public Attributes buildKeepingLast() diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java index 583e05bf8df..0064b9af276 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/ContentVersionsTest.java @@ -4,35 +4,43 @@ import org.junit.jupiter.api.Test; -import com.enonic.xp.security.PrincipalKey; - -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; class ContentVersionsTest { @Test void testBuilder() { + final Instant now1 = Instant.now(); + + final ContentVersion version1 = + ContentVersion.create().versionId( ContentVersionId.from( "a" ) ).timestamp( now1 ).comment( "comment" ).build(); + + final Instant now2 = now1.plusMillis( 1000 ); + + final ContentVersion version2 = + ContentVersion.create().versionId( ContentVersionId.from( "b" ) ).timestamp( now2 ).comment( "comment" ).build(); + final ContentVersions versions = ContentVersions.create().add( version1 ).add( version2 ).build(); + + assertThat( versions ).extracting( ContentVersion::getVersionId ).map( ContentVersionId::toString ).containsExactly( "a", "b" ); + } + + @Test + void testFrom() + { final Instant now1 = Instant.now(); - final ContentVersion version1 = ContentVersion.create().versionId( ContentVersionId.from( "a" ) ). - timestamp( now1 ). - comment( "comment" ). - build(); + final ContentVersion version1 = + ContentVersion.create().versionId( ContentVersionId.from( "a" ) ).timestamp( now1 ).comment( "comment" ).build(); final Instant now2 = now1.plusMillis( 1000 ); - final ContentVersion version2 = ContentVersion.create().versionId( ContentVersionId.from( "b" ) ). - timestamp( now2 ). - comment( "comment" ). - build(); + final ContentVersion version2 = + ContentVersion.create().versionId( ContentVersionId.from( "b" ) ).timestamp( now2 ).comment( "comment" ).build(); - final ContentVersions versions = ContentVersions.create(). - add( version1 ). - add( version2 ). - build(); + final ContentVersions versions = ContentVersions.from( version1, version2 ); - assertTrue( versions.iterator().hasNext() ); + assertThat( versions ).extracting( ContentVersion::getVersionId ).map( ContentVersionId::toString ).containsExactly( "a", "b" ); } } diff --git a/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java b/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java index 02219fc9e27..653d4bbaf79 100644 --- a/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java +++ b/modules/core/core-api/src/test/java/com/enonic/xp/content/FindContentVersionsResultTest.java @@ -9,16 +9,11 @@ class FindContentVersionsResultTest @Test void sameVersion() { - final ContentVersion version = ContentVersion.create().versionId( ContentVersionId.from( "a" ) ). - build(); + final ContentVersion version = ContentVersion.create().versionId( ContentVersionId.from( "a" ) ).build(); + final ContentVersions contentVersions = ContentVersions.from( version ); - final ContentVersions contentVersions = ContentVersions.create(). - add( version ). - build(); - - final FindContentVersionsResult result = FindContentVersionsResult.create(). - contentVersions( contentVersions ).totalHits( 2 ). - build(); + final FindContentVersionsResult result = + FindContentVersionsResult.create().contentVersions( contentVersions ).totalHits( 2 ).build(); assertEquals( contentVersions, result.getContentVersions() ); assertEquals( 1, result.getContentVersions().getSize() ); diff --git a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java index 1a2c640b46a..43b3ac9fb3a 100644 --- a/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java +++ b/modules/core/core-content/src/main/java/com/enonic/xp/core/impl/content/FindContentVersionsCommand.java @@ -48,14 +48,9 @@ public FindContentVersionsResult execute() final FindContentVersionsResult.Builder findContentVersionsResultBuilder = FindContentVersionsResult.create().totalHits( nodeVersionQueryResult.getTotalHits() ); - final ContentVersions.Builder contentVersionsBuilder = ContentVersions.create(); - - for ( final NodeVersionMetadata nodeVersionMetadata : nodeVersionQueryResult.getNodeVersionMetadatas() ) - { - contentVersionsBuilder.add( createVersion( nodeVersionMetadata ) ); - } - - return findContentVersionsResultBuilder.contentVersions( contentVersionsBuilder.build() ).build(); + return findContentVersionsResultBuilder.contentVersions( + nodeVersionQueryResult.getNodeVersionMetadatas().stream().map( this::createVersion ).collect( ContentVersions.collector() ) ) + .build(); } public ContentVersion createVersion( final NodeVersionMetadata nodeVersionMetadata ) diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java index 5846579ed6f..a3a91408911 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/node/NodeServiceImpl.java @@ -60,7 +60,6 @@ import com.enonic.xp.node.NodeService; import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionId; -import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeVersionIds; import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeVersionQuery; @@ -956,7 +955,7 @@ public void addAttributes( final NodeVersionId nodeVersionId, final Attributes a final InternalContext context = InternalContext.create( ContextAccessor.current() ).searchPreference( SearchPreference.PRIMARY ).build(); - nodeStorageService.setAttribute( nodeVersionId, attributes, context ); + nodeStorageService.addAttributes( nodeVersionId, attributes, context ); refresh( RefreshMode.STORAGE ); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java index da0e9aa3131..82b2d56342a 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageService.java @@ -3,10 +3,8 @@ import java.util.Collection; -import com.enonic.xp.node.Attributes; -import com.enonic.xp.node.NodeVersionIds; -import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.branch.Branch; +import com.enonic.xp.node.Attributes; import com.enonic.xp.node.Node; import com.enonic.xp.node.NodeCommitEntry; import com.enonic.xp.node.NodeCommitId; @@ -16,6 +14,8 @@ import com.enonic.xp.node.NodePaths; import com.enonic.xp.node.NodeVersion; import com.enonic.xp.node.NodeVersionId; +import com.enonic.xp.node.NodeVersionIds; +import com.enonic.xp.node.NodeVersionKey; import com.enonic.xp.node.NodeVersionMetadata; import com.enonic.xp.node.Nodes; import com.enonic.xp.node.PushNodesListener; @@ -23,7 +23,6 @@ import com.enonic.xp.repo.impl.NodeBranchEntries; import com.enonic.xp.repo.impl.NodeBranchEntry; import com.enonic.xp.security.acl.AccessControlList; -import com.enonic.xp.util.GenericValue; public interface NodeStorageService { @@ -41,7 +40,7 @@ public interface NodeStorageService NodeCommitEntry commit( NodeCommitEntry entry, NodeVersionIds versionIds, InternalContext context ); - void setAttribute( NodeVersionId versionId, Attributes attributes, InternalContext context ); + void addAttributes( NodeVersionId versionId, Attributes attributes, InternalContext context ); Node get( NodeId nodeId, InternalContext context ); diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java index f5dae135b68..95043ffabfd 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/storage/NodeStorageServiceImpl.java @@ -192,7 +192,7 @@ public NodeCommitEntry commit( final NodeCommitEntry nodeCommitEntry, final Node } @Override - public void setAttribute( final NodeVersionId versionId, Attributes value, final InternalContext context ) + public void addAttributes( final NodeVersionId versionId, Attributes value, final InternalContext context ) { final NodeVersionMetadata existingVersion = this.versionService.getVersion( versionId, context ); diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java index 370075827ce..e43c1f546fa 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_publish.java @@ -42,6 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.atMostOnce; @@ -423,7 +424,7 @@ void publish_with_message_no_message() assertTrue( iterator.hasNext() ); ContentVersion version = iterator.next(); - assertEquals( "", version.getComment() ); + assertNull( version.getComment() ); } @Test From 6bcc87ed544607f52bbf031c49f5a6711c1f1bfc Mon Sep 17 00:00:00 2001 From: rymsha Date: Fri, 31 Oct 2025 15:00:07 +0100 Subject: [PATCH 7/8] wip --- .../ContentAlreadyExistsException.java | 4 +- .../exception/DuplicateElementException.java | 13 ++ .../xp/issue/IssueAlreadyExistsException.java | 4 +- .../node/NodeAlreadyExistAtPathException.java | 3 +- .../BranchAlreadyExistsException.java} | 10 +- .../RepositoryAlreadyExistsException.java | 19 +++ .../IdProviderAlreadyExistsException.java | 4 +- .../PrincipalAlreadyExistsException.java | 5 +- .../CreateProjectIssuesAccessListCommand.java | 5 - .../CreateProjectRootAccessListCommand.java | 5 - .../ProjectAlreadyExistsException.java | 12 +- .../core/impl/project/ProjectServiceImpl.java | 30 ++-- .../impl/project/init/ContentInitializer.java | 74 ++-------- .../project/init/ContentRepoInitializer.java | 138 ++++++++++++++++++ .../init/RepoDependentInitializer.java | 37 ++--- ...or.java => Xp8DefaultProjectMigrator.java} | 20 +-- .../project/init/ContentInitializerTest.java | 7 - .../enonic/xp/repo/impl/NodeBranchEntry.java | 47 +----- .../storage/NodeBranchVersionFactory.java | 1 - .../RepositoryAlreadyExistException.java | 21 --- .../RepositoryServiceActivator.java | 3 + .../repository/RepositoryServiceImpl.java | 6 +- .../repository/SystemRepoInitializer.java | 13 +- .../impl/repository/Xp8IndexMigrator.java | 33 +++++ .../RepositoryServiceActivatorTest.java | 1 - .../content/AbstractContentServiceTest.java | 5 +- .../ContentServiceImplTest_versions.java | 5 - 27 files changed, 282 insertions(+), 243 deletions(-) create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/exception/DuplicateElementException.java rename modules/core/{core-repo/src/main/java/com/enonic/xp/repo/impl/repository/BranchAlreadyExistException.java => core-api/src/main/java/com/enonic/xp/repository/BranchAlreadyExistsException.java} (61%) create mode 100644 modules/core/core-api/src/main/java/com/enonic/xp/repository/RepositoryAlreadyExistsException.java create mode 100644 modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentRepoInitializer.java rename modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/{DefaultProjectMigrator.java => Xp8DefaultProjectMigrator.java} (89%) delete mode 100644 modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryAlreadyExistException.java create mode 100644 modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/Xp8IndexMigrator.java diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAlreadyExistsException.java b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAlreadyExistsException.java index f0a0a5d70d8..55a0c418023 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAlreadyExistsException.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/content/ContentAlreadyExistsException.java @@ -7,12 +7,12 @@ import com.enonic.xp.annotation.PublicApi; import com.enonic.xp.branch.Branch; -import com.enonic.xp.exception.NotFoundException; +import com.enonic.xp.exception.DuplicateElementException; import com.enonic.xp.repository.RepositoryId; @PublicApi public final class ContentAlreadyExistsException - extends NotFoundException + extends DuplicateElementException { private final ContentPath path; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/exception/DuplicateElementException.java b/modules/core/core-api/src/main/java/com/enonic/xp/exception/DuplicateElementException.java new file mode 100644 index 00000000000..f6f7a0f9191 --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/exception/DuplicateElementException.java @@ -0,0 +1,13 @@ +package com.enonic.xp.exception; + +import com.enonic.xp.annotation.PublicApi; + +@PublicApi +public class DuplicateElementException + extends BaseException +{ + public DuplicateElementException( final String message ) + { + super( message ); + } +} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/issue/IssueAlreadyExistsException.java b/modules/core/core-api/src/main/java/com/enonic/xp/issue/IssueAlreadyExistsException.java index 3ceed6a7337..32bd04ee46c 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/issue/IssueAlreadyExistsException.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/issue/IssueAlreadyExistsException.java @@ -1,7 +1,9 @@ package com.enonic.xp.issue; +import com.enonic.xp.exception.DuplicateElementException; + public final class IssueAlreadyExistsException - extends RuntimeException + extends DuplicateElementException { public IssueAlreadyExistsException( final IssueName issueName ) { diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeAlreadyExistAtPathException.java b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeAlreadyExistAtPathException.java index 99b288eef2f..eb746a4f59b 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeAlreadyExistAtPathException.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/node/NodeAlreadyExistAtPathException.java @@ -8,11 +8,12 @@ import com.enonic.xp.annotation.PublicApi; import com.enonic.xp.branch.Branch; +import com.enonic.xp.exception.DuplicateElementException; import com.enonic.xp.repository.RepositoryId; @PublicApi public class NodeAlreadyExistAtPathException - extends RuntimeException + extends DuplicateElementException { private final NodePath node; diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/BranchAlreadyExistException.java b/modules/core/core-api/src/main/java/com/enonic/xp/repository/BranchAlreadyExistsException.java similarity index 61% rename from modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/BranchAlreadyExistException.java rename to modules/core/core-api/src/main/java/com/enonic/xp/repository/BranchAlreadyExistsException.java index 5e9662a1790..054d384543c 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/BranchAlreadyExistException.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/repository/BranchAlreadyExistsException.java @@ -1,17 +1,17 @@ -package com.enonic.xp.repo.impl.repository; +package com.enonic.xp.repository; import java.text.MessageFormat; import com.enonic.xp.branch.Branch; -import com.enonic.xp.exception.BaseException; +import com.enonic.xp.exception.DuplicateElementException; -class BranchAlreadyExistException - extends BaseException +public final class BranchAlreadyExistsException + extends DuplicateElementException { private final Branch branch; - BranchAlreadyExistException( final Branch branch ) + public BranchAlreadyExistsException( final Branch branch ) { super( MessageFormat.format( "Branch [{0}] already exists", branch ) ); this.branch = branch; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/repository/RepositoryAlreadyExistsException.java b/modules/core/core-api/src/main/java/com/enonic/xp/repository/RepositoryAlreadyExistsException.java new file mode 100644 index 00000000000..3cea1c8a4dd --- /dev/null +++ b/modules/core/core-api/src/main/java/com/enonic/xp/repository/RepositoryAlreadyExistsException.java @@ -0,0 +1,19 @@ +package com.enonic.xp.repository; + + +import com.enonic.xp.exception.DuplicateElementException; + +public final class RepositoryAlreadyExistsException + extends DuplicateElementException +{ + public RepositoryAlreadyExistsException( final RepositoryId repositoryId ) + { + super( "Repository [{" + repositoryId + "}] already exists" ); + } + + @Override + public String getCode() + { + return "branchAlreadyExists"; + } +} diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/security/IdProviderAlreadyExistsException.java b/modules/core/core-api/src/main/java/com/enonic/xp/security/IdProviderAlreadyExistsException.java index 666e122a981..a07dfb952de 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/security/IdProviderAlreadyExistsException.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/security/IdProviderAlreadyExistsException.java @@ -3,11 +3,11 @@ import java.text.MessageFormat; import com.enonic.xp.annotation.PublicApi; -import com.enonic.xp.exception.BaseException; +import com.enonic.xp.exception.DuplicateElementException; @PublicApi public class IdProviderAlreadyExistsException - extends BaseException + extends DuplicateElementException { private final IdProviderKey idProviderKey; diff --git a/modules/core/core-api/src/main/java/com/enonic/xp/security/PrincipalAlreadyExistsException.java b/modules/core/core-api/src/main/java/com/enonic/xp/security/PrincipalAlreadyExistsException.java index 62133d7e19f..e30b8a9abae 100644 --- a/modules/core/core-api/src/main/java/com/enonic/xp/security/PrincipalAlreadyExistsException.java +++ b/modules/core/core-api/src/main/java/com/enonic/xp/security/PrincipalAlreadyExistsException.java @@ -3,13 +3,12 @@ import java.text.MessageFormat; import com.enonic.xp.annotation.PublicApi; -import com.enonic.xp.exception.BaseException; +import com.enonic.xp.exception.DuplicateElementException; @PublicApi public class PrincipalAlreadyExistsException - extends BaseException + extends DuplicateElementException { - private final PrincipalKey principalKey; public PrincipalAlreadyExistsException( final PrincipalKey principalKey ) diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectIssuesAccessListCommand.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectIssuesAccessListCommand.java index f5da871a541..af6a1619366 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectIssuesAccessListCommand.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectIssuesAccessListCommand.java @@ -26,11 +26,6 @@ public AccessControlList execute() private AccessControlList createIssuesRootPermissions() { - if ( projectName == null ) - { - return null; - } - return AccessControlList.create(). add( AccessControlEntry.create(). allowAll(). diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectRootAccessListCommand.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectRootAccessListCommand.java index 688514a8d2f..ac6264b7622 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectRootAccessListCommand.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/CreateProjectRootAccessListCommand.java @@ -31,11 +31,6 @@ public AccessControlList execute() private AccessControlList createContentRootPermissions() { - if ( projectName == null ) - { - return null; - } - return AccessControlList.create( permissions ). add( AccessControlEntry.create(). allowAll(). diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectAlreadyExistsException.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectAlreadyExistsException.java index 9f6598ff90a..3654d8ece86 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectAlreadyExistsException.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectAlreadyExistsException.java @@ -2,22 +2,14 @@ import java.text.MessageFormat; -import com.enonic.xp.exception.BaseException; +import com.enonic.xp.exception.DuplicateElementException; import com.enonic.xp.project.ProjectName; public final class ProjectAlreadyExistsException - extends BaseException + extends DuplicateElementException { - private final ProjectName projectName; - public ProjectAlreadyExistsException( final ProjectName projectName ) { super( MessageFormat.format( "Project with name [{0}] already exists", projectName ) ); - this.projectName = projectName; - } - - public ProjectName getProjectName() - { - return projectName; } } diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java index 0fe54ab4f15..03ca8c9d1e1 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java @@ -37,8 +37,9 @@ import com.enonic.xp.context.ContextBuilder; import com.enonic.xp.core.impl.project.init.ArchiveInitializer; import com.enonic.xp.core.impl.project.init.ContentInitializer; -import com.enonic.xp.core.impl.project.init.DefaultProjectMigrator; +import com.enonic.xp.core.impl.project.init.ContentRepoInitializer; import com.enonic.xp.core.impl.project.init.IssueInitializer; +import com.enonic.xp.core.impl.project.init.Xp8DefaultProjectMigrator; import com.enonic.xp.data.PropertySet; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.event.EventPublisher; @@ -117,16 +118,16 @@ public void initialize() final PropertySet projectData = repository.getData().getSet( ProjectConstants.PROJECT_DATA_SET_NAME ); doInitRootNodes( CreateProjectParams.create() - .name( ProjectName.from( repository.getId() ) ) - .displayName( projectData.getString( ProjectConstants.PROJECT_DISPLAY_NAME_PROPERTY ) ) - .description( projectData.getString( ProjectConstants.PROJECT_DESCRIPTION_PROPERTY ) ) - .build() ); + .name( ProjectName.from( repository.getId() ) ) + .displayName( projectData.getString( ProjectConstants.PROJECT_DISPLAY_NAME_PROPERTY ) ) + .description( projectData.getString( ProjectConstants.PROJECT_DESCRIPTION_PROPERTY ) ) + .build(), null ); } ); if ( repositories.stream() - .anyMatch( repository -> repository.getId().equals( DefaultProjectMigrator.DEFAULT_PROJECT_NAME.getRepoId() ) ) ) + .anyMatch( repository -> repository.getId().equals( Xp8DefaultProjectMigrator.DEFAULT_PROJECT_NAME.getRepoId() ) ) ) { - new DefaultProjectMigrator( nodeService, securityService, indexService ).migrate(); + new Xp8DefaultProjectMigrator( nodeService, securityService, indexService ).migrate(); } } ); } @@ -139,11 +140,6 @@ private static void buildParents( final Project.Builder project, final PropertyS } } - private void doInitRootNodes( final CreateProjectParams params ) - { - this.doInitRootNodes( params, null ); - } - private List getProjectRepositories( final Repositories repositories ) { return repositories.stream().map( repository -> { @@ -189,12 +185,18 @@ private static void buildIcon( final Project.Builder project, final PropertySet private void doInitRootNodes( final CreateProjectParams params, final PropertyTree contentRootData ) { + ContentRepoInitializer.create() + .repositoryService( repositoryService ) + .repositoryId( params.getName().getRepoId() ) + .repositoryData( createProjectData( params ) ) + .forceInitialization( params.isForceInitialization() ) + .build() + .initialize(); + ContentInitializer.create() .setIndexService( indexService ) .setNodeService( nodeService ) - .setRepositoryService( repositoryService ) .repositoryId( params.getName().getRepoId() ) - .setRepositoryData( createProjectData( params ) ) .setContentData( contentRootData ) .accessControlList( CreateProjectRootAccessListCommand.create() .projectName( params.getName() ) diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java index 13103040bb8..83cb39c6e74 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentInitializer.java @@ -8,24 +8,20 @@ import com.enonic.xp.content.ContentConstants; import com.enonic.xp.content.ContentPropertyNames; -import com.enonic.xp.context.Context; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.data.PropertyTree; import com.enonic.xp.index.ChildOrder; import com.enonic.xp.index.IndexPath; import com.enonic.xp.node.CreateNodeParams; import com.enonic.xp.node.Node; +import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodeIds; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.PushNodeParams; import com.enonic.xp.node.RefreshMode; import com.enonic.xp.query.Direction; import com.enonic.xp.repository.BranchNotFoundException; -import com.enonic.xp.repository.CreateBranchParams; -import com.enonic.xp.repository.CreateRepositoryParams; -import com.enonic.xp.repository.RepositoryService; import com.enonic.xp.security.RoleKeys; -import com.enonic.xp.security.User; import com.enonic.xp.security.acl.AccessControlEntry; import com.enonic.xp.security.acl.AccessControlList; import com.enonic.xp.security.acl.Permission; @@ -45,17 +41,11 @@ public final class ContentInitializer private static final ChildOrder CONTENT_DEFAULT_CHILD_ORDER = ChildOrder.from( CONTENT_INDEX_PATH_DISPLAY_NAME + " " + Direction.ASC ); - private final RepositoryService repositoryService; - - private final PropertyTree repositoryData; - private final PropertyTree contentData; private ContentInitializer( final Builder builder ) { super( builder ); - this.repositoryService = builder.repositoryService; - this.repositoryData = builder.repositoryData; this.contentData = builder.contentData; } @@ -67,12 +57,7 @@ public static Builder create() @Override public void doInitialize() { - createAdminContext( ContentConstants.BRANCH_MASTER ).runWith( () -> { - initializeRepository(); - createDraftBranch(); - } ); - final Context adminDraft = createAdminContext( ContentConstants.BRANCH_DRAFT ); - adminDraft.runWith( this::initContentNode ); + createAdminContext( ContentConstants.BRANCH_DRAFT ).runWith( this::initContentNode ); } @Override @@ -80,8 +65,8 @@ protected boolean isInitialized() { try { - return createAdminContext( ContentConstants.BRANCH_MASTER ).callWith( () -> repositoryService.isInitialized( repositoryId ) && - nodeService.getByPath( ContentConstants.CONTENT_ROOT_PATH ) != null ); + return createAdminContext( ContentConstants.BRANCH_MASTER ).callWith( + () -> nodeService.getByPath( ContentConstants.CONTENT_ROOT_PATH ) != null ); } catch ( BranchNotFoundException e ) { @@ -92,33 +77,19 @@ protected boolean isInitialized() @Override protected String getInitializationSubject() { - return repositoryId + " repo"; - } - - private void createDraftBranch() - { - this.repositoryService.createBranch( CreateBranchParams.from( ContentConstants.BRANCH_DRAFT.getValue() ) ); - } - - private void initializeRepository() - { - final CreateRepositoryParams createRepositoryParams = CreateRepositoryParams.create() - .repositoryId( repositoryId ) - .data( repositoryData ) - .rootPermissions( ContentConstants.CONTENT_REPO_DEFAULT_ACL ) - .rootChildOrder( ContentConstants.DEFAULT_CONTENT_REPO_ROOT_ORDER ) - .build(); - - this.repositoryService.createRepository( createRepositoryParams ); + return repositoryId + " repo [content] layout"; } private void initContentNode() { final Node contentRootNode = nodeService.getByPath( ContentConstants.CONTENT_ROOT_PATH ); - final User user = ContextAccessor.current().getAuthInfo().getUser(); - - if ( contentRootNode == null ) + final NodeId contentRootNodeId; + if ( contentRootNode != null ) + { + contentRootNodeId = contentRootNode.id(); + } + else { LOG.info( "Content root-node not found, creating" ); @@ -127,7 +98,7 @@ private void initContentNode() data.setString( ContentPropertyNames.DISPLAY_NAME, "Content" ); data.addSet( ContentPropertyNames.DATA ); data.addSet( ContentPropertyNames.FORM ); - data.setString( ContentPropertyNames.CREATOR, user.getKey().toString() ); + data.setString( ContentPropertyNames.CREATOR, ContextAccessor.current().getAuthInfo().getUser().getKey().toString() ); data.setInstant( ContentPropertyNames.CREATED_TIME, Instant.now() ); final Node contentRoot = nodeService.create( CreateNodeParams.create() @@ -142,32 +113,17 @@ private void initContentNode() LOG.info( "Created content root-node: {}", contentRoot ); - final NodeIds ids = NodeIds.from( contentRoot.id() ); - nodeService.push( PushNodeParams.create().ids( ids ).target( ContentConstants.BRANCH_MASTER ).build() ); + contentRootNodeId = contentRoot.id(); } + nodeService.push( + PushNodeParams.create().ids( NodeIds.from( contentRootNodeId ) ).target( ContentConstants.BRANCH_MASTER ).build() ); } public static class Builder extends RepoDependentInitializer.Builder { - private RepositoryService repositoryService; - - private PropertyTree repositoryData; - private PropertyTree contentData; - public Builder setRepositoryService( final RepositoryService repositoryService ) - { - this.repositoryService = repositoryService; - return this; - } - - public Builder setRepositoryData( final PropertyTree repositoryData ) - { - this.repositoryData = repositoryData; - return this; - } - public Builder setContentData( final PropertyTree contentData ) { this.contentData = contentData; diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentRepoInitializer.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentRepoInitializer.java new file mode 100644 index 00000000000..2386ae91bca --- /dev/null +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/ContentRepoInitializer.java @@ -0,0 +1,138 @@ +package com.enonic.xp.core.impl.project.init; + +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.enonic.xp.content.ContentConstants; +import com.enonic.xp.context.Context; +import com.enonic.xp.context.ContextAccessor; +import com.enonic.xp.context.ContextBuilder; +import com.enonic.xp.data.PropertyTree; +import com.enonic.xp.init.ExternalInitializer; +import com.enonic.xp.repository.BranchAlreadyExistsException; +import com.enonic.xp.repository.CreateBranchParams; +import com.enonic.xp.repository.CreateRepositoryParams; +import com.enonic.xp.repository.RepositoryAlreadyExistsException; +import com.enonic.xp.repository.RepositoryConstants; +import com.enonic.xp.repository.RepositoryId; +import com.enonic.xp.repository.RepositoryService; + +public class ContentRepoInitializer + extends ExternalInitializer +{ + private static final Logger LOG = LoggerFactory.getLogger( ContentRepoInitializer.class ); + + private final RepositoryService repositoryService; + + private final PropertyTree repositoryData; + + protected final RepositoryId repositoryId; + + private ContentRepoInitializer( Builder builder ) + { + super( builder ); + this.repositoryService = Objects.requireNonNull( builder.repositoryService ); + this.repositoryData = Objects.requireNonNull( builder.repositoryData ); + this.repositoryId = Objects.requireNonNull( builder.repositoryId ); + } + + public static Builder create() + { + return new Builder(); + } + + @Override + public void doInitialize() + { + createAdminContext().runWith( () -> { + initializeRepository(); + createDraftBranch(); + } ); + } + + @Override + protected boolean isInitialized() + { + return createAdminContext().callWith( () -> repositoryService.isInitialized( repositoryId ) && + repositoryService.get( repositoryId ).getBranches().contains( ContentConstants.BRANCH_DRAFT ) ); + } + + @Override + protected String getInitializationSubject() + { + return repositoryId + " repo"; + } + + private void createDraftBranch() + { + try + { + this.repositoryService.createBranch( CreateBranchParams.from( ContentConstants.BRANCH_DRAFT ) ); + } + catch ( BranchAlreadyExistsException e ) + { + LOG.debug( "Skip content repository branch init as it already exists", e ); + } + } + + private void initializeRepository() + { + try + { + this.repositoryService.createRepository( CreateRepositoryParams.create() + .repositoryId( repositoryId ) + .data( repositoryData ) + .rootPermissions( ContentConstants.CONTENT_REPO_DEFAULT_ACL ) + .rootChildOrder( ContentConstants.DEFAULT_CONTENT_REPO_ROOT_ORDER ) + .build() ); + } + catch ( RepositoryAlreadyExistsException e ) + { + LOG.debug( "Skip content repository init as it already exists", e ); + } + } + + private Context createAdminContext() + { + return ContextBuilder.from( ContextAccessor.current() ) + .branch( RepositoryConstants.MASTER_BRANCH ) + .repositoryId( repositoryId ) + .authInfo( RepoDependentInitializer.SUPER_USER_AUTH ) + .build(); + } + + public static class Builder + extends ExternalInitializer.Builder + { + private RepositoryService repositoryService; + + private PropertyTree repositoryData; + + private RepositoryId repositoryId; + + public Builder repositoryService( final RepositoryService repositoryService ) + { + this.repositoryService = repositoryService; + return this; + } + + public Builder repositoryData( final PropertyTree repositoryData ) + { + this.repositoryData = repositoryData; + return this; + } + + public Builder repositoryId( final RepositoryId repositoryId ) + { + this.repositoryId = repositoryId; + return this; + } + + public ContentRepoInitializer build() + { + return new ContentRepoInitializer( this ); + } + } +} diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/RepoDependentInitializer.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/RepoDependentInitializer.java index 1cabb213bcd..9fe0d0431d5 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/RepoDependentInitializer.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/RepoDependentInitializer.java @@ -18,10 +18,10 @@ public abstract class RepoDependentInitializer extends ExternalInitializer { - public static final User SUPER_USER = User.create(). - key( PrincipalKey.ofSuperUser() ). - login( PrincipalKey.ofSuperUser().getId() ). - build(); + public static final AuthenticationInfo SUPER_USER_AUTH = AuthenticationInfo.create() + .principals( RoleKeys.ADMIN ) + .user( User.create().key( PrincipalKey.ofSuperUser() ).login( PrincipalKey.ofSuperUser().getId() ).build() ) + .build(); protected final NodeService nodeService; @@ -33,23 +33,23 @@ protected RepoDependentInitializer( final Builder builder ) { super( builder ); - this.nodeService = builder.nodeService; - this.repositoryId = builder.repositoryId; - this.accessControlList = builder.accessControlList; + this.nodeService = Objects.requireNonNull( builder.nodeService ); + this.repositoryId = Objects.requireNonNull( builder.repositoryId ); + this.accessControlList = Objects.requireNonNull( builder.accessControlList ); } protected Context createAdminContext( Branch branch ) { - final AuthenticationInfo authInfo = createAdminAuthInfo(); - return ContextBuilder.from( ContextAccessor.current() ).branch( branch ).repositoryId( repositoryId ).authInfo( authInfo ).build(); + return createAdminContext(branch, repositoryId); } - protected AuthenticationInfo createAdminAuthInfo() + static Context createAdminContext( Branch branch, RepositoryId repositoryId ) { - return AuthenticationInfo.create(). - principals( RoleKeys.ADMIN ). - user( SUPER_USER ). - build(); + return ContextBuilder.from( ContextAccessor.current() ) + .branch( branch ) + .repositoryId( repositoryId ) + .authInfo( SUPER_USER_AUTH ) + .build(); } public static class Builder @@ -78,14 +78,5 @@ public T accessControlList( final AccessControlList accessControlList ) this.accessControlList = accessControlList; return (T) this; } - - @Override - protected void validate() - { - super.validate(); - Objects.requireNonNull( nodeService ); - Objects.requireNonNull( repositoryId, "repositoryId is required" ); - } - } } diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/DefaultProjectMigrator.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/Xp8DefaultProjectMigrator.java similarity index 89% rename from modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/DefaultProjectMigrator.java rename to modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/Xp8DefaultProjectMigrator.java index 7e0234c22a2..a6a71dd02fd 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/DefaultProjectMigrator.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/init/Xp8DefaultProjectMigrator.java @@ -7,8 +7,6 @@ import com.enonic.xp.branch.Branch; import com.enonic.xp.content.ContentConstants; import com.enonic.xp.context.Context; -import com.enonic.xp.context.ContextAccessor; -import com.enonic.xp.context.ContextBuilder; import com.enonic.xp.core.impl.project.CreateProjectRolesCommand; import com.enonic.xp.core.impl.project.ProjectAccessHelper; import com.enonic.xp.index.IndexService; @@ -28,9 +26,8 @@ import com.enonic.xp.security.acl.AccessControlEntry; import com.enonic.xp.security.acl.AccessControlList; import com.enonic.xp.security.acl.Permission; -import com.enonic.xp.security.auth.AuthenticationInfo; -public class DefaultProjectMigrator +public class Xp8DefaultProjectMigrator { public static final ProjectName DEFAULT_PROJECT_NAME = ProjectName.from( RepositoryId.from( "com.enonic.cms.default" ) ); @@ -63,7 +60,7 @@ public class DefaultProjectMigrator private final IndexService indexService; - public DefaultProjectMigrator( final NodeService nodeService, final SecurityService securityService, final IndexService indexService ) + public Xp8DefaultProjectMigrator( final NodeService nodeService, final SecurityService securityService, final IndexService indexService ) { this.nodeService = nodeService; this.securityService = securityService; @@ -151,17 +148,6 @@ private void applyPermissions( final NodePath nodePath, final List { - final CreateRepositoryParams createRepositoryParams = CreateRepositoryParams.create(). + this.repositoryService.createRepository( CreateRepositoryParams.create(). repositoryId( SystemConstants.SYSTEM_REPO_ID ). rootChildOrder( ChildOrder.name() ). rootPermissions( SystemConstants.SYSTEM_REPO_DEFAULT_ACL ). - build(); - - this.repositoryService.createRepository( createRepositoryParams ); + build() ); initRepositoryFolder(); } ); @@ -100,10 +95,10 @@ private void initRepositoryFolder() private Context createAdminContext() { - final User admin = User.create().key( SUPER_USER ).login( SUPER_USER.getId() ).build(); + final User admin = User.create().key( PrincipalKey.ofSuperUser() ).login( PrincipalKey.ofSuperUser().getId() ).build(); final AuthenticationInfo authInfo = AuthenticationInfo.create().principals( RoleKeys.ADMIN ).user( admin ).build(); return ContextBuilder.create(). - branch( SecurityConstants.BRANCH_SECURITY ). + branch( SystemConstants.BRANCH_SYSTEM ). repositoryId( SystemConstants.SYSTEM_REPO_ID ). authInfo( authInfo ).build(); } diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/Xp8IndexMigrator.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/Xp8IndexMigrator.java new file mode 100644 index 00000000000..ce40ad86922 --- /dev/null +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/Xp8IndexMigrator.java @@ -0,0 +1,33 @@ +package com.enonic.xp.repo.impl.repository; + +import java.util.Map; + +import com.enonic.xp.branch.Branch; +import com.enonic.xp.index.IndexType; +import com.enonic.xp.repo.impl.index.IndexServiceInternal; +import com.enonic.xp.repository.Repository; +import com.enonic.xp.repository.RepositoryService; + +class Xp8IndexMigrator +{ + final RepositoryService repositoryService; + final IndexServiceInternal indexServiceInternal; + + public Xp8IndexMigrator( final RepositoryService repositoryService, final IndexServiceInternal indexServiceInternal ) + { + this.repositoryService = repositoryService; + this.indexServiceInternal = indexServiceInternal; + } + + public void migrate() + { + for ( Repository repository : repositoryService.list() ) + { + final Map indexSettings = this.indexServiceInternal.getIndexMapping( repository.getId(), Branch.from( "master" ), IndexType.VERSION ); + if ( indexSettings != null ) + { + continue; + } + } + } +} diff --git a/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java b/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java index d533d2ec6b2..f19f297bba5 100644 --- a/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java +++ b/modules/core/core-repo/src/test/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivatorTest.java @@ -13,7 +13,6 @@ import com.enonic.xp.node.NodeId; import com.enonic.xp.node.NodePath; import com.enonic.xp.node.NodeVersionMetadata; -import com.enonic.xp.repo.impl.NodeBranchEntry; import com.enonic.xp.repo.impl.index.IndexServiceInternal; import com.enonic.xp.repo.impl.search.NodeSearchService; import com.enonic.xp.repo.impl.storage.NodeStorageService; diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java index d74d7946c18..270193d6e87 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/AbstractContentServiceTest.java @@ -210,10 +210,7 @@ public Context ctxMasterSu() return ContextBuilder.create(). branch( ContentConstants.BRANCH_MASTER ). repositoryId( testprojectName.getRepoId() ). - authInfo( AuthenticationInfo.create(). - principals( RoleKeys.ADMIN ). - user( ContentInitializer.SUPER_USER ). - build() ). + authInfo( ContentInitializer.SUPER_USER_AUTH ). build(); } diff --git a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java index ee6bfca5dad..aad7a1dce16 100644 --- a/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java +++ b/modules/itest/itest-core/src/test/java/com/enonic/xp/core/content/ContentServiceImplTest_versions.java @@ -1,8 +1,5 @@ package com.enonic.xp.core.content; -import java.util.List; -import java.util.function.Function; - import org.junit.jupiter.api.Test; import com.enonic.xp.archive.ArchiveContentParams; @@ -19,8 +16,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; class ContentServiceImplTest_versions extends AbstractContentServiceTest From d4a104e7719681e285f803f7b1808e226bcc80b2 Mon Sep 17 00:00:00 2001 From: rymsha Date: Mon, 3 Nov 2025 16:16:49 +0100 Subject: [PATCH 8/8] wip --- .../com/enonic/xp/core/impl/project/ProjectServiceImpl.java | 1 + .../xp/repo/impl/repository/RepositoryServiceActivator.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java index 03ca8c9d1e1..7de137a593d 100644 --- a/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java +++ b/modules/core/core-project/src/main/java/com/enonic/xp/core/impl/project/ProjectServiceImpl.java @@ -186,6 +186,7 @@ private static void buildIcon( final Project.Builder project, final PropertySet private void doInitRootNodes( final CreateProjectParams params, final PropertyTree contentRootData ) { ContentRepoInitializer.create() + .setIndexService( indexService ) .repositoryService( repositoryService ) .repositoryId( params.getName().getRepoId() ) .repositoryData( createProjectData( params ) ) diff --git a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivator.java b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivator.java index 195bdbd87da..37aac91b1f8 100644 --- a/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivator.java +++ b/modules/core/core-repo/src/main/java/com/enonic/xp/repo/impl/repository/RepositoryServiceActivator.java @@ -55,7 +55,7 @@ public void activate( final BundleContext context ) build(). initialize(); - new Xp8IndexMigrator( repositoryService, indexServiceInternal).migrate(); + //new Xp8IndexMigrator( repositoryService, indexServiceInternal).migrate(); service = context.registerService( new String[]{RepositoryService.class.getName(), InternalRepositoryService.class.getName()}, repositoryService, null );