diff --git a/Source/Plugins/Core/com.equella.base/src/com/tle/beans/hierarchy/HierarchyTopicKeyResource.java b/Source/Plugins/Core/com.equella.base/src/com/tle/beans/hierarchy/HierarchyTopicKeyResource.java index cd5016f32e..448ff8dcdb 100644 --- a/Source/Plugins/Core/com.equella.base/src/com/tle/beans/hierarchy/HierarchyTopicKeyResource.java +++ b/Source/Plugins/Core/com.equella.base/src/com/tle/beans/hierarchy/HierarchyTopicKeyResource.java @@ -29,6 +29,7 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.NamedQuery; import javax.persistence.Table; import org.hibernate.annotations.AttributeAccessor; import org.hibernate.annotations.Index; @@ -36,6 +37,10 @@ @Entity @Table(name = "hierarchy_topic_key_resources") @AttributeAccessor("field") +@NamedQuery( + name = "getByItemUuidAndInstitution", + query = + "FROM HierarchyTopicKeyResource t WHERE t.itemUuid = :itemUuid AND t.institution = :institution") public class HierarchyTopicKeyResource { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/Source/Plugins/Core/com.equella.core/plugin-jpf.xml b/Source/Plugins/Core/com.equella.core/plugin-jpf.xml index 356334468f..a8c5aea2cc 100644 --- a/Source/Plugins/Core/com.equella.core/plugin-jpf.xml +++ b/Source/Plugins/Core/com.equella.core/plugin-jpf.xml @@ -1405,12 +1405,6 @@ - - - - - - diff --git a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyDao.java b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyDao.java index b7a7e6377e..a3d5b3bc77 100644 --- a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyDao.java +++ b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyDao.java @@ -45,7 +45,7 @@ public interface HierarchyDao extends AbstractTreeDao { HierarchyTopic findByUuid(String uuid, Institution institution); /** Save the given key resource entity into DB */ - void saveKeyResources(HierarchyTopicKeyResource entity); + void saveKeyResource(HierarchyTopicKeyResource entity); /** Get all key resources for a given topic in a given institution. */ List getKeyResources( @@ -55,6 +55,10 @@ List getKeyResources( List getKeyResources( String itemUuid, int itemVersion, Institution institution); + /** Get all key resources for a given item UUID and institution. */ + List getKeyResourcesByItemUuid( + String itemUuid, Institution institution); + /** Get a key resource for a given item in a given topic. */ Optional getKeyResource( String legacyHierarchyCompoundUuid, @@ -65,6 +69,9 @@ Optional getKeyResource( /** Get all key resources for a given institution. */ List getAllKeyResources(Institution institution); + /** Delete key resource by a given entity. */ + void deleteKeyResource(HierarchyTopicKeyResource entity); + /** Delete a key resource for a given item in a given topic. */ void deleteKeyResource(String topicId, String itemUuid, int itemVersion); diff --git a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyService.java b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyService.java index 4d5767298a..f6f39d286e 100644 --- a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyService.java +++ b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/HierarchyService.java @@ -112,6 +112,9 @@ FreeTextBooleanQuery getSearchClause( /** Get all key resources for a given hierarchy compound UUID. */ List getKeyResources(HierarchyCompoundUuid compoundUuid); + /** Get all key resources for a given item UUID. */ + List getKeyResources(String itemUuid); + /** Get all key resources and convert to Item for a given hierarchy compound UUID. */ List getKeyResourceItems(HierarchyCompoundUuid compoundUuid); @@ -161,8 +164,15 @@ void updateKeyResources( void delete(HierarchyTopic topic); + /** Delete key resource by the given key resource entity. */ + void deleteKeyResource(HierarchyTopicKeyResource keyResource); + + /** Delete key resource by the given itemId from current institution. */ + void deleteKeyResources(ItemKey itemId); + void deleteKeyResources(Item item); + /** Delete key resource by the given itemId from the given hierarchy. */ void deleteKeyResources(HierarchyCompoundUuid hierarchyCompoundUuid, ItemKey itemId); void removeDeletedItemReference(String uuid, int version); diff --git a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/convert/KeyResourceConverter.java b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/convert/KeyResourceConverter.java index 7d06b6f663..33d9fc2505 100644 --- a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/convert/KeyResourceConverter.java +++ b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/convert/KeyResourceConverter.java @@ -66,11 +66,11 @@ public void doImport(TemporaryFileHandle staging, Institution institution, Conve entries.forEach( entry -> { - HierarchyTopicKeyResource keyResources = + HierarchyTopicKeyResource keyResource = xmlHelper.readXmlFile(keyResourceImportFolder, entry); - keyResources.setInstitution(institution); + keyResource.setInstitution(institution); - hierarchyDao.saveKeyResources(keyResources); + hierarchyDao.saveKeyResource(keyResource); hierarchyDao.flush(); hierarchyDao.clear(); }); diff --git a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyDaoImpl.java b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyDaoImpl.java index 2074590486..4850ed5845 100644 --- a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyDaoImpl.java +++ b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyDaoImpl.java @@ -214,10 +214,15 @@ public void deleteAllKeyResources(Institution institution) { } @Override - public void saveKeyResources(HierarchyTopicKeyResource entity) { + public void saveKeyResource(HierarchyTopicKeyResource entity) { getHibernateTemplate().save(entity); } + @Override + public void deleteKeyResource(HierarchyTopicKeyResource entity) { + getHibernateTemplate().delete(entity); + } + @Override public List getKeyResources( String dynamicHierarchyId, Institution institution) { @@ -259,6 +264,21 @@ public List getKeyResources( return keyResources; } + @Override + public List getKeyResourcesByItemUuid( + String itemUuid, Institution institution) { + return (List) + getHibernateTemplate() + .execute( + (Session session) -> { + return session + .getNamedQuery("getByItemUuidAndInstitution") + .setParameter("itemUuid", itemUuid) + .setParameter("institution", CurrentInstitution.get()) + .list(); + }); + } + @Override public List getAllKeyResources(Institution institution) { List keyResources = diff --git a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyServiceImpl.java b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyServiceImpl.java index 5a7417f498..575263050b 100644 --- a/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyServiceImpl.java +++ b/Source/Plugins/Core/com.equella.core/src/com/tle/core/hierarchy/impl/HierarchyServiceImpl.java @@ -35,6 +35,7 @@ import com.tle.beans.hierarchy.HierarchyTreeNode; import com.tle.beans.item.Item; import com.tle.beans.item.ItemId; +import com.tle.beans.item.ItemIdKey; import com.tle.beans.item.ItemKey; import com.tle.common.Check; import com.tle.common.beans.exception.ValidationError; @@ -184,7 +185,7 @@ public void addKeyResource(HierarchyCompoundUuid compoundUuid, ItemKey itemId) { newKeyResources.setItemVersion(itemId.getVersion()); newKeyResources.setInstitution(CurrentInstitution.get()); newKeyResources.setDateCreated(new Date()); - dao.saveKeyResources(newKeyResources); + dao.saveKeyResource(newKeyResources); } /** Check whether the given item is a key resource of the given hierarchy topic. */ @@ -198,6 +199,18 @@ public boolean hasKeyResource(HierarchyCompoundUuid compoundUuid, ItemKey itemId return keyResource.isPresent(); } + @Override + @Transactional + public void deleteKeyResource(HierarchyTopicKeyResource keyResource) { + dao.deleteKeyResource(keyResource); + } + + @Override + @Transactional + public void deleteKeyResources(ItemKey itemId) { + dao.deleteKeyResources(itemId.getUuid(), itemId.getVersion(), CurrentInstitution.get()); + } + @Override @Transactional public void deleteKeyResources(Item item) { @@ -681,9 +694,31 @@ public XStream getXStream() { @Override public void itemDeletedEvent(ItemDeletedEvent event) { - Item item = new Item(); - item.setId(event.getKey()); - // TODO: OEQ-2051 Delete related key resources + // When an Item delete event is published, a key resource should be deleted when: + // * the referenced Item version is exactly the same as the Item to be deleted, or + // * pointing to the latest version (which is represented by 0) and there are not any more + // versions of that Item. + // In the second case, please note that the Item is NOT removed until all the listeners for Item + // delete event complete their tasks. + // This means when there is only one version of that Item remaining, the pointing to the latest + // version key resource should be removed as well. + final int lastItemFlag = 1; + + ItemIdKey itemIdKey = event.getItemId(); + String deletedItemUuid = itemIdKey.getUuid(); + int deletedItemVersion = itemIdKey.getVersion(); + + List allItems = itemService.getVersionDetails(deletedItemUuid); + + getKeyResources(deletedItemUuid) + .forEach( + keyResource -> { + int keyResourceItemVersion = keyResource.getItemVersion(); + if (keyResourceItemVersion == deletedItemVersion + || (keyResourceItemVersion == 0 && allItems.size() == lastItemFlag)) { + deleteKeyResource(keyResource); + } + }); } @Override @@ -722,6 +757,11 @@ public List getKeyResources(HierarchyCompoundUuid com return dao.getKeyResources(compoundUuid.buildString(true), CurrentInstitution.get()); } + @Override + public List getKeyResources(String itemUuid) { + return dao.getKeyResourcesByItemUuid(itemUuid, CurrentInstitution.get()); + } + @Override public List getKeyResourceItems(HierarchyCompoundUuid compoundUuid) { // HierarchyTopicKeyResource. diff --git a/Source/Plugins/Core/com.equella.core/src/com/tle/core/scheduler/standard/task/RemoveInvalidDynamicKeyResource.java b/Source/Plugins/Core/com.equella.core/src/com/tle/core/scheduler/standard/task/RemoveInvalidDynamicKeyResource.java deleted file mode 100644 index 531915d107..0000000000 --- a/Source/Plugins/Core/com.equella.core/src/com/tle/core/scheduler/standard/task/RemoveInvalidDynamicKeyResource.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to The Apereo Foundation under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * The Apereo Foundation licenses this file to you under the Apache License, - * Version 2.0, (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.tle.core.scheduler.standard.task; - -import com.google.inject.Inject; -import com.tle.beans.Institution; -import com.tle.common.institution.CurrentInstitution; -import com.tle.core.guice.Bind; -import com.tle.core.hierarchy.HierarchyDao; -import com.tle.core.item.dao.ItemDao; -import com.tle.core.scheduler.ScheduledTask; -import javax.inject.Singleton; -import org.springframework.transaction.annotation.Transactional; - -/** - * Scheduled task running weekly to remove all the dynamic key resources that reference to deleted - * Items from the current Institution. - */ -@Bind -@Singleton -public class RemoveInvalidDynamicKeyResource implements ScheduledTask { - @Inject private ItemDao itemDao; - @Inject private HierarchyDao hierarchyDao; - - @Transactional - @Override - public void execute() { - Institution currentInstitution = CurrentInstitution.get(); - - hierarchyDao - .getAllKeyResources(currentInstitution) - .forEach( - keyResource -> { - String itemUuid = keyResource.getItemUuid(); - int itemVersion = keyResource.getItemVersion(); - if (itemDao.getItemInfo(itemUuid, itemVersion) == null) { - hierarchyDao.deleteKeyResources(itemUuid, itemVersion, currentInstitution); - } - }); - } -}