diff --git a/pmd-ruleset.xml b/pmd-ruleset.xml
index 8869e21..ef18056 100644
--- a/pmd-ruleset.xml
+++ b/pmd-ruleset.xml
@@ -36,7 +36,13 @@
-->
-
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index e774a36..35776f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,11 +15,24 @@
+ 5.8.2
4.6.0
UTF-8
11
+
+
+
+ org.junit
+ junit-bom
+ ${junit.version}
+ pom
+ import
+
+
+
+
@@ -56,19 +69,16 @@
org.junit.jupiter
junit-jupiter-api
- 5.6.2
test
org.junit.jupiter
junit-jupiter-engine
- 5.6.2
test
org.junit.platform
junit-platform-runner
- 1.6.2
test
@@ -77,6 +87,12 @@
1.3
test
+
+ org.mockito
+ mockito-core
+ 4.5.1
+ test
+
diff --git a/spotbug-exclude-filter.xml b/spotbug-exclude-filter.xml
index e2e4b22..de9f2df 100644
--- a/spotbug-exclude-filter.xml
+++ b/spotbug-exclude-filter.xml
@@ -8,7 +8,7 @@
+ pattern="REC_CATCH_EXCEPTION,RV_CHECK_FOR_POSITIVE_INDEXOF,BC_UNCONFIRMED_CAST_OF_RETURN_VALUE,THROWS_METHOD_THROWS_CLAUSE_THROWABLE" />
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/EntityLock.java b/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/EntityLock.java
index 6f11117..6761965 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/EntityLock.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/EntityLock.java
@@ -4,8 +4,8 @@
public final class EntityLock implements Serializable {
- private final Identifier entity;
- private final Identifier user;
+ private final long entity;
+ private final long user;
private final long created;
private final long lastAccess;
private final long ttl;
@@ -20,11 +20,11 @@ private EntityLock(Builder builder) {
this.ttl = builder.ttl;
}
- public Identifier getEntity() {
+ public long getEntity() {
return entity;
}
- public Identifier getUser() {
+ public long getUser() {
return user;
}
@@ -55,8 +55,8 @@ public String toString() {
public static class Builder {
- private Identifier entity;
- private Identifier user;
+ private long entity;
+ private long user;
private long created;
private long lastAccess;
private long ttl;
@@ -72,14 +72,12 @@ private Builder(EntityLock entityLock) {
this.ttl = entityLock.ttl;
}
- public Builder entity(Identifier entity) {
- assert entity != null;
+ public Builder entity(long entity) {
this.entity = entity;
return this;
}
- public Builder user(Identifier user) {
- assert user != null;
+ public Builder user(long user) {
this.user = user;
return this;
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/RecycleBinItem.java b/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/RecycleBinItem.java
index 96abdb3..ea8e2ce 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/RecycleBinItem.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/domain/entity/RecycleBinItem.java
@@ -6,23 +6,23 @@
public final class RecycleBinItem {
- private final Identifier identifier;
- private final Identifier parent;
+ private final long id;
+ private final long parent;
private final Entity entity;
private final List children;
private RecycleBinItem(Builder builder) {
- this.identifier = builder.identifier;
+ this.id = builder.id;
this.parent = builder.parent;
this.entity = builder.entity;
this.children = builder.children;
}
- public Identifier getIdentifier() {
- return this.identifier;
+ public long getId() {
+ return this.id;
}
- public Identifier getParent() {
+ public long getParent() {
return this.parent;
}
@@ -44,27 +44,25 @@ public Builder toBuilder() {
public static class Builder {
- private Identifier identifier;
- private Identifier parent;
+ private long id;
+ private long parent;
private Entity entity;
private List children = new ArrayList<>();
private Builder() {}
private Builder(RecycleBinItem recycleBinItem) {
- this.identifier = recycleBinItem.identifier;
+ this.id = recycleBinItem.id;
this.parent = recycleBinItem.parent;
this.entity = recycleBinItem.entity;
this.children = new ArrayList<>(recycleBinItem.children);
}
- public Builder identifier(Identifier identifier) {
- assert identifier != null;
- this.identifier = identifier;
+ public Builder identifier(long id) {
+ this.id = id;
return this;
}
- public Builder parent(Identifier parent) {
- assert parent != null;
+ public Builder parent(long parent) {
this.parent = parent;
return this;
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/domain/exception/EntityNotFound.java b/src/main/java/com/sitepark/ies/contentrepository/core/domain/exception/EntityNotFound.java
index de5426d..d2849d1 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/domain/exception/EntityNotFound.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/domain/exception/EntityNotFound.java
@@ -1,24 +1,22 @@
package com.sitepark.ies.contentrepository.core.domain.exception;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
-
public class EntityNotFound extends ContentRepositoryException {
private static final long serialVersionUID = 1L;
- private final Identifier identifier;
+ private final long id;
- public EntityNotFound(Identifier identifier) {
+ public EntityNotFound(long id) {
super();
- this.identifier = identifier;
+ this.id = id;
}
- public Identifier getIdentifier() {
- return this.identifier;
+ public long getId() {
+ return this.id;
}
@Override
public String getMessage() {
- return "Entity with identifier " + this.identifier + " not found";
+ return "Entity with id " + this.id + " not found";
}
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/domain/exception/GroupNotEmpty.java b/src/main/java/com/sitepark/ies/contentrepository/core/domain/exception/GroupNotEmpty.java
new file mode 100644
index 0000000..8c69839
--- /dev/null
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/domain/exception/GroupNotEmpty.java
@@ -0,0 +1,22 @@
+package com.sitepark.ies.contentrepository.core.domain.exception;
+
+public class GroupNotEmpty extends ContentRepositoryException {
+ private static final long serialVersionUID = 1L;
+
+ private final long id;
+
+ public GroupNotEmpty(long id) {
+ super();
+ this.id = id;
+ }
+
+ public long getId() {
+ return this.id;
+ }
+
+ @Override
+ public String getMessage() {
+ return "Group with id " + this.id + " not empty";
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/AccessControl.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/AccessControl.java
index bbc8b5d..9fd14ea 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/AccessControl.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/AccessControl.java
@@ -1,16 +1,14 @@
package com.sitepark.ies.contentrepository.core.port;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
-
public interface AccessControl {
- boolean isEntityCreateable(Identifier parent);
- boolean isEntityReadable(Identifier identifier);
- boolean isEntityWritable(Identifier identifier);
- boolean isEntityRemovable(Identifier identifier);
+ boolean isEntityCreateable(long parent);
+ boolean isEntityReadable(long id);
+ boolean isEntityWritable(long id);
+ boolean isEntityRemovable(long id);
- boolean isGroupCreateable(Identifier parent);
- boolean isGroupReadable(Identifier identifier);
- boolean isGroupWritable(Identifier identifier);
- boolean isGroupRemoveable(Identifier identifier);
+ boolean isGroupCreateable(long parent);
+ boolean isGroupReadable(long id);
+ boolean isGroupWritable(long id);
+ boolean isGroupRemoveable(long id);
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/ContentRepository.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/ContentRepository.java
index 691fb34..2faf0f3 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/ContentRepository.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/ContentRepository.java
@@ -8,9 +8,13 @@
import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
public interface ContentRepository {
+ boolean isGroup(long id);
+ boolean isEmptyGroup(long id);
Optional store(Entity entity);
- Optional get(Identifier identifier);
- Optional remove(Identifier identifier);
+ Optional get(long id);
+ void removeEntity(long id);
+ void removeGroup(long id);
Optional resolveAnchor(Anchor anchor);
- List getAllMediaReferences(Identifier identifier);
+ long resolve(Identifier identifier);
+ List getAllMediaReferences(long id);
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/EntityLockManager.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/EntityLockManager.java
index 0e47b66..067c7bd 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/EntityLockManager.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/EntityLockManager.java
@@ -4,11 +4,10 @@
import java.util.Optional;
import com.sitepark.ies.contentrepository.core.domain.entity.EntityLock;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
public interface EntityLockManager {
- Optional getLock(Identifier identifier);
- void lock(Identifier identifier);
- void unlock(Identifier identifier);
+ Optional getLock(long id);
+ void lock(long id);
+ void unlock(long id);
List getLockList();
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/HistoryManager.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/HistoryManager.java
index 14ec3f5..72876c1 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/HistoryManager.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/HistoryManager.java
@@ -4,10 +4,9 @@
import com.sitepark.ies.contentrepository.core.domain.entity.HistoryEntry;
import com.sitepark.ies.contentrepository.core.domain.entity.HistoryEntryType;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
public interface HistoryManager {
- void purge(Identifier identifier);
- HistoryEntry createEntry(Identifier identifier, long timestamp, HistoryEntryType type);
- List getHistory(Identifier identifier);
+ void purge(long id);
+ HistoryEntry createEntry(long id, long timestamp, HistoryEntryType type);
+ List getHistory(long id);
}
\ No newline at end of file
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/IdGenerator.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/IdGenerator.java
index b220ad8..641ce56 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/IdGenerator.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/IdGenerator.java
@@ -1,5 +1,5 @@
package com.sitepark.ies.contentrepository.core.port;
public interface IdGenerator {
- Long generate();
+ long generate();
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/Publisher.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/Publisher.java
index 4d993df..062b837 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/Publisher.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/Publisher.java
@@ -1,8 +1,6 @@
package com.sitepark.ies.contentrepository.core.port;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
-
public interface Publisher {
- void republish(Identifier identifier, long version);
- void depublish(Identifier identifier);
+ void republish(long id, long version);
+ void depublish(long id);
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/RecycleBin.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/RecycleBin.java
index 46a21b6..db51cca 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/RecycleBin.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/RecycleBin.java
@@ -3,13 +3,12 @@
import java.util.List;
import java.util.Optional;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
import com.sitepark.ies.contentrepository.core.domain.entity.RecycleBinItem;
import com.sitepark.ies.contentrepository.core.domain.entity.RecycleBinItemFilter;
public interface RecycleBin {
- Optional get(Identifier identifier);
+ Optional get(long id);
void add(RecycleBinItem item);
- void remove(Identifier identifier);
+ void removeByObject(long id);
List find(RecycleBinItemFilter filter);
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/SearchIndex.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/SearchIndex.java
index 0feab61..1ce3f55 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/SearchIndex.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/SearchIndex.java
@@ -1,9 +1,8 @@
package com.sitepark.ies.contentrepository.core.port;
import com.sitepark.ies.contentrepository.core.domain.entity.Entity;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
public interface SearchIndex {
void index(Entity entity);
- void remove(Identifier identifier);
+ void remove(long id);
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/port/VersioningManager.java b/src/main/java/com/sitepark/ies/contentrepository/core/port/VersioningManager.java
index 4b1bfd9..6b66ed4 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/port/VersioningManager.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/port/VersioningManager.java
@@ -4,15 +4,14 @@
import com.sitepark.ies.contentrepository.core.domain.entity.Entity;
import com.sitepark.ies.contentrepository.core.domain.entity.EntityVersion;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
public interface VersioningManager {
- void removeAllVersions(Identifier identifier);
+ void removeAllVersions(long id);
Entity createNewVersion(Entity entity);
Entity revertToVersion(EntityVersion version);
Entity getVersion(EntityVersion version);
Entity getNextVersionSince(long timestamp);
- List getAllMediaReferences(Identifier identifier);
+ List getAllMediaReferences(long id);
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/PurgeEntity.java b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/PurgeEntity.java
index 024e1b7..accbecd 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/PurgeEntity.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/PurgeEntity.java
@@ -6,10 +6,7 @@
import javax.inject.Inject;
-import org.eclipse.jdt.annotation.NonNull;
-
import com.sitepark.ies.contentrepository.core.domain.entity.EntityLock;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
import com.sitepark.ies.contentrepository.core.domain.exception.AccessDenied;
import com.sitepark.ies.contentrepository.core.domain.exception.EntityLocked;
import com.sitepark.ies.contentrepository.core.port.AccessControl;
@@ -50,34 +47,30 @@ protected PurgeEntity(ContentRepository repository, EntityLockManager lockManage
this.publisher = publisher;
}
- public void purge(@NonNull Identifier identifier) {
-
- if (identifier == null) {
- throw new IllegalArgumentException("identifier is null");
- }
+ public void purgeEntity(long id) {
- if (!this.accessControl.isEntityRemovable(identifier)) {
- throw new AccessDenied("Not allowed to remove entity " + identifier);
+ if (!this.accessControl.isEntityRemovable(id)) {
+ throw new AccessDenied("Not allowed to remove entity " + id);
}
- Optional lock = this.lockManager.getLock(identifier);
+ Optional lock = this.lockManager.getLock(id);
lock.ifPresent(l -> {
throw new EntityLocked(l);
});
- this.searchIndex.remove(identifier);
+ this.searchIndex.remove(id);
- this.publisher.depublish(identifier);
+ this.publisher.depublish(id);
- List mediaRefs = this.repository.getAllMediaReferences(identifier);
- this.repository.remove(identifier);
+ List mediaRefs = this.repository.getAllMediaReferences(id);
+ this.repository.removeEntity(id);
- this.historyManager.purge(identifier);
+ this.historyManager.purge(id);
- List mediaRefsFromOtherVersions = this.versioningManager.getAllMediaReferences(identifier);
- this.versioningManager.removeAllVersions(identifier);
+ List mediaRefsFromOtherVersions = this.versioningManager.getAllMediaReferences(id);
+ this.versioningManager.removeAllVersions(id);
- this.recycleBin.remove(identifier);
+ this.recycleBin.removeByObject(id);
List allMediaRefs = new ArrayList<>();
allMediaRefs.addAll(mediaRefs);
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/PurgeGroup.java b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/PurgeGroup.java
new file mode 100644
index 0000000..5e7b51b
--- /dev/null
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/PurgeGroup.java
@@ -0,0 +1,87 @@
+package com.sitepark.ies.contentrepository.core.usecase;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+import com.sitepark.ies.contentrepository.core.domain.entity.EntityLock;
+import com.sitepark.ies.contentrepository.core.domain.exception.AccessDenied;
+import com.sitepark.ies.contentrepository.core.domain.exception.EntityLocked;
+import com.sitepark.ies.contentrepository.core.domain.exception.GroupNotEmpty;
+import com.sitepark.ies.contentrepository.core.port.AccessControl;
+import com.sitepark.ies.contentrepository.core.port.ContentRepository;
+import com.sitepark.ies.contentrepository.core.port.EntityLockManager;
+import com.sitepark.ies.contentrepository.core.port.HistoryManager;
+import com.sitepark.ies.contentrepository.core.port.MediaRepository;
+import com.sitepark.ies.contentrepository.core.port.Publisher;
+import com.sitepark.ies.contentrepository.core.port.RecycleBin;
+import com.sitepark.ies.contentrepository.core.port.SearchIndex;
+import com.sitepark.ies.contentrepository.core.port.VersioningManager;
+
+public final class PurgeGroup {
+
+ private final ContentRepository repository;
+ private final EntityLockManager lockManager;
+ private final VersioningManager versioningManager;
+ private final HistoryManager historyManager;
+ private final AccessControl accessControl;
+ private final RecycleBin recycleBin;
+ private final SearchIndex searchIndex;
+ private final MediaRepository mediaRepository;
+ private final Publisher publisher;
+
+ @Inject
+ protected PurgeGroup(ContentRepository repository, EntityLockManager lockManager,
+ VersioningManager versioningManager, HistoryManager historyManager, AccessControl accessControl,
+ RecycleBin recycleBin, SearchIndex searchIndex, MediaRepository mediaRepository, Publisher publisher) {
+
+ this.repository = repository;
+ this.lockManager = lockManager;
+ this.historyManager = historyManager;
+ this.versioningManager = versioningManager;
+ this.accessControl = accessControl;
+ this.recycleBin = recycleBin;
+ this.searchIndex = searchIndex;
+ this.mediaRepository = mediaRepository;
+ this.publisher = publisher;
+ }
+
+ public void purgeGroup(long id) {
+
+ if (!this.accessControl.isGroupRemoveable(id)) {
+ throw new AccessDenied("Not allowed to remove group " + id);
+ }
+
+ if (!this.repository.isEmptyGroup(id)) {
+ throw new GroupNotEmpty(id);
+ }
+
+ Optional lock = this.lockManager.getLock(id);
+ lock.ifPresent(l -> {
+ throw new EntityLocked(l);
+ });
+
+ this.searchIndex.remove(id);
+
+ this.publisher.depublish(id);
+
+ List mediaRefs = this.repository.getAllMediaReferences(id);
+ this.repository.removeGroup(id);
+
+ this.historyManager.purge(id);
+
+ List mediaRefsFromOtherVersions = this.versioningManager.getAllMediaReferences(id);
+ this.versioningManager.removeAllVersions(id);
+
+ this.recycleBin.removeByObject(id);
+
+ List allMediaRefs = new ArrayList<>();
+ allMediaRefs.addAll(mediaRefs);
+ allMediaRefs.addAll(mediaRefsFromOtherVersions);
+
+ this.mediaRepository.remove(allMediaRefs);
+
+ }
+}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RecoverEntity.java b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RecoverEntity.java
index 5fa8349..6bec139 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RecoverEntity.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RecoverEntity.java
@@ -4,7 +4,6 @@
import com.sitepark.ies.contentrepository.core.domain.entity.Entity;
import com.sitepark.ies.contentrepository.core.domain.entity.HistoryEntryType;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
import com.sitepark.ies.contentrepository.core.domain.entity.RecycleBinItem;
import com.sitepark.ies.contentrepository.core.domain.exception.AccessDenied;
import com.sitepark.ies.contentrepository.core.domain.exception.EntityNotFound;
@@ -31,13 +30,13 @@ protected RecoverEntity(ContentRepository repository, HistoryManager historyMana
this.searchIndex = searchIndex;
}
- public void recover(Identifier identifier) {
+ public void recover(long id) {
- Optional recycleBinItem = this.recycleBin.get(identifier);
- recycleBinItem.orElseThrow(() -> new EntityNotFound(identifier));
+ Optional recycleBinItem = this.recycleBin.get(id);
+ recycleBinItem.orElseThrow(() -> new EntityNotFound(id));
if (!this.accessControl.isGroupCreateable(recycleBinItem.get().getParent())) {
- throw new AccessDenied("Not allowed to recover entity " + recycleBinItem.get().getIdentifier()
+ throw new AccessDenied("Not allowed to recover entity " + recycleBinItem.get().getId()
+ " in group " + recycleBinItem.get().getParent());
}
@@ -45,7 +44,7 @@ public void recover(Identifier identifier) {
this.repository.store(entity);
- this.historyManager.createEntry(identifier, System.currentTimeMillis(), HistoryEntryType.RESTORED);
+ this.historyManager.createEntry(id, System.currentTimeMillis(), HistoryEntryType.RESTORED);
this.searchIndex.index(entity);
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RemoveEntity.java b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RemoveEntity.java
index 95ca153..a1837f0 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RemoveEntity.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/RemoveEntity.java
@@ -5,14 +5,15 @@
import com.sitepark.ies.contentrepository.core.domain.entity.Entity;
import com.sitepark.ies.contentrepository.core.domain.entity.EntityLock;
import com.sitepark.ies.contentrepository.core.domain.entity.HistoryEntryType;
-import com.sitepark.ies.contentrepository.core.domain.entity.Identifier;
import com.sitepark.ies.contentrepository.core.domain.entity.RecycleBinItem;
import com.sitepark.ies.contentrepository.core.domain.exception.AccessDenied;
import com.sitepark.ies.contentrepository.core.domain.exception.EntityLocked;
+import com.sitepark.ies.contentrepository.core.domain.exception.GroupNotEmpty;
import com.sitepark.ies.contentrepository.core.port.AccessControl;
import com.sitepark.ies.contentrepository.core.port.ContentRepository;
import com.sitepark.ies.contentrepository.core.port.EntityLockManager;
import com.sitepark.ies.contentrepository.core.port.HistoryManager;
+import com.sitepark.ies.contentrepository.core.port.Publisher;
import com.sitepark.ies.contentrepository.core.port.RecycleBin;
import com.sitepark.ies.contentrepository.core.port.SearchIndex;
@@ -24,43 +25,80 @@ public final class RemoveEntity {
private final AccessControl accessControl;
private final RecycleBin recycleBin;
private final SearchIndex searchIndex;
+ private final Publisher publisher;
protected RemoveEntity(ContentRepository repository, EntityLockManager lockManager,
- HistoryManager historyManager, AccessControl accessControl, RecycleBin recycleBin,
- SearchIndex searchIndex) {
+ HistoryManager historyManager, AccessControl accessControl,
+ RecycleBin recycleBin, SearchIndex searchIndex, Publisher publisher) {
+
this.repository = repository;
this.lockManager = lockManager;
this.historyManager = historyManager;
this.accessControl = accessControl;
this.recycleBin = recycleBin;
this.searchIndex = searchIndex;
+ this.publisher = publisher;
+ }
+
+ public void remove(long id) {
+ if (this.repository.isGroup(id)) {
+ this.removeGroup(id);
+ } else {
+ this.removeEntity(id);
+ }
}
- public Optional remove(Identifier identifier) {
+ public void removeGroup(long id) {
- if (!this.accessControl.isEntityRemovable(identifier)) {
- throw new AccessDenied("Not allowed to remove entity " + identifier);
+ if (!this.accessControl.isGroupRemoveable(id)) {
+ throw new AccessDenied("Not allowed to remove group " + id);
}
- Optional entity = this.repository.get(identifier);
- if (entity.isEmpty()) {
- return entity;
+ if (!this.repository.isEmptyGroup(id)) {
+ throw new GroupNotEmpty(id);
}
- Optional lock = this.lockManager.getLock(identifier);
+ Optional lock = this.lockManager.getLock(id);
lock.ifPresent(l -> {
throw new EntityLocked(l);
});
- this.repository.remove(identifier);
+ this.searchIndex.remove(id);
+
+ this.repository.removeGroup(id);
- this.historyManager.createEntry(identifier, System.currentTimeMillis(), HistoryEntryType.REMOVED);
+ this.historyManager.createEntry(id, System.currentTimeMillis(), HistoryEntryType.REMOVED);
RecycleBinItem recycleBinItem = RecycleBinItem.builder().build();
this.recycleBin.add(recycleBinItem);
- this.searchIndex.remove(identifier);
+ }
+
+ public void removeEntity(long id) {
+
+ if (!this.accessControl.isEntityRemovable(id)) {
+ throw new AccessDenied("Not allowed to remove entity " + id);
+ }
- return entity;
+ Optional entity = this.repository.get(id);
+ if (entity.isEmpty()) {
+ return;
+ }
+
+ Optional lock = this.lockManager.getLock(id);
+ lock.ifPresent(l -> {
+ throw new EntityLocked(l);
+ });
+
+ this.searchIndex.remove(id);
+
+ this.publisher.depublish(id);
+
+ this.repository.removeEntity(id);
+
+ this.historyManager.createEntry(id, System.currentTimeMillis(), HistoryEntryType.REMOVED);
+
+ RecycleBinItem recycleBinItem = RecycleBinItem.builder().build();
+ this.recycleBin.add(recycleBinItem);
}
}
diff --git a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/StoreEntity.java b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/StoreEntity.java
index 0f78f5f..1bd0d0f 100644
--- a/src/main/java/com/sitepark/ies/contentrepository/core/usecase/StoreEntity.java
+++ b/src/main/java/com/sitepark/ies/contentrepository/core/usecase/StoreEntity.java
@@ -57,16 +57,20 @@ private Identifier create(Entity newEntity) {
Optional parent = newEntity.getParent();
parent.orElseThrow(() -> new ParentMissing());
- if (!this.accessControl.isEntityCreateable(parent.get())) {
+ long parentId = this.repository.resolve(parent.get());
+
+ if (!this.accessControl.isEntityCreateable(parentId)) {
throw new AccessDenied("Not allowed to create entity in group " + parent);
}
- Entity entityWithId = newEntity.toBuilder().identifier(Identifier.ofId(this.idGenerator.generate())).build();
+ long generatedId = this.idGenerator.generate();
+
+ Entity entityWithId = newEntity.toBuilder().identifier(Identifier.ofId(generatedId)).build();
Entity versioned = this.versioningManager.createNewVersion(entityWithId);
this.repository.store(versioned);
- this.historyManager.createEntry(versioned.getIdentifier().get(), versioned.getVersion().get().getTimestamp(),
+ this.historyManager.createEntry(generatedId, versioned.getVersion().get().getTimestamp(),
HistoryEntryType.CREATED);
this.searchIndex.index(versioned);
@@ -78,14 +82,16 @@ private Identifier update(Entity updateEntity) {
updateEntity.getIdentifier()
.orElseThrow(() -> new IllegalArgumentException("Update failed, identifier missing"));
- Optional existsEntity = this.repository.get(updateEntity.getIdentifier().get());
- existsEntity.orElseThrow(() -> new EntityNotFound(updateEntity.getIdentifier().get()));
+ long id = this.repository.resolve(updateEntity.getIdentifier().get());
+
+ Optional existsEntity = this.repository.get(id);
+ existsEntity.orElseThrow(() -> new EntityNotFound(id));
- if (!this.accessControl.isEntityWritable(updateEntity.getIdentifier().get())) {
+ if (!this.accessControl.isEntityWritable(id)) {
throw new AccessDenied("Not allowed to update entity " + updateEntity.getIdentifier());
}
- Optional lock = this.lockManager.getLock(updateEntity.getIdentifier().get());
+ Optional lock = this.lockManager.getLock(id);
lock.ifPresent(l -> {
throw new EntityLocked(l);
});
@@ -100,7 +106,7 @@ private Identifier update(Entity updateEntity) {
this.repository.store(versioned);
this.searchIndex.index(versioned);
- this.historyManager.createEntry(versioned.getIdentifier().get(), versioned.getVersion().get().getTimestamp(),
+ this.historyManager.createEntry(id, versioned.getVersion().get().getTimestamp(),
HistoryEntryType.UPDATED);
return versioned.getIdentifier().get();
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 11e4275..82b3689 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -2,6 +2,7 @@
exports com.sitepark.ies.contentrepository.core.domain.entity;
exports com.sitepark.ies.contentrepository.core.domain.exception;
exports com.sitepark.ies.contentrepository.core.port;
+ exports com.sitepark.ies.contentrepository.core.usecase;
requires javax.inject;
requires org.eclipse.jdt.annotation;
}
\ No newline at end of file
diff --git a/src/test/java/com/sitepark/ies/contentrepository/core/usecase/PurgeEntityTest.java b/src/test/java/com/sitepark/ies/contentrepository/core/usecase/PurgeEntityTest.java
new file mode 100644
index 0000000..2e44df7
--- /dev/null
+++ b/src/test/java/com/sitepark/ies/contentrepository/core/usecase/PurgeEntityTest.java
@@ -0,0 +1,129 @@
+package com.sitepark.ies.contentrepository.core.usecase;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Optional;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.InOrder;
+
+import com.sitepark.ies.contentrepository.core.domain.entity.EntityLock;
+import com.sitepark.ies.contentrepository.core.domain.exception.AccessDenied;
+import com.sitepark.ies.contentrepository.core.domain.exception.EntityLocked;
+import com.sitepark.ies.contentrepository.core.port.AccessControl;
+import com.sitepark.ies.contentrepository.core.port.ContentRepository;
+import com.sitepark.ies.contentrepository.core.port.EntityLockManager;
+import com.sitepark.ies.contentrepository.core.port.HistoryManager;
+import com.sitepark.ies.contentrepository.core.port.MediaRepository;
+import com.sitepark.ies.contentrepository.core.port.Publisher;
+import com.sitepark.ies.contentrepository.core.port.RecycleBin;
+import com.sitepark.ies.contentrepository.core.port.SearchIndex;
+import com.sitepark.ies.contentrepository.core.port.VersioningManager;
+
+class PurgeEntityTest {
+
+ @Test
+ void testAccessDenied() {
+
+ AccessControl accessControl = mock(AccessControl.class);
+ when(accessControl.isEntityRemovable(anyLong())).thenReturn(false);
+
+ var purgeEntity = new PurgeEntity(
+ null,
+ null,
+ null,
+ null,
+ accessControl,
+ null,
+ null,
+ null,
+ null);
+ assertThrows(AccessDenied.class, () -> {
+ purgeEntity.purgeEntity(10L);
+ });
+ }
+
+ @Test
+ void testEntityIsLocked() {
+
+ AccessControl accessControl = mock(AccessControl.class);
+ when(accessControl.isEntityRemovable(anyLong())).thenReturn(true);
+
+ EntityLockManager lockManager = mock(EntityLockManager.class);
+ when(lockManager.getLock(anyLong()))
+ .thenReturn(
+ Optional.of(
+ EntityLock.builder().entity(10L).build()
+ )
+ );
+
+ var purgeEntity = new PurgeEntity(
+ null,
+ lockManager,
+ null,
+ null,
+ accessControl,
+ null,
+ null,
+ null,
+ null);
+ EntityLocked entityLocked = assertThrows(EntityLocked.class, () -> {
+ purgeEntity.purgeEntity(10L);
+ }, "entity should be locked");
+ assertEquals(10L, entityLocked.getLock().getEntity(), "unexpected entity id");
+ }
+
+ @SuppressWarnings("PMD")
+ @Test
+ void testPurge() {
+
+ AccessControl accessControl = mock(AccessControl.class);
+ when(accessControl.isEntityRemovable(anyLong())).thenReturn(true);
+
+ ContentRepository repository = mock(ContentRepository.class);
+ EntityLockManager lockManager = mock(EntityLockManager.class);
+ VersioningManager versioningManager = mock(VersioningManager.class);
+ HistoryManager historyManager = mock(HistoryManager.class);
+
+ RecycleBin recycleBin = mock(RecycleBin.class);
+ SearchIndex searchIndex = mock(SearchIndex.class);
+ MediaRepository mediaRepository = mock(MediaRepository.class);
+ Publisher publisher = mock(Publisher.class);
+
+ PurgeEntity purgeEntity = new PurgeEntity(
+ repository,
+ lockManager,
+ versioningManager,
+ historyManager,
+ accessControl,
+ recycleBin,
+ searchIndex,
+ mediaRepository,
+ publisher);
+ purgeEntity.purgeEntity(10L);
+
+ InOrder inOrder = inOrder(
+ searchIndex,
+ publisher,
+ repository,
+ historyManager,
+ versioningManager,
+ recycleBin,
+ mediaRepository
+ );
+
+ inOrder.verify(searchIndex).remove(10L);
+ inOrder.verify(publisher).depublish(10L);
+ inOrder.verify(repository).removeEntity(10L);
+ inOrder.verify(historyManager).purge(10L);
+ inOrder.verify(versioningManager).removeAllVersions(10L);
+ inOrder.verify(recycleBin).removeByObject(10L);
+ inOrder.verify(mediaRepository).remove(anyList());
+ }
+}