From 6a7f85f4de1e061d707b7b1eb3bfe4f5e18b8284 Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 11 Oct 2017 17:59:23 +0000 Subject: [PATCH] CCM NG: Next part of the sites/pages/themes complex git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5040 8810af33-2d31-482b-a856-94f89814c4df Former-commit-id: e7dfec180d132e359156dfd50ee03ed32fcd333c --- .../org/librecms/pagemodel/PageModel.java | 77 ----------- .../CmsPageBuilder.java} | 27 +++- .../main/java/org/librecms/pages/Pages.java | 23 +++- .../org/librecms/pages/PagesRepository.java | 51 ++++++-- .../java/org/librecms/pages/PagesRouter.java | 122 ++++++++++++++++-- .../org/libreccm/pagemodel/PageBuilder.java | 6 +- .../pagemodel/PageModelRepository.java | 2 +- .../main/java/org/libreccm/sites/Site.java | 5 + .../org/libreccm/sites/SiteRepository.java | 17 ++- 9 files changed, 214 insertions(+), 116 deletions(-) delete mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/PageModel.java rename ccm-cms/src/main/java/org/librecms/{pagemodel/BasePage.java => pages/CmsPageBuilder.java} (63%) diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/PageModel.java b/ccm-cms/src/main/java/org/librecms/pagemodel/PageModel.java deleted file mode 100644 index 8ef61cbba..000000000 --- a/ccm-cms/src/main/java/org/librecms/pagemodel/PageModel.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2016 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.pagemodel; - -import com.arsdigita.templating.Templating; -import com.arsdigita.xml.Document; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author Jens Pelzetter - */ -@WebServlet(urlPatterns = {"*.bebop"}) -public class PageModel extends HttpServlet { - - private static final long serialVersionUID = 1056528247823275004L; - - @Override - protected void doGet(final HttpServletRequest request, - final HttpServletResponse response) - throws ServletException { - - final BasePage page = new BasePage(); - final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); - final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName( - "JavaScript"); - scriptEngine.put("page", page); - - try { - scriptEngine.eval( - "load(\'nashorn:mozilla_compat.js\');\n" - + "importClass(org.librecms.pagemodel.BasePage);\n" - + "var BasePage = Java.type('org.librecms.pagemodel.BasePage');\n" -// + "var page = new BasePage;\n" -// + "print(page.getClass().getName());\n" - + "page.setPageAttribute(\'name\', \'page-model-demo\');\n" - + "page.setPageAttribute(\'application\', \'content\');\n" - + "label = new com.arsdigita.bebop.Label(\'Test\');\n" - + "page.add(label);\n"); - } catch (ScriptException ex) { - throw new ServletException(ex); - } - -// final BasePage page = (BasePage) scriptEngine.get("page"); - page.lock(); - - final Document document = page.buildDocument(request, response); - Templating.getPresentationManager().servePage(document, - request, - response); - - } - -} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/BasePage.java b/ccm-cms/src/main/java/org/librecms/pages/CmsPageBuilder.java similarity index 63% rename from ccm-cms/src/main/java/org/librecms/pagemodel/BasePage.java rename to ccm-cms/src/main/java/org/librecms/pages/CmsPageBuilder.java index a4becd380..b3e6ddf27 100644 --- a/ccm-cms/src/main/java/org/librecms/pagemodel/BasePage.java +++ b/ccm-cms/src/main/java/org/librecms/pages/CmsPageBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 LibreCCM Foundation. + * 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 @@ -16,18 +16,31 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ -package org.librecms.pagemodel; +package org.librecms.pages; -import com.arsdigita.bebop.Page; +import org.libreccm.pagemodel.AbstractPageBuilder; + +import java.util.HashMap; +import java.util.Map; + +import javax.enterprise.context.RequestScoped; /** * * @author Jens Pelzetter */ -public class BasePage extends Page { - - public void setPageAttribute(final String name, final String value) { - super.setAttribute(name, value); +@RequestScoped +public class CmsPageBuilder extends AbstractPageBuilder { + + @Override + public Map buildPage(final Map parameters) { + + final Map result = new HashMap<>(); + + return result; + } + + } 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 00b725735..75df6b286 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/Pages.java +++ b/ccm-cms/src/main/java/org/librecms/pages/Pages.java @@ -62,8 +62,27 @@ import static org.librecms.CmsConstants.*; name = "Pages.availableForDefaultSite", query = "SELECT (CASE WHEN COUNT(p) > 0 THEN true ELSE false END) " + "FROM Pages p JOIN p.site s " - + "WHERE s.defaultSite = true"), - + + "WHERE s.defaultSite = true") + , + @NamedQuery( + name = "Pages.findPageModelForIndexPage", + query = "SELECT DISTINCT m " + + "FROM PageModel m " + + "JOIN m.categories c " + + "WHERE c.category = :category " + + "AND c.type = '" + + PagesConstants.CATEGORIZATION_TYPE_PAGE_MODEL_INDEX + "' " + + "AND m.version = :version") + , + @NamedQuery( + name = "Pages.findPageModelForItemPage", + query = "SELECT DISTINCT m " + + "FROM PageModel m " + + "JOIN m.categories c " + + "WHERE c.category = :category " + + "AND c.type = '" + + PagesConstants.CATEGORIZATION_TYPE_PAGE_MODEL_ITEM + "' " + + "AND m.version = :version") }) public class Pages extends CcmApplication implements Serializable { diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java b/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java index b4fafbe9c..8d11f87d3 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java +++ b/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java @@ -18,15 +18,14 @@ */ package org.librecms.pages; -import com.arsdigita.ui.admin.AdminUiConstants; +import org.libreccm.categorization.Category; import org.libreccm.core.AbstractEntityRepository; -import org.libreccm.core.CcmObjectRepository; import org.libreccm.core.CoreConstants; +import org.libreccm.pagemodel.PageModelVersion; import org.libreccm.security.RequiresPrivilege; import org.libreccm.sites.SiteRepository; -import org.librecms.CmsConstants; -import org.librecms.contentsection.privileges.AdminPrivileges; +import org.libreccm.pagemodel.PageModel; import java.util.Optional; @@ -51,12 +50,12 @@ public class PagesRepository extends AbstractEntityRepository { if (siteRepo.hasSiteForDomain(domainOfSite)) { final TypedQuery query = getEntityManager() - .createNamedQuery("Pages.findForSite", Pages.class); + .createNamedQuery("Pages.findForSite", Pages.class); query.setParameter("domain", domainOfSite); - + try { return Optional.of(query.getSingleResult()); - } catch(NoResultException ex) { + } catch (NoResultException ex) { return Optional.empty(); } } else { @@ -70,6 +69,40 @@ public class PagesRepository extends AbstractEntityRepository { } } + @Transactional(Transactional.TxType.REQUIRED) + public Optional findPageModelForIndexPage( + final Category category, + final PageModelVersion version) { + + final TypedQuery query = getEntityManager() + .createNamedQuery("Pages.findPageModelForIndexPage", PageModel.class); + query.setParameter("category", category); + query.setParameter("version", version.toString()); + + try { + return Optional.of(query.getSingleResult()); + } catch(NoResultException ex) { + return Optional.empty(); + } + } + + @Transactional(Transactional.TxType.REQUIRED) + public Optional findPageModelForItemPage( + final Category category, + final PageModelVersion version) { + + final TypedQuery query = getEntityManager() + .createNamedQuery("Pages.findPageModelForItemPage", PageModel.class); + query.setParameter("category", category); + query.setParameter("version", version.toString()); + + try { + return Optional.of(query.getSingleResult()); + } catch(NoResultException ex) { + return Optional.empty(); + } + } + @Override public Class getEntityClass() { return Pages.class; @@ -85,11 +118,11 @@ public class PagesRepository extends AbstractEntityRepository { public void save(final Pages pages) { super.save(pages); } - + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Override public void delete(final Pages pages) { super.delete(pages); } - + } diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java b/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java index c972a2f84..1775789bb 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java +++ b/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java @@ -21,10 +21,22 @@ package org.librecms.pages; import org.libreccm.categorization.Category; import org.libreccm.categorization.CategoryManager; import org.libreccm.categorization.CategoryRepository; +import org.libreccm.pagemodel.PageModel; import org.libreccm.pagemodel.PageModelManager; +import org.libreccm.pagemodel.PageModelVersion; +import org.libreccm.sites.Site; +import org.libreccm.sites.SiteRepository; +import org.libreccm.theming.ThemeInfo; +import org.libreccm.theming.ThemeVersion; +import org.libreccm.theming.Themes; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; +import javax.persistence.EntityManager; import javax.transaction.Transactional; import javax.ws.rs.DefaultValue; import javax.ws.rs.NotFoundException; @@ -32,7 +44,9 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; /** @@ -48,27 +62,58 @@ public class PagesRouter { @Inject private CategoryRepository categoryRepo; - + @Inject + private CmsPageBuilder pageBuilder; + + @Inject + private EntityManager entityManager; + + @Inject + private PagesRepository pagesRepo; @Inject private PageModelManager pageModelManager; @Inject - private PagesRepository siteRepo; + private SiteRepository siteRepo; + + @Inject + private Themes themes; @Path("/index.{lang}.html") @Produces("text/html") @Transactional(Transactional.TxType.REQUIRED) public String getCategoryIndexPage( - @Context final UriInfo uriInfo, - @PathParam("page") final String page, - @PathParam("lang") final String language, - @QueryParam("theme") @DefaultValue("--DEFAULT--") final String theme) { + @Context + final UriInfo uriInfo, + @PathParam("page") + final String page, + @PathParam("lang") + final String language, + @QueryParam("theme") + @DefaultValue("--DEFAULT--") + final String theme, + @QueryParam("theme-version") + @DefaultValue("LIVE") + final String themeVersion, + @QueryParam("pagemodel-version") + @DefaultValue("LIVE") + final String pageModelVersion) { final String domain = uriInfo.getBaseUri().getHost(); - final Pages pages = siteRepo + final Site site; + if (siteRepo.hasSiteForDomain(domain)) { + site = siteRepo.findByDomain(domain).get(); + } else { + site = siteRepo + .findDefaultSite() + .orElseThrow(() -> new NotFoundException( + "No matching Site and no default Site.")); + } + + final Pages pages = pagesRepo .findPagesForSite(domain) .orElseThrow(() -> new NotFoundException(String .format("No Pages for domain \"%s\" available.", @@ -81,13 +126,64 @@ public class PagesRouter { page, domain))); + final Optional pageModel = pagesRepo + .findPageModelForIndexPage(category, + PageModelVersion + .valueOf(pageModelVersion)); + final Map parameters = new HashMap<>(); + parameters.put("currentCategory", category); + + final Map buildResult; + if (pageModel.isPresent()) { + buildResult = pageBuilder.buildPage(pageModel.get(), parameters); + } else { + buildResult = pageBuilder.buildPage(parameters); + } + + final ThemeInfo themeInfo; + if ("--DEFAULT--".equals(theme)) { + themeInfo = themes + .getTheme(site.getDefaultTheme(), + ThemeVersion.valueOf(themeVersion)) + .orElseThrow(() -> new WebApplicationException( + String.format("The configured default theme \"%s\" for " + + "site \"%s\" is not available.", + site.getDomainOfSite(), + site.getDefaultTheme()), + Response.Status.INTERNAL_SERVER_ERROR)); + } else { + themeInfo = themes.getTheme(theme, + ThemeVersion.valueOf(themeVersion)) + .orElseThrow(() -> new WebApplicationException( + String.format("The theme \"%s\" is not available.", + theme), + Response.Status.BAD_REQUEST)); + } + + return themes.process(buildResult, themeInfo); + } + + @Path("/index.{lang}.tree") + @Produces("text/html") + @Transactional(Transactional.TxType.REQUIRED) + public String getCategoryIndexPageTree( + @Context + final UriInfo uriInfo, + @PathParam("page") + final String page, + @PathParam("lang") + final String language, + @QueryParam("theme") + @DefaultValue("--DEFAULT--") + final String theme, + @QueryParam("theme-version") + @DefaultValue("LIVE") + final String themeVersion, + @QueryParam("pagemodel-version") + @DefaultValue("LIVE") + final String pageModelVersion) { - // ToDo Get PageModelBuilder - // ToDo Build page - // ToDo Get Theme Processor - // ToDo Pass page to theme processor - // ToDo Return result of ThemeProcessor throw new UnsupportedOperationException(); } @@ -97,7 +193,7 @@ public class PagesRouter { @PathParam("page") final String page, @PathParam("lang") final String language, @QueryParam("theme") @DefaultValue("--DEFAULT--") final String theme) { - + throw new UnsupportedOperationException(); } diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageBuilder.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageBuilder.java index 701d70595..179ecdb23 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageBuilder.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageBuilder.java @@ -20,13 +20,11 @@ package org.libreccm.pagemodel; import java.util.Map; -import javax.enterprise.context.RequestScoped; /** * Interface for page builders. A page builder is invoked to build a page a - * specific type. An implementation must be a CDI bean which is annotated with - * the qualifier {@link PageModelType}. The recommended scope is - * {@link RequestScoped}. + * specific type. An implementation should be a CDI bean which is annotated with + * the qualifier {@link PageModelType}. * * An implementation should add all default components which have to be present * in page. The {@link PageModel} should only specify diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java index 7b8bf2075..90f616ae9 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelRepository.java @@ -50,7 +50,7 @@ public class PageModelRepository extends AbstractEntityRepository { } } + @Transactional(Transactional.TxType.REQUIRED) + public Optional findDefaultSite() { + final TypedQuery query = getEntityManager() + .createNamedQuery("Site.findDefaultSite", Site.class); + + try { + return Optional.of(query.getSingleResult()); + } catch (NoResultException ex) { + return Optional.empty(); + } + } + @Transactional(Transactional.TxType.REQUIRED) public boolean hasSiteForDomain(final String domain) { @@ -66,7 +77,7 @@ public class SiteRepository extends AbstractEntityRepository { public void save(final Site site) { super.save(site); } - + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Override public void delete(final Site site) { @@ -82,5 +93,5 @@ public class SiteRepository extends AbstractEntityRepository { public boolean isNew(final Site site) { return site.getObjectId() == 0; } - + }