From c4cdff52225a130f9e5664d4052d42625d2d64db Mon Sep 17 00:00:00 2001 From: srosse <stephane.rosse@frentix.com> Date: Fri, 22 Mar 2019 17:00:14 +0100 Subject: [PATCH] OO-3980: allow to move root cur. elements from a curriculum to an other --- .../modules/curriculum/CurriculumService.java | 10 ++ .../manager/CurriculumElementDAO.java | 42 +++++++- .../manager/CurriculumServiceImpl.java | 7 ++ .../restapi/CurriculumElementsWebService.java | 12 ++- .../manager/CurriculumElementDAOTest.java | 101 ++++++++++++++++++ .../CurriculumElementsWebServiceTest.java | 72 +++++++++++++ 6 files changed, 238 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java index 7cf7e87852c..f9b4ce0e901 100644 --- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java +++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java @@ -322,6 +322,16 @@ public interface CurriculumService { */ public CurriculumElement moveCurriculumElement(CurriculumElement elementToMove, CurriculumElement newParent, CurriculumElement siblingBefore); + /** + * Move a root curriculum element from a curriculum to an other. This operation + * is committed asap. + * + * @param rootElement The curriculum element (must be a root one) + * @param curriculum The target curriculum + * @return The update element + */ + public CurriculumElement moveCurriculumElement(CurriculumElement rootElement, Curriculum curriculum); + /** * The list of members of the specified curriculum element. * diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java index d881917928d..5c172fe8d2a 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java @@ -184,6 +184,34 @@ public class CurriculumElementDAO { return dbInstance.getCurrentEntityManager().merge(element); } + public CurriculumElement move(CurriculumElement rootElementToMove, Curriculum newCurriculum) { + CurriculumElementImpl rootElement = (CurriculumElementImpl)rootElementToMove; + List<CurriculumElement> descendants = getDescendants(rootElement);// load the descendants with the old curriculum + descendants.remove(rootElementToMove); + + CurriculumImpl oldCurriculum = loadCurriculumByKey(rootElement); + if(oldCurriculum == null) return rootElement; + oldCurriculum.getRootElements().remove(rootElement); + rootElement.setPosCurriculum(null); + rootElement.setCurriculumParent(null); + rootElement = dbInstance.getCurrentEntityManager().merge(rootElement); + dbInstance.getCurrentEntityManager().merge(oldCurriculum); + + CurriculumImpl curriculum = loadCurriculumByKey(newCurriculum.getKey()); + curriculum.getRootElements().add(rootElement); + rootElement.setCurriculum(curriculum); + rootElement.setPosCurriculum(Long.valueOf(curriculum.getRootElements().size())); + rootElement.setCurriculumParent(curriculum); + rootElement = dbInstance.getCurrentEntityManager().merge(rootElement); + curriculum = dbInstance.getCurrentEntityManager().merge(curriculum); + + for(CurriculumElement descendant:descendants) { + ((CurriculumElementImpl)descendant).setCurriculum(curriculum); + dbInstance.getCurrentEntityManager().merge(descendant); + } + return rootElement; + } + public CurriculumElement move(CurriculumElement elementToMove, CurriculumElement newParentElement, CurriculumElement siblingBefore) { CurriculumElement parentElement = elementToMove.getParent(); CurriculumElementImpl element = (CurriculumElementImpl)elementToMove; @@ -191,14 +219,14 @@ public class CurriculumElementDAO { if(parentElement == null && newParentElement == null) { // reorder curriculum children - CurriculumImpl curriculum = loadCurriculunByKey(element); + CurriculumImpl curriculum = loadCurriculumByKey(element); List<CurriculumElement> rootElements = curriculum.getRootElements(); reorderList(element, rootElements, siblingBefore); dbInstance.getCurrentEntityManager().merge(curriculum); } else if(parentElement == null) { // move from curriculum as root to a curriculum element - CurriculumImpl curriculum = loadCurriculunByKey(element); + CurriculumImpl curriculum = loadCurriculumByKey(element); List<CurriculumElement> rootElements = curriculum.getRootElements(); element.setCurriculumParent(null); rootElements.remove(element); @@ -218,7 +246,7 @@ public class CurriculumElementDAO { element.setParent(null); dbInstance.getCurrentEntityManager().merge(parentElement); - CurriculumImpl curriculum = loadCurriculunByKey(element); + CurriculumImpl curriculum = loadCurriculumByKey(element); element.setCurriculumParent(curriculum); List<CurriculumElement> rootElements = curriculum.getRootElements(); reorderList(element, rootElements, siblingBefore); @@ -291,14 +319,18 @@ public class CurriculumElementDAO { } } - private CurriculumImpl loadCurriculunByKey(CurriculumElement element) { + private CurriculumImpl loadCurriculumByKey(CurriculumElement element) { + return loadCurriculumByKey(element.getCurriculum().getKey()); + } + + private CurriculumImpl loadCurriculumByKey(Long curriculumKey) { StringBuilder sb = new StringBuilder(128); sb.append("select cur from curriculum cur") .append(" where cur.key=:key"); List<CurriculumImpl> curriculums = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), CurriculumImpl.class) - .setParameter("key", element.getCurriculum().getKey()) + .setParameter("key", curriculumKey) .getResultList(); return curriculums == null || curriculums.isEmpty() ? null : curriculums.get(0); } diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java index e66887e70df..a509c633d12 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java @@ -382,6 +382,13 @@ public class CurriculumServiceImpl implements CurriculumService, OrganisationDat return curriculumElementDao.move(elementToMove, newParent, siblingBefore); } + @Override + public CurriculumElement moveCurriculumElement(CurriculumElement rootElement, Curriculum curriculum) { + CurriculumElement element = curriculumElementDao.move(rootElement, curriculum); + dbInstance.commit(); + return element; + } + @Override public List<CurriculumElement> getCurriculumElements(CurriculumRef curriculum, CurriculumElementStatus[] status) { return curriculumElementDao.loadElements(curriculum, status); diff --git a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java index 4acd045a405..f5cc47b7ecc 100644 --- a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java +++ b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java @@ -91,7 +91,7 @@ public class CurriculumElementsWebService { @Autowired private CurriculumElementToTaxonomyLevelDAO curriculumElementToTaxonomyLevelDao; - private final Curriculum curriculum; + private Curriculum curriculum; public CurriculumElementsWebService(Curriculum curriculum) { this.curriculum = curriculum; @@ -244,6 +244,7 @@ public class CurriculumElementsWebService { } boolean move = false; + boolean moveAsCurriculumRoot = false; if(curriculumElement.getKey() == null) { elementToSave = curriculumService.createCurriculumElement(curriculumElement.getIdentifier(), curriculumElement.getDisplayName(), null, curriculumElement.getBeginDate(), curriculumElement.getEndDate(), parentElement, type, @@ -258,6 +259,10 @@ public class CurriculumElementsWebService { if(parentElement != null && elementToSave.getParent() != null && !elementToSave.getParent().getKey().equals(parentElement.getKey())) { move = true; + } else if(parentElement == null && elementToSave.getParent() == null + && (elementToSave.getCurriculum() != null && !elementToSave.getCurriculum().getKey().equals(curriculum.getKey()))) { + // this is a root curriculum element and it get a new curriculum as home + moveAsCurriculumRoot = true; } } @@ -277,6 +282,11 @@ public class CurriculumElementsWebService { curriculumService.moveCurriculumElement(savedElement, parentElement, null); dbInstance.commit(); savedElement = curriculumService.getCurriculumElement(savedElement); + } else if(moveAsCurriculumRoot) { + dbInstance.commit();// make sure all is flushed on the database before such a move + curriculum = curriculumService.getCurriculum(curriculum); + System.out.println(curriculum.getDisplayName()); + savedElement = curriculumService.moveCurriculumElement(savedElement, curriculum); } return savedElement; } diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java index bee234f655b..122907d38a6 100644 --- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java +++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java @@ -603,7 +603,108 @@ public class CurriculumElementDAOTest extends OlatTestCase { Assert.assertEquals(element1_1_3, rootElements.get(1)); } + @Test + public void moveRootCurriculumElement_curriculumToCurriculum() { + Curriculum curriculum = curriculumDao.createAndPersist("cur-start-", "Curriculum to start", "Curriculum", null); + Curriculum targetCurriculum = curriculumDao.createAndPersist("cur-new-home-", "Curriculum as new home", "Curriculum", null); + + CurriculumElement element1 = curriculumElementDao.createCurriculumElement("Element-1", "1. Element", CurriculumElementStatus.active, + null, null, null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_1 = curriculumElementDao.createCurriculumElement("Element-1-1", "1.1. Element", CurriculumElementStatus.active, + null, null, element1, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_2 = curriculumElementDao.createCurriculumElement("Element-1-2", "1.2. Element", CurriculumElementStatus.active, + null, null, element1, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_2_1 = curriculumElementDao.createCurriculumElement("Element-1-2-1", "1.2.1. Element", CurriculumElementStatus.active, + null, null, element1_2, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_2_2 = curriculumElementDao.createCurriculumElement("Element-1-2-2", "1.2.2 Element", CurriculumElementStatus.active, + null, null, element1_2, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + dbInstance.commitAndCloseSession(); + + // move element1 under its new curriculum + curriculumElementDao.move(element1, targetCurriculum); + dbInstance.commitAndCloseSession(); + + // check the source curriculum + CurriculumImpl reloadedCurriculum = (CurriculumImpl)curriculumDao.loadByKey(curriculum.getKey()); + List<CurriculumElement> rootElements = reloadedCurriculum.getRootElements(); + Assert.assertTrue(rootElements.isEmpty()); + + // check the target curriculum + CurriculumImpl reloadedTargetCurriculum = (CurriculumImpl)curriculumDao.loadByKey(targetCurriculum.getKey()); + List<CurriculumElement> targetRootElements = reloadedTargetCurriculum.getRootElements(); + Assert.assertEquals(1, targetRootElements.size()); + Assert.assertTrue(targetRootElements.contains(element1)); + + List<CurriculumElement> movedElements = curriculumElementDao.loadElements(reloadedTargetCurriculum, CurriculumElementStatus.values()); + Assert.assertTrue(movedElements.contains(element1)); + Assert.assertTrue(movedElements.contains(element1_1)); + Assert.assertTrue(movedElements.contains(element1_2)); + Assert.assertTrue(movedElements.contains(element1_2_1)); + Assert.assertTrue(movedElements.contains(element1_2_2)); + } + @Test + public void moveRootCurriculumElement_curriculumToCurriculum_v2() { + Curriculum curriculum = curriculumDao.createAndPersist("cur-start-", "Curriculum to start", "Curriculum", null); + Curriculum targetCurriculum = curriculumDao.createAndPersist("cur-new-home-", "Curriculum as new home", "Curriculum", null); + + CurriculumElement element1 = curriculumElementDao.createCurriculumElement("Element-1", "1. Element", CurriculumElementStatus.active, + null, null, null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_1 = curriculumElementDao.createCurriculumElement("Element-1-1", "1.1. Element", CurriculumElementStatus.active, + null, null, element1, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_2 = curriculumElementDao.createCurriculumElement("Element-1-2", "1.2. Element", CurriculumElementStatus.active, + null, null, element1, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_2_1 = curriculumElementDao.createCurriculumElement("Element-1-2-1", "1.2.1. Element", CurriculumElementStatus.active, + null, null, element1_2, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element1_2_2 = curriculumElementDao.createCurriculumElement("Element-1-2-2", "1.2.2 Element", CurriculumElementStatus.active, + null, null, element1_2, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + + CurriculumElement stayingElement1 = curriculumElementDao.createCurriculumElement("T-Element-1", "1. Element", CurriculumElementStatus.active, + null, null, null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement stayingElement1_1 = curriculumElementDao.createCurriculumElement("T-Element-1-1", "1.1. Element", CurriculumElementStatus.active, + null, null, stayingElement1, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + + CurriculumElement targetElement1 = curriculumElementDao.createCurriculumElement("T-Element-1", "1. Element", CurriculumElementStatus.active, + null, null, null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, targetCurriculum); + CurriculumElement targetElement1_1 = curriculumElementDao.createCurriculumElement("T-Element-1-1", "1.1. Element", CurriculumElementStatus.active, + null, null, targetElement1, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, targetCurriculum); + dbInstance.commitAndCloseSession(); + + // move element1 under its new curriculum + curriculumElementDao.move(element1, targetCurriculum); + dbInstance.commitAndCloseSession(); + + // check the source curriculum + CurriculumImpl reloadedCurriculum = (CurriculumImpl)curriculumDao.loadByKey(curriculum.getKey()); + List<CurriculumElement> rootElements = reloadedCurriculum.getRootElements(); + Assert.assertEquals(1, rootElements.size()); + Assert.assertTrue(rootElements.contains(stayingElement1)); + + // check the target curriculum + CurriculumImpl reloadedTargetCurriculum = (CurriculumImpl)curriculumDao.loadByKey(targetCurriculum.getKey()); + List<CurriculumElement> targetRootElements = reloadedTargetCurriculum.getRootElements(); + Assert.assertEquals(2, targetRootElements.size()); + Assert.assertTrue(targetRootElements.contains(targetElement1)); + Assert.assertTrue(targetRootElements.contains(element1)); + + List<CurriculumElement> targetElements = curriculumElementDao.loadElements(reloadedTargetCurriculum, CurriculumElementStatus.values()); + Assert.assertEquals(7, targetElements.size()); + // current ones + Assert.assertTrue(targetElements.contains(targetElement1)); + Assert.assertTrue(targetElements.contains(targetElement1_1)); + // moved ones + Assert.assertTrue(targetElements.contains(element1)); + Assert.assertTrue(targetElements.contains(element1_1)); + Assert.assertTrue(targetElements.contains(element1_2)); + Assert.assertTrue(targetElements.contains(element1_2_1)); + Assert.assertTrue(targetElements.contains(element1_2_2)); + + List<CurriculumElement> stayingElements = curriculumElementDao.loadElements(curriculum, CurriculumElementStatus.values()); + Assert.assertEquals(2, stayingElements.size()); + // current ones + Assert.assertTrue(stayingElements.contains(stayingElement1)); + Assert.assertTrue(stayingElements.contains(stayingElement1_1)); + } @Test public void getMembersIdentity() { diff --git a/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java b/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java index ab7beeb9883..ac4f330618d 100644 --- a/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java +++ b/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java @@ -57,8 +57,11 @@ import org.olat.modules.curriculum.CurriculumElementType; import org.olat.modules.curriculum.CurriculumLectures; import org.olat.modules.curriculum.CurriculumRoles; import org.olat.modules.curriculum.CurriculumService; +import org.olat.modules.curriculum.manager.CurriculumDAO; +import org.olat.modules.curriculum.manager.CurriculumElementDAO; import org.olat.modules.curriculum.manager.CurriculumElementToTaxonomyLevelDAO; import org.olat.modules.curriculum.model.CurriculumElementRefImpl; +import org.olat.modules.curriculum.model.CurriculumImpl; import org.olat.modules.curriculum.model.CurriculumMember; import org.olat.modules.curriculum.model.SearchMemberParameters; import org.olat.modules.curriculum.restapi.CurriculumElementMemberVO; @@ -92,10 +95,14 @@ public class CurriculumElementsWebServiceTest extends OlatJerseyTestCase { @Autowired private TaxonomyDAO taxonomyDao; @Autowired + private CurriculumDAO curriculumDao; + @Autowired private TaxonomyLevelDAO taxonomyLevelDao; @Autowired private CurriculumService curriculumService; @Autowired + private CurriculumElementDAO curriculumElementDao; + @Autowired private OrganisationService organisationService; @Autowired @@ -321,6 +328,71 @@ public class CurriculumElementsWebServiceTest extends OlatJerseyTestCase { Assert.assertEquals(type, savedElement.getType()); } + + @Test + public void updateCurriculumElement_moveToOtherCurriculum() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Organisation defOrganisation = organisationService.getDefaultOrganisation(); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 25", "REST-p-25-organisation", "", defOrganisation, null); + Curriculum sourceCurriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Source Curriculum", "A source curriculum", organisation); + Curriculum targetCurriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Target Curriculum", "A target curriculum", organisation); + CurriculumElement element1 = curriculumService.createCurriculumElement("Element-25", "Element2 5", CurriculumElementStatus.active, + null, null, null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, sourceCurriculum); + CurriculumElement element1_1 = curriculumService.createCurriculumElement("Element-25-1", "Element 25-1", CurriculumElementStatus.active, + null, null, element1, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, sourceCurriculum); + + dbInstance.commitAndCloseSession(); + + CurriculumElementVO vo = new CurriculumElementVO(); + vo.setKey(element1.getKey()); + vo.setDisplayName("REST updated element"); + vo.setCurriculumKey(targetCurriculum.getKey()); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(targetCurriculum.getKey().toString()) + .path("elements").build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method, vo); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + + // checked VO + CurriculumElementVO savedVo = conn.parse(response, CurriculumElementVO.class); + Assert.assertNotNull(savedVo); + Assert.assertNotNull(savedVo.getKey()); + Assert.assertEquals("REST updated element", savedVo.getDisplayName()); + Assert.assertEquals(targetCurriculum.getKey(), savedVo.getCurriculumKey()); + Assert.assertNull(savedVo.getParentElementKey()); + + // checked database + CurriculumElement savedElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(savedVo.getKey())); + Assert.assertNotNull(savedElement); + Assert.assertEquals(savedVo.getKey(), savedElement.getKey()); + Assert.assertEquals("REST updated element", savedElement.getDisplayName()); + Assert.assertEquals(targetCurriculum, savedElement.getCurriculum()); + + // check the source curriculum (low level to make sure the position are rights) + CurriculumImpl reloadedCurriculum = (CurriculumImpl)curriculumDao.loadByKey(sourceCurriculum.getKey()); + List<CurriculumElement> rootElements = reloadedCurriculum.getRootElements(); + Assert.assertTrue(rootElements.isEmpty()); + + // check the target curriculum (low level to make sure the position are rights) + CurriculumImpl reloadedTargetCurriculum = (CurriculumImpl)curriculumDao.loadByKey(targetCurriculum.getKey()); + List<CurriculumElement> targetRootElements = reloadedTargetCurriculum.getRootElements(); + Assert.assertEquals(1, targetRootElements.size()); + Assert.assertTrue(targetRootElements.contains(element1)); + + List<CurriculumElement> movedElements = curriculumElementDao.loadElements(reloadedTargetCurriculum, CurriculumElementStatus.values()); + Assert.assertTrue(movedElements.contains(element1)); + Assert.assertTrue(movedElements.contains(element1_1)); + + List<CurriculumElement> sourceElements = curriculumElementDao.loadElements(sourceCurriculum, CurriculumElementStatus.values()); + Assert.assertTrue(sourceElements.isEmpty()); + } + /** * Set the parent element key as itself. * -- GitLab