diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java index 0aabbba16..5fce2094a 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java @@ -1,22 +1,22 @@ - /** - * This file is part of the Meeds project (https://meeds.io/). - * - * Copyright (C) 2020 - 2024 Meeds Association contact@meeds.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ +/** +* This file is part of the Meeds project (https://meeds.io/). +* +* Copyright (C) 2020 - 2024 Meeds Association contact@meeds.io +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 3 of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ package org.exoplatform.wiki.jpa.dao; import java.util.List; @@ -28,18 +28,16 @@ import jakarta.persistence.NoResultException; import jakarta.persistence.TypedQuery; -/** - * Created by The eXo Platform SAS - * Author : eXoPlatform - * exo@exoplatform.com - * Jun 24, 2015 - */ public class DraftPageDAO extends WikiBaseDAO { + private static final String TARGET_PAGE_ID_PARAM = "targetPageId"; + public DraftPageEntity findDraftPageByName(String draftPageName) { - TypedQuery query = getEntityManager().createNamedQuery("wikiDraftPage.findDraftPageByName", DraftPageEntity.class) - .setMaxResults(1) - .setParameter("draftPageName", draftPageName); + TypedQuery query = getEntityManager() + .createNamedQuery("wikiDraftPage.findDraftPageByName", + DraftPageEntity.class) + .setMaxResults(1) + .setParameter("draftPageName", draftPageName); try { return query.getSingleResult(); @@ -49,38 +47,48 @@ public DraftPageEntity findDraftPageByName(String draftPageName) { } public List findDraftPagesByTargetPage(long targetPageId) { - TypedQuery query = getEntityManager().createNamedQuery("wikiDraftPage.findDraftPageByTargetPage", DraftPageEntity.class) - .setParameter("targetPageId", targetPageId); - return query.getResultList(); + return getEntityManager().createNamedQuery("wikiDraftPage.findDraftPageByTargetPage", DraftPageEntity.class) + .setParameter(TARGET_PAGE_ID_PARAM, targetPageId) + .getResultList(); } public List findDraftPagesByParentPage(long parentPageId) { - TypedQuery query = getEntityManager().createNamedQuery("wikiDraftPage.findDraftPagesByParentPage", DraftPageEntity.class) - .setParameter("parentPageId", parentPageId); + TypedQuery query = getEntityManager() + .createNamedQuery("wikiDraftPage.findDraftPagesByParentPage", + DraftPageEntity.class) + .setParameter("parentPageId", parentPageId); return query.getResultList(); } @ExoTransactional public void deleteDraftPagesByTargetPage(long targetPageId) { - List draftPages = findDraftPagesByTargetPage(targetPageId); - for (DraftPageEntity draftPage: draftPages) { + for (DraftPageEntity draftPage : draftPages) { delete(draftPage); } + } + @ExoTransactional + public void deleteDraftPagesByParentPage(long targetPageId) { + List draftPages = findDraftPagesByParentPage(targetPageId); + for (DraftPageEntity draftPage : draftPages) { + delete(draftPage); + } } @ExoTransactional public void deleteDraftPagesByName(String draftName) { DraftPageEntity draftPage = findDraftPageByName(draftName); - if(draftPage != null) { + if (draftPage != null) { delete(draftPage); } } public DraftPageEntity findLatestDraftPageByTargetPage(Long targetPageId) { - TypedQuery query = getEntityManager().createNamedQuery("wikiDraftPage.findLatestDraftPageByTargetPage", DraftPageEntity.class) - .setParameter("targetPageId", targetPageId); + TypedQuery query = getEntityManager() + .createNamedQuery("wikiDraftPage.findLatestDraftPageByTargetPage", + DraftPageEntity.class) + .setParameter(TARGET_PAGE_ID_PARAM, targetPageId); try { query.setMaxResults(1); @@ -101,7 +109,7 @@ public DraftPageEntity findLatestDraftPageByTargetPageAndLang(Long targetPageId, TypedQuery query = getEntityManager().createNamedQuery("wikiDraftPage.findLatestDraftPageByTargetPageAndLang", DraftPageEntity.class) - .setParameter("targetPageId", targetPageId) + .setParameter(TARGET_PAGE_ID_PARAM, targetPageId) .setParameter("lang", lang); query.setMaxResults(1); try { diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/EmotionIconDAO.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/EmotionIconDAO.java index 065bbe737..628a21d92 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/EmotionIconDAO.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/EmotionIconDAO.java @@ -16,7 +16,6 @@ */ package org.exoplatform.wiki.jpa.dao; -import org.exoplatform.commons.persistence.impl.GenericDAOJPAImpl; import org.exoplatform.wiki.jpa.entity.EmotionIconEntity; import jakarta.persistence.NoResultException; diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageDAO.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageDAO.java index 7fdb76a52..29bac358d 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageDAO.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageDAO.java @@ -1,89 +1,116 @@ - /** - * This file is part of the Meeds project (https://meeds.io/). - * - * Copyright (C) 2020 - 2024 Meeds Association contact@meeds.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ +/** +* This file is part of the Meeds project (https://meeds.io/). +* +* Copyright (C) 2020 - 2024 Meeds Association contact@meeds.io +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 3 of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ package org.exoplatform.wiki.jpa.dao; +import java.util.Arrays; import java.util.List; -import jakarta.persistence.NonUniqueResultException; -import jakarta.persistence.TypedQuery; +import org.apache.commons.collections.CollectionUtils; import org.exoplatform.wiki.jpa.entity.PageEntity; +import org.exoplatform.wiki.jpa.entity.WikiEntity; import org.exoplatform.wiki.model.WikiType; +import jakarta.persistence.NonUniqueResultException; +import jakarta.persistence.TypedQuery; +import jakarta.transaction.Transactional; + /** * Created by The eXo Platform SAS Author : eXoPlatform exo@exoplatform.com Jun * 24, 2015 */ public class PageDAO extends WikiBaseDAO { + private static final String TYPE_PARAM = "type"; + + private static final String OWNER_PARAM = "owner"; + + private DraftPageDAO draftPageDAO; + + private PageMoveDAO pageMoveDAO; + + private PageVersionDAO pageVersionDAO; + + public PageDAO(DraftPageDAO draftPageDAO, PageMoveDAO pageMoveDAO, PageVersionDAO pageVersionDAO) { + this.draftPageDAO = draftPageDAO; + this.pageMoveDAO = pageMoveDAO; + this.pageVersionDAO = pageVersionDAO; + } + public List getAllPagesOfWiki(String wikiType, String wikiOwner) { - //We need to add the first "/" on the wiki owner if it's wiki group - if (wikiType.toUpperCase().equals(WikiType.GROUP.name())) wikiOwner = validateGroupWikiOwner(wikiOwner); + // We need to add the first "/" on the wiki owner if it's wiki group + if (wikiType.toUpperCase().equals(WikiType.GROUP.name())) + wikiOwner = validateGroupWikiOwner(wikiOwner); TypedQuery query = getEntityManager().createNamedQuery("wikiPage.getAllPagesOfWiki", PageEntity.class) - .setParameter("type", wikiType) - .setParameter("owner", wikiOwner); + .setParameter(TYPE_PARAM, wikiType) + .setParameter(OWNER_PARAM, wikiOwner); return query.getResultList(); } public List getPagesOfWiki(String wikiType, String wikiOwner, boolean deleted) { - //We need to add the first "/" on the wiki owner if it's wiki group - if (wikiType.toUpperCase().equals(WikiType.GROUP.name())) wikiOwner = validateGroupWikiOwner(wikiOwner); + // We need to add the first "/" on the wiki owner if it's wiki group + if (wikiType.toUpperCase().equals(WikiType.GROUP.name())) + wikiOwner = validateGroupWikiOwner(wikiOwner); TypedQuery query = getEntityManager().createNamedQuery("wikiPage.getPagesOfWiki", PageEntity.class) - .setParameter("type", wikiType) - .setParameter("owner", wikiOwner) - .setParameter("deleted", deleted); + .setParameter(TYPE_PARAM, wikiType) + .setParameter(OWNER_PARAM, wikiOwner) + .setParameter("deleted", deleted); return query.getResultList(); } public PageEntity getPageOfWikiByName(String wikiType, String wikiOwner, String pageName) { - //We need to add the first "/" on the wiki owner if it's wiki group - if (WikiType.GROUP.isSame(wikiType)) wikiOwner = validateGroupWikiOwner(wikiOwner); + // We need to add the first "/" on the wiki owner if it's wiki group + if (WikiType.GROUP.isSame(wikiType)) + wikiOwner = validateGroupWikiOwner(wikiOwner); PageEntity pageEntity = null; TypedQuery query = getEntityManager().createNamedQuery("wikiPage.getPageOfWikiByName", PageEntity.class) - .setParameter("name", pageName) - .setParameter("type", wikiType) - .setParameter("owner", wikiOwner); - - // We don't use "query.getSingleResult()" because there is no good solution to have a case sensitive comparison - // on the page name between all supported databases (I look at you MySQL). Having several pages in a wiki - // with the same name with different cases is allowed functionally speaking, so we post-process results in Java + .setParameter("name", pageName) + .setParameter(TYPE_PARAM, wikiType) + .setParameter(OWNER_PARAM, wikiOwner); + + // We don't use "query.getSingleResult()" because there is no good solution + // to have a case sensitive comparison + // on the page name between all supported databases (I look at you MySQL). + // Having several pages in a wiki + // with the same name with different cases is allowed functionally speaking, + // so we post-process results in Java // to be sure to have a case sensitive match in a database agnostic way List results = query.getResultList(); - if(results != null) { + if (results != null) { for (PageEntity pageEntityResult : results) { // compare names with case sensitivity if (pageEntityResult.getName().equals(pageName)) { if (pageEntity == null) { pageEntity = pageEntityResult; } else { - throw new NonUniqueResultException("More than 1 page with the name " + pageName - + " in the wiki " + wikiType + ":" + wikiOwner + " has been returned"); + throw new NonUniqueResultException("More than 1 page with the name " + pageName + " in the wiki " + wikiType + ":" + + wikiOwner + " has been returned"); } } } @@ -93,11 +120,17 @@ public PageEntity getPageOfWikiByName(String wikiType, String wikiOwner, String } public List getChildrenPages(PageEntity page) { - TypedQuery query = getEntityManager().createNamedQuery("wikiPage.getChildrenPages", PageEntity.class) - .setParameter("id", page.getId()); - return query.getResultList(); + return getEntityManager().createNamedQuery("wikiPage.getChildrenPages", PageEntity.class) + .setParameter("id", page.getId()) + .getResultList(); + } + public List getAllChildrenPages(PageEntity page) { + return getEntityManager().createNamedQuery("wikiPage.getAllChildrenPages", PageEntity.class) + .setParameter("id", page.getId()) + .getResultList(); + } public List findAllIds(int offset, int limit) { TypedQuery query = getEntityManager().createNamedQuery("wikiPage.getAllIds", Long.class); @@ -115,17 +148,95 @@ public Long countAllIds() { } public List findAllBySyntax(String syntax, int offset, int limit) { - return getEntityManager().createNamedQuery("wikiPage.getAllPagesBySyntax") - .setParameter("syntax", syntax) - .setFirstResult(offset) - .setMaxResults(limit) - .getResultList(); + return getEntityManager().createNamedQuery("wikiPage.getAllPagesBySyntax", PageEntity.class) + .setParameter("syntax", syntax) + .setFirstResult(offset) + .setMaxResults(limit) + .getResultList(); + } + + public List getRelatedPages(long pageId) { + return getEntityManager().createNamedQuery("wikiPage.getRelatedPages", PageEntity.class) + .setParameter("pageId", pageId) + .getResultList(); } public Long countPageChildrenById(Long pageId) { return (Long) getEntityManager().createNamedQuery("wikiPage.countPageChildrenById") - .setParameter("id", pageId) - .getSingleResult(); + .setParameter("id", pageId) + .getSingleResult(); + } + + @Override + public void deleteAll(List entities) { + entities = entities.stream().sorted((p1, p2) -> { + // Necessary to use this in order to safely convert Long comparaison to + // int + if (p2.getId() > p1.getId()) { + return 1; + } else if (p2.getId() < p1.getId()) { + return -1; + } else { + return 0; + } + }).toList(); + super.deleteAll(entities); + } + + @Override + public void delete(PageEntity entity) { + List children = getAllChildrenPages(entity); + if (CollectionUtils.isNotEmpty(children)) { + Arrays.stream(children.toArray(PageEntity[]::new)) + .forEach(this::delete); + } + entity.setChildren(null); + + updatePageDependencies(entity); + + entity = refreshEntity(entity); + if (entity != null) { + super.delete(entity); + } + } + + @Transactional + protected PageEntity refreshEntity(PageEntity entity) { + entity = find(entity.getId()); + if (entity != null) { + getEntityManager().refresh(entity); + } + return entity; + } + + @Transactional + protected void updatePageDependencies(PageEntity entity) { + List relatedPages = getRelatedPages(entity.getId()); + if (CollectionUtils.isNotEmpty(relatedPages)) { + relatedPages.forEach(p -> { + if (CollectionUtils.isNotEmpty(p.getRelatedPages()) + && p.getRelatedPages().removeIf(page -> page.getId() == entity.getId())) { + update(p); + } + }); + } + entity.setRelatedPages(null); + + draftPageDAO.deleteDraftPagesByTargetPage(entity.getId()); + draftPageDAO.deleteDraftPagesByParentPage(entity.getId()); + entity.setDrafts(null); + + pageVersionDAO.deletePageVersions(entity.getId()); + entity.setVersions(null); + + pageMoveDAO.deletePageMoves(entity.getId()); + entity.setMoves(null); + + WikiEntity wiki = entity.getWiki(); + if (wiki.getWikiHome() != null && wiki.getWikiHome().getId() == entity.getId()) { + wiki.setWikiHome(null); + } + entity.setParentPage(null); } } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageMoveDAO.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageMoveDAO.java index 07e6fd094..4b50bbe7e 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageMoveDAO.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageMoveDAO.java @@ -18,24 +18,43 @@ */ package org.exoplatform.wiki.jpa.dao; +import java.util.List; + +import org.apache.commons.collections4.CollectionUtils; + import org.exoplatform.wiki.jpa.entity.PageMoveEntity; import org.exoplatform.wiki.model.WikiType; import jakarta.persistence.TypedQuery; -import java.util.List; -public class PageMoveDAO extends WikiBaseDAO { +public class PageMoveDAO extends WikiBaseDAO { + + private static final String PAGE_ID_PARAM = "pageId"; public List findInPageMoves(String wikiType, String wikiOwner, String pageName) { - //We need to add the first "/" on the wiki owner if it's wiki group - if (wikiType.toUpperCase().equals(WikiType.GROUP.name())) wikiOwner = validateGroupWikiOwner(wikiOwner); + // We need to add the first "/" on the wiki owner if it's wiki group + if (wikiType.toUpperCase().equals(WikiType.GROUP.name())) + wikiOwner = validateGroupWikiOwner(wikiOwner); TypedQuery query = getEntityManager().createNamedQuery("wikiPageMove.getPreviousPage", PageMoveEntity.class) - .setParameter("wikiType", wikiType) - .setParameter("wikiOwner", wikiOwner) - .setParameter("pageName", pageName); + .setParameter("wikiType", wikiType) + .setParameter("wikiOwner", wikiOwner) + .setParameter("pageName", pageName); return query.getResultList(); } + public List findMovesByPage(Long pageId) { + return getEntityManager().createNamedQuery("wikiPageMove.findMovesByPage", PageMoveEntity.class) + .setParameter(PAGE_ID_PARAM, pageId) + .getResultList(); + } + + public void deletePageMoves(long pageId) { + List moves = findMovesByPage(pageId); + if (CollectionUtils.isNotEmpty(moves)) { + moves.forEach(this::delete); + } + } + } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageVersionDAO.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageVersionDAO.java index dfcfc6134..786842883 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageVersionDAO.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/PageVersionDAO.java @@ -16,32 +16,37 @@ */ package org.exoplatform.wiki.jpa.dao; -import org.exoplatform.commons.persistence.impl.GenericDAOJPAImpl; -import org.exoplatform.wiki.jpa.entity.PageEntity; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.collections4.CollectionUtils; + import org.exoplatform.wiki.jpa.entity.PageVersionEntity; import jakarta.persistence.NoResultException; -import jakarta.persistence.Query; import jakarta.persistence.TypedQuery; -import java.util.Collections; -import java.util.List; public class PageVersionDAO extends WikiBaseDAO { - public Long getLastversionNumberOfPage(Long pageId) { - Query query = getEntityManager().createNamedQuery("wikiPageVersion.getLastversionNumberOfPage") - .setParameter("pageId", pageId); - try { - return (Long) query.getSingleResult(); - } catch (NoResultException e) { - return null; - } - } + private static final String PAGE_ID_PARAM = "pageId"; + + public Long getLastversionNumberOfPage(Long pageId) { + TypedQuery query = getEntityManager().createNamedQuery("wikiPageVersion.getLastversionNumberOfPage", Long.class) + .setParameter(PAGE_ID_PARAM, pageId); + + try { + return query.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } public PageVersionEntity getPageversionByPageIdAndVersion(Long pageId, Long versionNumber) { - TypedQuery query = getEntityManager().createNamedQuery("wikiPageVersion.getPageversionByPageIdAndVersion", PageVersionEntity.class) - .setParameter("pageId", pageId) - .setParameter("versionNumber", versionNumber); + TypedQuery query = getEntityManager() + .createNamedQuery("wikiPageVersion.getPageversionByPageIdAndVersion", + PageVersionEntity.class) + .setParameter(PAGE_ID_PARAM, pageId) + .setParameter("versionNumber", versionNumber); try { return query.getSingleResult(); @@ -51,24 +56,24 @@ public PageVersionEntity getPageversionByPageIdAndVersion(Long pageId, Long vers } public List findAllVersionsBySyntax(String syntax, int offset, int limit) { - return getEntityManager().createNamedQuery("wikiPageVersion.getAllPagesVersionsBySyntax") - .setParameter("syntax", syntax) - .setFirstResult(offset) - .setMaxResults(limit) - .getResultList(); + return getEntityManager().createNamedQuery("wikiPageVersion.getAllPagesVersionsBySyntax", PageVersionEntity.class) + .setParameter("syntax", syntax) + .setFirstResult(offset) + .setMaxResults(limit) + .getResultList(); } public Long countPagesVersionsBySyntax(String syntax) { return (Long) getEntityManager().createNamedQuery("wikiPageVersion.countAllPagesVersionsBySyntax") - .setParameter("syntax", syntax) - .getSingleResult(); + .setParameter("syntax", syntax) + .getSingleResult(); } public List findPageVersionsByPageIdAndLang(Long pageId, String lang) { TypedQuery query = getEntityManager() .createNamedQuery("wikiPageVersion.getPageVersionsByPageIdAndLang", PageVersionEntity.class) - .setParameter("pageId", pageId) + .setParameter(PAGE_ID_PARAM, pageId) .setParameter("lang", lang); try { return query.getResultList(); @@ -76,12 +81,12 @@ public List findPageVersionsByPageIdAndLang(Long pageId, Stri return Collections.emptyList(); } } - + public PageVersionEntity findLatestVersionByPageIdAndLang(Long pageId, String lang) { TypedQuery query = getEntityManager() .createNamedQuery("wikiPageVersion.getLatestPageVersionsByPageIdAndLang", PageVersionEntity.class) - .setParameter("pageId", pageId) + .setParameter(PAGE_ID_PARAM, pageId) .setParameter("lang", lang); query.setMaxResults(1); try { @@ -90,15 +95,24 @@ public PageVersionEntity findLatestVersionByPageIdAndLang(Long pageId, String la return null; } } - + public List findPageAvailableTranslationLanguages(Long pageId) { - Query query = getEntityManager().createNamedQuery("wikiPageVersion.getPageAvailableTranslationLanguages") - .setParameter("pageId", pageId); - try { - return query.getResultList(); - } catch (NoResultException e) { - return Collections.emptyList(); + return getEntityManager().createNamedQuery("wikiPageVersion.getPageAvailableTranslationLanguages", String.class) + .setParameter(PAGE_ID_PARAM, pageId) + .getResultList(); + } + + public List findVersionsByPage(Long pageId) { + return getEntityManager().createNamedQuery("wikiPageVersion.findVersionsByPage", PageVersionEntity.class) + .setParameter(PAGE_ID_PARAM, pageId) + .getResultList(); + } + + public void deletePageVersions(long pageId) { + List versions = findVersionsByPage(pageId); + if (CollectionUtils.isNotEmpty(versions)) { + versions.forEach(this::delete); } } - + } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/WikiDAO.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/WikiDAO.java index 7798e93e7..5989d4bde 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/WikiDAO.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/WikiDAO.java @@ -24,6 +24,7 @@ import jakarta.persistence.NoResultException; import jakarta.persistence.TypedQuery; +import org.exoplatform.commons.api.persistence.ExoTransactional; import org.exoplatform.wiki.jpa.entity.WikiEntity; import org.exoplatform.wiki.model.WikiType; @@ -33,8 +34,17 @@ */ public class WikiDAO extends WikiBaseDAO { + private PageDAO pageDAO; + + public WikiDAO(PageDAO pageDAO) { + this.pageDAO = pageDAO; + } + public List findAllIds(int offset, int limit) { - return getEntityManager().createNamedQuery("wiki.getAllIds").setFirstResult(offset).setMaxResults(limit).getResultList(); + return getEntityManager().createNamedQuery("wiki.getAllIds", Long.class) + .setFirstResult(offset) + .setMaxResults(limit) + .getResultList(); } public WikiEntity getWikiByTypeAndOwner(String wikiType, String wikiOwner) { @@ -60,4 +70,14 @@ public List getWikisByType(String wikiType) { return query.getResultList(); } + @Override + @ExoTransactional + public void delete(WikiEntity entity) { + if (entity.getWikiHome() != null) { + pageDAO.delete(entity.getWikiHome()); + } + entity.setWikiHome(null); + super.delete(entity); + } + } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java index 4f38fdb59..e94d1f670 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java @@ -19,9 +19,27 @@ package org.exoplatform.wiki.jpa.entity; -import java.util.*; - -import jakarta.persistence.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.CollectionTable; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.NamedQuery; +import jakarta.persistence.OneToMany; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; @@ -39,6 +57,8 @@ @NamedQuery(name = "wikiPage.getAllPagesOfWiki", query = "SELECT p FROM WikiPageEntity p JOIN p.wiki w WHERE w.type = :type AND w.owner = :owner") @NamedQuery(name = "wikiPage.getPagesOfWiki", query = "SELECT p FROM WikiPageEntity p JOIN p.wiki w WHERE w.type = :type AND w.owner = :owner AND p.deleted = :deleted") @NamedQuery(name = "wikiPage.getChildrenPages", query = "SELECT p FROM WikiPageEntity p WHERE p.parentPage.id = :id AND p.deleted = false ORDER BY p.name") +@NamedQuery(name = "wikiPage.getAllChildrenPages", query = "SELECT p FROM WikiPageEntity p WHERE p.parentPage.id = :id ORDER BY p.name") +@NamedQuery(name = "wikiPage.getRelatedPages", query = "SELECT p FROM WikiPageEntity p INNER JOIN p.relatedPages r where r.id = :pageId") @NamedQuery(name = "wikiPage.getAllPagesBySyntax", query = "SELECT p FROM WikiPageEntity p WHERE p.syntax = :syntax OR p.syntax IS NULL ORDER BY p.updatedDate DESC") @NamedQuery(name = "wikiPage.countPageChildrenById", query = "SELECT COUNT(*) FROM WikiPageEntity p WHERE p.parentPage.id = :id AND p.deleted = false") @Data @@ -61,14 +81,23 @@ public class PageEntity extends BasePageEntity { @EqualsAndHashCode.Exclude private PageEntity parentPage; - @OneToMany(mappedBy = "page", cascade = CascadeType.ALL) + @OneToMany(mappedBy = "parentPage") + @EqualsAndHashCode.Exclude + private List children; + + @OneToMany(mappedBy = "targetPage") + @EqualsAndHashCode.Exclude + private List drafts; + + @OneToMany(mappedBy = "page") @EqualsAndHashCode.Exclude private List versions; @ManyToMany - @JoinTable(name = "WIKI_PAGES_RELATED_PAGES", - joinColumns = {@JoinColumn(name = "PAGE_ID")}, - inverseJoinColumns = {@JoinColumn(name = "RELATED_PAGE_ID")} + @JoinTable( + name = "WIKI_PAGES_RELATED_PAGES", + joinColumns = {@JoinColumn(name = "PAGE_ID")}, + inverseJoinColumns = {@JoinColumn(name = "RELATED_PAGE_ID")} ) @EqualsAndHashCode.Exclude private List relatedPages; diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageMoveEntity.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageMoveEntity.java index 12e073272..1ce9b2d9b 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageMoveEntity.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageMoveEntity.java @@ -25,22 +25,14 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import jakarta.persistence.NamedQueries; import jakarta.persistence.NamedQuery; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; -/** - * Created by The eXo Platform SAS - * Author : eXoPlatform - * exo@exoplatform.com - * Jun 23, 2015 - */ @Entity(name = "WikiPageMoveEntity") @Table(name = "WIKI_PAGE_MOVES") -@NamedQueries({ - @NamedQuery(name = "wikiPageMove.getPreviousPage", query = "SELECT p FROM WikiPageMoveEntity p WHERE p.wikiType = :wikiType AND p.wikiOwner = :wikiOwner AND p.pageName = :pageName") -}) +@NamedQuery(name = "wikiPageMove.getPreviousPage", query = "SELECT p FROM WikiPageMoveEntity p WHERE p.wikiType = :wikiType AND p.wikiOwner = :wikiOwner AND p.pageName = :pageName") +@NamedQuery(name = "wikiPageMove.findMovesByPage", query = "SELECT p FROM WikiPageMoveEntity p WHERE p.page.id = :pageId") public class PageMoveEntity { public PageMoveEntity() { diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageVersionEntity.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageVersionEntity.java index 0009d869a..cce2b6495 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageVersionEntity.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageVersionEntity.java @@ -26,7 +26,6 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import jakarta.persistence.NamedQueries; import jakarta.persistence.NamedQuery; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; @@ -39,16 +38,14 @@ */ @Entity(name = "WikiPageVersionEntity") @Table(name = "WIKI_PAGE_VERSIONS") -@NamedQueries({ - @NamedQuery(name = "wikiPageVersion.getLastversionNumberOfPage", query = "SELECT max(p.versionNumber) FROM WikiPageVersionEntity p WHERE p.page.id = :pageId"), - @NamedQuery(name = "wikiPageVersion.getPageversionByPageIdAndVersion", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND p.versionNumber = :versionNumber"), - @NamedQuery(name = "wikiPageVersion.getAllPagesVersionsBySyntax", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.syntax = :syntax OR p.syntax IS NULL ORDER BY p.updatedDate DESC"), - @NamedQuery(name = "wikiPageVersion.countAllPagesVersionsBySyntax", query = "SELECT COUNT(p) FROM WikiPageVersionEntity p WHERE p.syntax = :syntax OR p.syntax IS NULL"), - @NamedQuery(name = "wikiPageVersion.getPageVersionsByPageIdAndLang", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND ((:lang IS NULL AND p.lang IS NULL) OR (:lang IS NOT NULL AND p.lang = :lang))"), - @NamedQuery(name = "wikiPageVersion.getLatestPageVersionsByPageIdAndLang", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND ((:lang IS NULL AND p.lang IS NULL) OR (:lang IS NOT NULL AND p.lang = :lang)) ORDER BY p.versionNumber DESC"), - @NamedQuery(name = "wikiPageVersion.getPageAvailableTranslationLanguages", query = "SELECT DISTINCT p.lang FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND p.lang IS NOT NULL") - -}) +@NamedQuery(name = "wikiPageVersion.getLastversionNumberOfPage", query = "SELECT max(p.versionNumber) FROM WikiPageVersionEntity p WHERE p.page.id = :pageId") +@NamedQuery(name = "wikiPageVersion.getPageversionByPageIdAndVersion", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND p.versionNumber = :versionNumber") +@NamedQuery(name = "wikiPageVersion.getAllPagesVersionsBySyntax", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.syntax = :syntax OR p.syntax IS NULL ORDER BY p.updatedDate DESC") +@NamedQuery(name = "wikiPageVersion.countAllPagesVersionsBySyntax", query = "SELECT COUNT(p) FROM WikiPageVersionEntity p WHERE p.syntax = :syntax OR p.syntax IS NULL") +@NamedQuery(name = "wikiPageVersion.getPageVersionsByPageIdAndLang", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND ((:lang IS NULL AND p.lang IS NULL) OR (:lang IS NOT NULL AND p.lang = :lang))") +@NamedQuery(name = "wikiPageVersion.getLatestPageVersionsByPageIdAndLang", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND ((:lang IS NULL AND p.lang IS NULL) OR (:lang IS NOT NULL AND p.lang = :lang)) ORDER BY p.versionNumber DESC") +@NamedQuery(name = "wikiPageVersion.getPageAvailableTranslationLanguages", query = "SELECT DISTINCT p.lang FROM WikiPageVersionEntity p WHERE p.page.id = :pageId AND p.lang IS NOT NULL") +@NamedQuery(name = "wikiPageVersion.findVersionsByPage", query = "SELECT p FROM WikiPageVersionEntity p WHERE p.page.id = :pageId") public class PageVersionEntity extends BasePageEntity { @Id @SequenceGenerator(name="SEQ_WIKI_PAGE_VERSIONS_VERS_ID", sequenceName="SEQ_WIKI_PAGE_VERSIONS_VERS_ID", allocationSize = 1) diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/WikiEntity.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/WikiEntity.java index 660a948e9..de40476fa 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/WikiEntity.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/WikiEntity.java @@ -16,6 +16,7 @@ */ package org.exoplatform.wiki.jpa.entity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -54,7 +55,7 @@ public class WikiEntity { @Column(name = "TYPE") private String type; - @OneToOne + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "WIKI_HOME") private PageEntity wikiHome; diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java b/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java index 3faea9a2b..e80eac7d7 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java @@ -27,11 +27,11 @@ import java.util.concurrent.Executors; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; + import org.exoplatform.commons.file.services.FileService; import org.picocontainer.Startable; -import com.google.common.util.concurrent.ThreadFactoryBuilder; - import org.exoplatform.services.security.Identity; import org.exoplatform.social.common.service.HTMLUploadImageProcessor; @@ -58,7 +58,8 @@ public NotesExportService(NoteService noteService, this.htmlUploadImageProcessor = htmlUploadImageProcessor; this.fileService = fileService; this.exportThreadPool = - Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Notes-Export-File-%d").build()); + Executors.newCachedThreadPool(new BasicThreadFactory.Builder().namingPattern("Notes-Export-File-%d") + .build()); } @Override diff --git a/notes-service/src/test/java/org/exoplatform/wiki/jpa/BaseWikiJPAIntegrationTest.java b/notes-service/src/test/java/org/exoplatform/wiki/jpa/BaseWikiJPAIntegrationTest.java index 177658679..94bc30c40 100644 --- a/notes-service/src/test/java/org/exoplatform/wiki/jpa/BaseWikiJPAIntegrationTest.java +++ b/notes-service/src/test/java/org/exoplatform/wiki/jpa/BaseWikiJPAIntegrationTest.java @@ -19,7 +19,6 @@ package org.exoplatform.wiki.jpa; -import org.exoplatform.commons.api.persistence.DataInitializer; import org.exoplatform.commons.file.services.FileService; import org.exoplatform.container.PortalContainer; import org.exoplatform.wiki.jpa.dao.DraftPageDAO; @@ -36,24 +35,27 @@ */ public abstract class BaseWikiJPAIntegrationTest extends BaseTest { protected WikiDAO wikiDAO; + protected PageDAO pageDAO; + protected DraftPageDAO draftPageDAO; + protected PageVersionDAO pageVersionDAO; + protected PageMoveDAO pageMoveDAO; + protected TemplateDAO templateDAO; + protected EmotionIconDAO emotionIconDAO; - protected FileService fileService; + + protected FileService fileService; @Override public void setUp() throws Exception { super.setUp(); - // make sure data are well initialized for each test - DataInitializer dataInitializer = PortalContainer.getInstance().getComponentInstanceOfType(DataInitializer.class); - dataInitializer.initData(); - - //Init fileService - fileService= PortalContainer.getInstance().getComponentInstanceOfType(FileService.class); + // Init fileService + fileService = PortalContainer.getInstance().getComponentInstanceOfType(FileService.class); // Init DAO wikiDAO = PortalContainer.getInstance().getComponentInstanceOfType(WikiDAO.class); pageDAO = PortalContainer.getInstance().getComponentInstanceOfType(PageDAO.class); @@ -62,7 +64,7 @@ public void setUp() throws Exception { pageMoveDAO = PortalContainer.getInstance().getComponentInstanceOfType(PageMoveDAO.class); templateDAO = PortalContainer.getInstance().getComponentInstanceOfType(TemplateDAO.class); emotionIconDAO = PortalContainer.getInstance().getComponentInstanceOfType(EmotionIconDAO.class); - // Clean Data + begin(); cleanDB(); } @@ -70,16 +72,14 @@ public void setUp() throws Exception { public void tearDown() throws Exception { // Clean Data cleanDB(); + end(); super.tearDown(); } private void cleanDB() { - emotionIconDAO.deleteAll(); - templateDAO.deleteAll(); - pageMoveDAO.deleteAll(); - pageVersionDAO.deleteAll(); - draftPageDAO.deleteAll(); + restartTransaction(); pageDAO.deleteAll(); wikiDAO.deleteAll(); } + }