diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java index 35c1fab3f..5ba7e4c3e 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java @@ -55,19 +55,19 @@ import org.librecms.contentsection.privileges.ItemPrivileges; import java.util.Optional; - /** - *

A CMSPage is a Bebop {@link com.arsdigita.bebop.Page} - * implementation of the {@link com.arsdigita.cms.dispatcher.ResourceHandler} - * interface.

+ *

+ * A CMSPage is a Bebop {@link com.arsdigita.bebop.Page} implementation + * of the {@link com.arsdigita.cms.dispatcher.ResourceHandler} interface.

* - *

It stores the current {@link com.arsdigita.cms.ContentSection} and, if + *

+ * It stores the current {@link com.arsdigita.cms.ContentSection} and, if * applicable, the {@link com.arsdigita.cms.ContentItem} in the page state as * request local objects. Components that are part of the CMSPage * may access these objects by calling:

- *
+ * 
  *     getContentSection(PageState state);
- *     
+ *
* * @author Michael Pih (pihman@arsdigita.com) * @author Uday Mathur (umathur@arsdigita.com) @@ -76,16 +76,23 @@ public class CMSPage extends Page implements ResourceHandler { private static final Logger LOGGER = LogManager.getLogger(CMSPage.class); - /** The global assets URL stub XML parameter name. */ + /** + * The global assets URL stub XML parameter name. + */ public final static String ASSETS = "ASSETS"; - /** The XML page class. */ + /** + * The XML page class. + */ public final static String PAGE_CLASS = "CMS"; - /** Map of XML parameters */ + /** + * Map of XML parameters + */ private HashMap m_params; - /** */ + /** + * */ private PageTransformer m_transformer; public CMSPage() { @@ -135,18 +142,21 @@ public class CMSPage extends Page implements ResourceHandler { // Make sure the error display gets rendered. getErrorDisplay().setIdAttr("page-body"); - final Class presenterClass = BebopConfig.getConfig().getPresenterClass(); + final Class presenterClass = BebopConfig + .getConfig().getPresenterClass(); final PresentationManager pm; try { pm = presenterClass.getDeclaredConstructor().newInstance(); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { + } catch (InstantiationException + | IllegalAccessException + | InvocationTargetException + | NoSuchMethodException ex) { throw new RuntimeException(ex); } if (pm instanceof PageTransformer) { m_transformer = (PageTransformer) pm; - } - else { + } else { m_transformer = new PageTransformer(); } } @@ -172,7 +182,9 @@ public class CMSPage extends Page implements ResourceHandler { * Fetches the value of the XML parameter. * * @param name The parameter name + * * @return The parameter value + * * @pre (name != null) */ public String getXMLParameter(String name) { @@ -182,8 +194,9 @@ public class CMSPage extends Page implements ResourceHandler { /** * Set an XML parameter. * - * @param name The parameter name + * @param name The parameter name * @param value The parameter value + * * @pre (name != null) */ public void setXMLParameter(String name, String value) { @@ -194,20 +207,19 @@ public class CMSPage extends Page implements ResourceHandler { * Fetch the request-local content section. * * @param request The HTTP request + * * @return The current content section * - * @deprecated use com.arsdigita.cms.CMS.getContext().getContentSection() - * instead - * Despite of being deprecated it can not be removed because it - * is required by the interface Resourcehandler which is - * implemented by this class. - * On the other hand, if deprecated, implementing ResourceHandler - * may not be required + * @deprecated use com.arsdigita.cms.CMS.getContext().getContentSection() + * instead Despite of being deprecated it can not be removed because it is + * required by the interface Resourcehandler which is implemented by this + * class. On the other hand, if deprecated, implementing ResourceHandler may + * not be required */ @Override public ContentSection getContentSection(HttpServletRequest request) { // Resets all content sections associations. - // return ContentSectionDispatcher.getContentSection(request); + // return ContentSectionDispatcher.getContentSection(request); return ContentSectionServlet.getContentSection(request); } @@ -215,13 +227,12 @@ public class CMSPage extends Page implements ResourceHandler { * Fetch the request-local content section. * * @param state The page state + * * @return The current content section * * @deprecated use com.arsdigita.cms.CMS.getContext().getContentSection() - * instead - * Despite of being deprecated it can not be removed because it - * is required by ContentItemPage which extends CMSPage and - * uses this method. + * instead Despite of being deprecated it can not be removed because it is + * required by ContentItemPage which extends CMSPage and uses this method. */ public ContentSection getContentSection(PageState state) { return getContentSection(state.getRequest()); @@ -231,15 +242,14 @@ public class CMSPage extends Page implements ResourceHandler { * Fetch the request-local content item. * * @param request The HTTP request + * * @return The current content item * * @deprecated use com.arsdigita.cms.CMS.getContext().getContentItem() - * instead - * Despite of being deprecated it can not be removed because it - * is required by the interface Resourcehandler which is - * implemented by this class. - * On the other hand, if deprecated, implementing ResourceHandler - * may not be required + * instead Despite of being deprecated it can not be removed because it is + * required by the interface Resourcehandler which is implemented by this + * class. On the other hand, if deprecated, implementing ResourceHandler may + * not be required */ public ContentItem getContentItem(HttpServletRequest request) { // resets all content item associations @@ -250,12 +260,12 @@ public class CMSPage extends Page implements ResourceHandler { * Fetch the request-local content item. * * @param state The page state + * * @return The current content item + * * @deprecated use com.arsdigita.cms.CMS.getContext().getContentItem() - * instead. - * Despite of being deprecated it can not be removed because it - * is required by ContentItemPage which extends CMSPage and - * uses this method. + * instead. Despite of being deprecated it can not be removed because it is + * required by ContentItemPage which extends CMSPage and uses this method. */ public ContentItem getContentItem(PageState state) { return getContentItem(state.getRequest()); @@ -264,65 +274,70 @@ public class CMSPage extends Page implements ResourceHandler { /** * Services the Bebop page. * - * @param request The servlet request object + * @param request The servlet request object * @param response the servlet response object - * @param actx The request context + * @param actx The request context * * @pre m_transformer != null */ @Override public void dispatch(final HttpServletRequest request, - final HttpServletResponse response , + final HttpServletResponse response, final RequestContext actx) throws IOException, ServletException { final CcmApplication app = Web.getWebContext().getApplication(); ContentSection section = null; - + if (app == null) { //Nothing to do - } else if(app instanceof ContentSection) { + } else if (app instanceof ContentSection) { section = (ContentSection) app; - } - + } + if (section != null) { CMS.getContext().setContentSection(section); } - + final String itemId = request.getParameter("item_id"); - + if (itemId != null) { final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentItemRepository itemRepo = cdiUtil.findBean(ContentItemRepository.class); + final ContentItemRepository itemRepo = cdiUtil.findBean( + ContentItemRepository.class); final ContentItem item = itemRepo .findById(Long.parseLong(itemId)).get(); final PermissionChecker permissionChecker = cdiUtil.findBean( PermissionChecker.class); - permissionChecker.checkPermission(ItemPrivileges.PREVIEW, + permissionChecker.checkPermission(ItemPrivileges.PREVIEW, item); CMS.getContext().setContentItem(item); } - + final Document document = buildDocument(request, response); - + m_transformer.servePage(document, request, response); } /** * Overwrites bebop.Page#generateXMLHelper to add the name of the user * logged in to the page (displayed as part of the header). + * * @param ps * @param parent - * @return + * + * @return */ @Override protected Element generateXMLHelper(PageState ps, Document parent) { - Element page = super.generateXMLHelper(ps,parent); - final Optional user = CdiUtil.createCdiUtil().findBean(Shiro.class).getUser(); - if ( user.isPresent()) { - page.addAttribute("name",user.get().getName()); + Element page = super.generateXMLHelper(ps, parent); + final Optional user = CdiUtil.createCdiUtil() + .findBean(Shiro.class).getUser(); + if (user.isPresent()) { + page.addAttribute("name", user.get().getName()); } return page; } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSApplicationPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSApplicationPage.java index 2bc576f56..a39a58456 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSApplicationPage.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSApplicationPage.java @@ -131,14 +131,15 @@ public class CMSApplicationPage extends Page { getErrorDisplay().setIdAttr("page-body"); final Class presenterClass = BebopConfig - .getConfig().getPresenterClass(); + .getConfig() + .getPresenterClass(); final PresentationManager presenter; try { presenter = presenterClass.getDeclaredConstructor().newInstance(); } catch (InstantiationException - | IllegalAccessException - | NoSuchMethodException - | InvocationTargetException ex) { + | IllegalAccessException + | NoSuchMethodException + | InvocationTargetException ex) { throw new RuntimeException("Failed to create PresentationManager", ex); } diff --git a/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java b/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java index 64f820968..53299f1fd 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java +++ b/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java @@ -20,7 +20,6 @@ package org.librecms.pages; import org.libreccm.categorization.Category; import org.libreccm.core.AbstractEntityRepository; -import org.libreccm.core.CoreConstants; import org.libreccm.security.RequiresPrivilege; import java.util.Optional; @@ -28,6 +27,7 @@ import java.util.Optional; import javax.enterprise.context.RequestScoped; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; +import javax.transaction.Transactional; /** * Repository for {@link Page} entities. @@ -37,12 +37,16 @@ import javax.persistence.TypedQuery; @RequestScoped public class PageRepository extends AbstractEntityRepository{ + private static final long serialVersionUID = -338101684757468443L; + /** * Find the {@link Page} associated with a {@link Category}. * * @param category The {@link Category} associated with the {@link Page}. * @return */ + @RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES) + @Transactional(Transactional.TxType.REQUIRED) public Optional findPageForCategory(final Category category) { final TypedQuery query = getEntityManager() @@ -56,14 +60,14 @@ public class PageRepository extends AbstractEntityRepository{ } } - @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - @Override + @RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES) + @Transactional(Transactional.TxType.REQUIRED) public void save(final Page page) { super.save(page); } - @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - @Override + @RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES) + @Transactional(Transactional.TxType.REQUIRED) public void delete(final Page page) { super.delete(page); } diff --git a/ccm-cms/src/main/java/org/librecms/pages/Pages.java b/ccm-cms/src/main/java/org/librecms/pages/Pages.java index 374c74825..9f6f254cc 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/Pages.java +++ b/ccm-cms/src/main/java/org/librecms/pages/Pages.java @@ -19,8 +19,7 @@ package org.librecms.pages; import org.libreccm.categorization.Domain; -import org.libreccm.sites.Site; -import org.libreccm.web.CcmApplication; +import org.libreccm.sites.SiteAwareApplication; import java.io.Serializable; import java.util.Objects; @@ -35,9 +34,9 @@ import javax.persistence.Table; import static org.librecms.CmsConstants.*; /** - * The {@code Pages} application. Each instance of this application provides - * the page tree for specific site. - * + * The {@code Pages} application. Each instance of this application provides the + * page tree for specific site. + * * @author Jens Pelzetter */ @Entity @@ -66,17 +65,10 @@ import static org.librecms.CmsConstants.*; + "FROM Pages p JOIN p.site s " + "WHERE s.defaultSite = true") }) -public class Pages extends CcmApplication implements Serializable { +public class Pages extends SiteAwareApplication implements Serializable { private static final long serialVersionUID = -352205318143692477L; - /** - * The {@link Site} to which this pages instance belongs. - */ - @OneToOne - @JoinColumn(name = "SITE_ID") - private Site site; - /** * The category {@link Domain} which is used the model the page tree. */ @@ -84,14 +76,6 @@ public class Pages extends CcmApplication implements Serializable { @JoinColumn(name = "CATEGORY_DOMAIN_ID") private Domain categoryDomain; - public Site getSite() { - return site; - } - - protected void setSite(final Site site) { - this.site = site; - } - public Domain getCategoryDomain() { return categoryDomain; } @@ -104,7 +88,6 @@ public class Pages extends CcmApplication implements Serializable { public int hashCode() { int hash = 7; hash = 17 * hash + Objects.hashCode(categoryDomain); - hash = 17 * hash + Objects.hashCode(site); return hash; } @@ -132,10 +115,6 @@ public class Pages extends CcmApplication implements Serializable { return false; } - if (!Objects.equals(site, other.getSite())) { - return false; - } - return Objects.equals(categoryDomain, other.getCategoryDomain()); } @@ -143,15 +122,4 @@ public class Pages extends CcmApplication implements Serializable { public boolean canEqual(final Object obj) { return obj instanceof Pages; } - - @Override - public String toString(final String data) { - - return super.toString(String.format( - ", site = \"%s\"%s", - Objects.toString(site), - data - )); - } - } diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesManager.java b/ccm-cms/src/main/java/org/librecms/pages/PagesManager.java index a35e18a15..2d36cee12 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/PagesManager.java +++ b/ccm-cms/src/main/java/org/librecms/pages/PagesManager.java @@ -19,29 +19,45 @@ package org.librecms.pages; import org.libreccm.categorization.Domain; +import org.libreccm.security.RequiresPrivilege; +import org.libreccm.sites.Site; +import org.libreccm.sites.SiteManager; + +import java.io.Serializable; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; +import javax.transaction.Transactional; /** * Manager class for {@link Pages}. - * + * * @author Jens Pelzetter */ @RequestScoped -public class PagesManager { - +public class PagesManager implements Serializable { + + private static final long serialVersionUID = 888880071212859827L; + @Inject - private PagesRepository pagesRepo; - - public Pages createPages(final Domain domain) { - + private PagesRepository pagesRepo; + + @Inject + private SiteManager siteManager; + + @RequiresPrivilege(PagesPrivileges.ADMINISTER_PAGES) + @Transactional(Transactional.TxType.REQUIRED) + public Pages createPages(final Site site, + final Domain domain) { + final Pages pages = new Pages(); pages.setCategoryDomain(domain); - + + siteManager.addApplicationToSite(site, pages); + pagesRepo.save(pages); - + return pages; } - + } diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesPrivileges.java b/ccm-cms/src/main/java/org/librecms/pages/PagesPrivileges.java new file mode 100644 index 000000000..4d27cb7f2 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pages/PagesPrivileges.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library 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 2.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.pages; + +/** + * Constants for privileges allowing administrative actions on pages. + * + * @author Jens Pelzetter + */ +public final class PagesPrivileges { + + public static final String ADMINISTER_PAGES = "administer_pages"; + + private PagesPrivileges() { + //Nothing + } + +} diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_19__pages_site_aware.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_19__pages_site_aware.sql new file mode 100644 index 000000000..4eeeb7706 --- /dev/null +++ b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_19__pages_site_aware.sql @@ -0,0 +1,13 @@ +alter table CCM_CMS.PAGES_APP + drop constraint FK3wkyn4oxa65f7svtj917m61jc; + +alter table CCM_CMS.PAGES_APP + drop contraint FKrrk4g7my3e4qkdoeiygkqxduy; + +alter table CCM_CMS.PAGES_APP + drop column if exists SITE_ID; + +alter table CCM_CMS.PAGES_APP + add constraint FKk4jb5fylibg2pbbaypyt6f8lb + foreign key (OBJECT_ID) + references SITE_AWARE_APPLICATIONS; diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_19__pages_site_aware.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_19__pages_site_aware.sql new file mode 100644 index 000000000..4eeeb7706 --- /dev/null +++ b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_19__pages_site_aware.sql @@ -0,0 +1,13 @@ +alter table CCM_CMS.PAGES_APP + drop constraint FK3wkyn4oxa65f7svtj917m61jc; + +alter table CCM_CMS.PAGES_APP + drop contraint FKrrk4g7my3e4qkdoeiygkqxduy; + +alter table CCM_CMS.PAGES_APP + drop column if exists SITE_ID; + +alter table CCM_CMS.PAGES_APP + add constraint FKk4jb5fylibg2pbbaypyt6f8lb + foreign key (OBJECT_ID) + references SITE_AWARE_APPLICATIONS; diff --git a/ccm-core/src/main/java/org/libreccm/sites/Site.java b/ccm-core/src/main/java/org/libreccm/sites/Site.java index 2a7dce615..56f0f4067 100644 --- a/ccm-core/src/main/java/org/libreccm/sites/Site.java +++ b/ccm-core/src/main/java/org/libreccm/sites/Site.java @@ -22,12 +22,16 @@ import static org.libreccm.core.CoreConstants.*; import org.libreccm.core.CcmObject; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Objects; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; import javax.persistence.Table; /** @@ -66,6 +70,14 @@ public class Site extends CcmObject { @Column(name = "DEFAULT_THEME") private String defaultTheme; + @OneToMany(mappedBy = "site") + private List applications; + + public Site() { + super(); + applications = new ArrayList<>(); + } + public String getDomainOfSite() { return domainOfSite; } @@ -89,7 +101,23 @@ public class Site extends CcmObject { public void setDefaultTheme(final String defaultTheme) { this.defaultTheme = defaultTheme; } + + public List getApplications() { + return Collections.unmodifiableList(applications); + } + + protected void setApplications(final List applications) { + this.applications = new ArrayList<>(applications); + } + protected void addApplication(final SiteAwareApplication application) { + applications.add(application); + } + + protected void removeApplication(final SiteAwareApplication application) { + applications.remove(application); + } + @Override public int hashCode() { int hash = 3; diff --git a/ccm-core/src/main/java/org/libreccm/sites/SiteAwareApplication.java b/ccm-core/src/main/java/org/libreccm/sites/SiteAwareApplication.java new file mode 100644 index 000000000..1f98be983 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/sites/SiteAwareApplication.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library 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 2.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.sites; + +import org.libreccm.web.CcmApplication; + +import java.util.Objects; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * + * @author Jens Pelzetter + */ +@Entity +@Table(name = "SITE_AWARE_APPLICATIONS") +public class SiteAwareApplication extends CcmApplication { + + private static final long serialVersionUID = -8892544588904174406L; + + @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @JoinColumn(name = "SITE_ID") + private Site site; + + public Site getSite() { + return site; + } + + protected void setSite(final Site site) { + this.site = site; + } + + @Override + public int hashCode() { + int hash = 3; + if (site != null) { + hash = 59 * hash + Objects.hashCode(site.getDomainOfSite()); + hash = 59 * hash + Objects.hashCode(site.isDefaultSite()); + hash = 59 * hash + Objects.hashCode(site.getDefaultTheme()); + } + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof SiteAwareApplication)) { + return false; + } + final SiteAwareApplication other = (SiteAwareApplication) obj; + if (!other.canEqual(this)) { + return false; + } + if (site == null && other.getSite() != null) { + return false; + } else if (site != null && other.getSite() == null) { + return false; + } else { + if (!Objects.equals(site.getDomainOfSite(), + other.getSite().getDomainOfSite())) { + return false; + } + if (site.isDefaultSite() != other.getSite().isDefaultSite()) { + return false; + } + if (!Objects.equals(site.getDefaultTheme(), + other.getSite().getDefaultTheme())) { + return false; + } + } + + return true; + } + + @Override + public boolean canEqual(final Object obj) { + return obj instanceof SiteAwareApplication; + } + + @Override + public String toString(final String data) { + + if (site == null) { + return super.toString(String.format(", site = null%d", data)); + } else { + return super.toString(String.format(", site = { " + + "domainOfSite = \"%s\", " + + "isDefaultSite = %b," + + "defaultTheme = \"%s\" }%s", + site.getDomainOfSite(), + site.isDefaultSite(), + site.getDefaultTheme(), + data)); + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/sites/SiteManager.java b/ccm-core/src/main/java/org/libreccm/sites/SiteManager.java new file mode 100644 index 000000000..fd609235e --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/sites/SiteManager.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library 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 2.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.sites; + +import static org.libreccm.core.CoreConstants.*; + +import org.libreccm.security.RequiresPrivilege; +import org.libreccm.web.ApplicationRepository; + +import java.io.Serializable; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +public class SiteManager implements Serializable { + + private static final long serialVersionUID = 1834820718630385805L; + + @Inject + private ApplicationRepository applicationRepo; + + @Inject + private SiteRepository siteRepo; + + @RequiresPrivilege(PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public void addApplicationToSite(final Site site, + final SiteAwareApplication application) { + + site.addApplication(application); + application.setSite(site); + + siteRepo.save(site); + applicationRepo.save(application); + } + + @RequiresPrivilege(PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public void removeApplicationFromSite(final Site site, + final SiteAwareApplication application) { + + site.removeApplication(application); + application.setSite(null); + + siteRepo.save(site); + applicationRepo.save(application); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/sites/SiteRepository.java b/ccm-core/src/main/java/org/libreccm/sites/SiteRepository.java index 84de9cfe0..91676f8c1 100644 --- a/ccm-core/src/main/java/org/libreccm/sites/SiteRepository.java +++ b/ccm-core/src/main/java/org/libreccm/sites/SiteRepository.java @@ -36,6 +36,8 @@ import javax.transaction.Transactional; @RequestScoped public class SiteRepository extends AbstractEntityRepository { + private static final long serialVersionUID = 3120528987720524155L; + @Transactional(Transactional.TxType.REQUIRED) public Optional findByDomain(final String domain) { diff --git a/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_17__site_aware_application.sql b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_17__site_aware_application.sql new file mode 100644 index 000000000..91defae62 --- /dev/null +++ b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_17__site_aware_application.sql @@ -0,0 +1,15 @@ +create table SITE_AWARE_APPLICATIONS ( + OBJECT_ID bigint not null, + SITE_ID bigint, + primary key (OBJECT_ID) +); + +alter table SITE_AWARE_APPLICATIONS + add constraint FKopo91c29jaunpcusjwlphhxkd + foreign key (SITE_ID) + references CCM_CORE.SITES; + +alter table SITE_AWARE_APPLICATIONS + add constraint FKslbu2qagg23dmdu01lun7oh7x + foreign key (OBJECT_ID) + references CCM_CORE.APPLICATIONS; \ No newline at end of file diff --git a/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_17__site_aware_application.sql b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_17__site_aware_application.sql new file mode 100644 index 000000000..f5017b5cb --- /dev/null +++ b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_17__site_aware_application.sql @@ -0,0 +1,15 @@ +create table SITE_AWARE_APPLICATIONS ( + OBJECT_ID int8 not null, + SITE_ID int8, + primary key (OBJECT_ID) +); + +alter table SITE_AWARE_APPLICATIONS + add constraint FKopo91c29jaunpcusjwlphhxkd + foreign key (SITE_ID) + references CCM_CORE.SITES; + +alter table SITE_AWARE_APPLICATIONS + add constraint FKslbu2qagg23dmdu01lun7oh7x + foreign key (OBJECT_ID) + references CCM_CORE.APPLICATIONS; \ No newline at end of file