From 32d5eed14d0f7992b1edda252e2a7b5c3f9135d5 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Wed, 6 Jan 2021 19:27:44 +0100 Subject: [PATCH] More user friendly methods for getting template for ThemesMvc --- .../theming/manifest/ThemeManifest.java | 104 +++++---- .../org/libreccm/theming/mvc/ThemesMvc.java | 61 +++-- .../libreccm/ui/login/LoginController.java | 6 +- .../libreccm/ui/login/LogoutController.java | 2 +- .../themes/ccm-freemarker/theme.json | 221 ++++++++++-------- 5 files changed, 225 insertions(+), 169 deletions(-) diff --git a/ccm-core/src/main/java/org/libreccm/theming/manifest/ThemeManifest.java b/ccm-core/src/main/java/org/libreccm/theming/manifest/ThemeManifest.java index 4c91258b4..27f1a5b76 100644 --- a/ccm-core/src/main/java/org/libreccm/theming/manifest/ThemeManifest.java +++ b/ccm-core/src/main/java/org/libreccm/theming/manifest/ThemeManifest.java @@ -92,11 +92,15 @@ public class ThemeManifest implements Serializable { private String defaultTemplate; @XmlElement(name = "mvc-templates", namespace = THEMES_XML_NS) - private Map> mvcTemplates; + private Map mvcTemplates; + + @XmlElement(name = "views", namespace = THEMES_XML_NS) + private Map> views; public ThemeManifest() { templates = new ArrayList<>(); mvcTemplates = new HashMap<>(); + views = new HashMap<>(); } public String getName() { @@ -163,65 +167,62 @@ public class ThemeManifest implements Serializable { this.defaultTemplate = defaultTemplate; } - public Map> getMvcTemplates() { + public Map getMvcTemplates() { return Collections.unmodifiableMap(mvcTemplates); } - public Optional> getMvcTemplatesOfCategory( - final String category - ) { - return Optional.ofNullable(mvcTemplates.get(category)); - } - - public void addMvcTemplatesCategory(final String category) { - mvcTemplates.put(category, new HashMap<>()); - } - - public void addMvcTemplatesCategory( - final String category, final Map templates - ) { - mvcTemplates.put(category, templates); - } - - public Optional getMvcTemplate( - final String category, final String objectType - ) { - final Optional> templatesInCat - = getMvcTemplatesOfCategory(category); - - if (templatesInCat.isPresent()) { - return Optional.ofNullable(templatesInCat.get().get(objectType)); - } else { - return Optional.empty(); - } + public Optional getMvcTemplate(final String name) { + return Optional.ofNullable(mvcTemplates.get(name)); } public void addMvcTemplate( - final String category, - final String objectType, - final ThemeTemplate template + final String name, final ThemeTemplate template ) { - if (!mvcTemplates.containsKey(category)) { - addMvcTemplatesCategory(category); - } - - mvcTemplates - .get(category) - .put( - objectType, - Objects.requireNonNull( - template, - "Template can't be null." - ) - ); + mvcTemplates.put(name, template); } protected void setMvcTemplates( - final Map> mvcTemplates + final Map mvcTemplates ) { this.mvcTemplates = mvcTemplates; } + public Map> getViews() { + return Collections.unmodifiableMap(views); + } + + public Map getViewsOfApplication(final String application) { + if (views.containsKey(application)) { + return views.get(application); + } else { + return Collections.emptyMap(); + } + } + + public void addViewsOfApplication( + final String application, final Map viewsOfApplication + ) { + views.put(application, viewsOfApplication); + } + + public void addViewToApplication( + final String application, final String view, final String templateName + ) { + final Map applicationViews; + if (views.containsKey(application)) { + applicationViews = views.get(application); + } else { + applicationViews = new HashMap<>(); + views.put(application, applicationViews); + } + + applicationViews.put(view, templateName); + } + + protected void setViews(final Map> views) { + this.views = new HashMap<>(views); + } + @Override public int hashCode() { int hash = 7; @@ -233,6 +234,7 @@ public class ThemeManifest implements Serializable { hash = 83 * hash + Objects.hashCode(templates); hash = 83 * hash + Objects.hashCode(defaultTemplate); hash = 83 * hash + Objects.hashCode(mvcTemplates); + hash = 83 * hash + Objects.hashCode(views); return hash; } @@ -272,7 +274,11 @@ public class ThemeManifest implements Serializable { if (!Objects.equals(defaultTemplate, other.getDefaultTemplate())) { return false; } - return mvcTemplates.equals(other.getMvcTemplates()); + if (!Objects.equals(mvcTemplates, other.getMvcTemplates())) { + return false; + } + + return Objects.equals(views, other.getViews()); } public boolean canEqual(final Object obj) { @@ -295,7 +301,8 @@ public class ThemeManifest implements Serializable { + "description = \"%s\", " + "templates = %s, " + "defaultTemplate, " - + "mvcTemplates = %s%s" + + "mvcTemplates = %s," + + "views = %s%s" + " }", super.toString(), name, @@ -306,6 +313,7 @@ public class ThemeManifest implements Serializable { Objects.toString(templates), defaultTemplate, Objects.toString(mvcTemplates), + Objects.toString(views), data ); diff --git a/ccm-core/src/main/java/org/libreccm/theming/mvc/ThemesMvc.java b/ccm-core/src/main/java/org/libreccm/theming/mvc/ThemesMvc.java index f999d9b2e..999bb7630 100644 --- a/ccm-core/src/main/java/org/libreccm/theming/mvc/ThemesMvc.java +++ b/ccm-core/src/main/java/org/libreccm/theming/mvc/ThemesMvc.java @@ -18,6 +18,7 @@ */ package org.libreccm.theming.mvc; +import org.libreccm.core.UnexpectedErrorException; import org.libreccm.sites.Site; import org.libreccm.sites.SiteRepository; import org.libreccm.theming.ThemeInfo; @@ -61,7 +62,8 @@ public class ThemesMvc { public String getMvcTemplate( final UriInfo uriInfo, - final String application + final String application, + final String view ) { final Site site = getSite(uriInfo); final String theme = parseThemeParam(uriInfo); @@ -72,35 +74,46 @@ public class ThemesMvc { themeVersion ); final ThemeManifest manifest = themeInfo.getManifest(); - final Map applicationTemplates = manifest - .getMvcTemplatesOfCategory("applications") + final Map views = manifest.getViewsOfApplication( + application + ); + final String viewTemplateName; + if (views.containsKey(view)) { + viewTemplateName = views.get(view); + } else { + final Map defaultAppViews = manifest + .getViewsOfApplication(application); + if (defaultAppViews.containsKey("default")) { + viewTemplateName = defaultAppViews.get("default"); + } else { + throw new WebApplicationException( + String.format( + "Theme \"%s\" does not provide a template for view " + + "\"%s\" of application \"%s\", and there is no " + + "default template configured.", + themeInfo.getName(), + view, + application + ) + ); + } + } + + final ThemeTemplate themeTemplate = manifest + .getMvcTemplate(viewTemplateName) .orElseThrow( () -> new WebApplicationException( String.format( - "Manifest of theme %s has no application templates.", - themeInfo.getName() - ), - Response.Status.INTERNAL_SERVER_ERROR - ) - ); - final ThemeTemplate themeTemplate; - if (applicationTemplates.containsKey(application)) { - themeTemplate = applicationTemplates.get(application); - } else { - themeTemplate = Optional.ofNullable( - applicationTemplates.get("@default") - ).orElseThrow( - () -> new WebApplicationException( - String.format( - "Theme %s does not provide a template for application " - + "%s and has not default template for " - + "applications.", - theme, - application + "Theme \"%s\" maps view \"%s\" of application \"%s\" " + + "to template \"%s\" but not template with this " + + "name was found in the theme.", + themeInfo.getName(), + view, + application, + viewTemplateName ) ) ); - } models.put("contextPath", servletContext.getContextPath()); models.put("themeName", themeInfo.getName()); diff --git a/ccm-core/src/main/java/org/libreccm/ui/login/LoginController.java b/ccm-core/src/main/java/org/libreccm/ui/login/LoginController.java index d75e0c61d..f006369e5 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/login/LoginController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/login/LoginController.java @@ -96,7 +96,7 @@ public class LoginController { models.put("loginFailed", false); } models.put("returnUrl", returnUrl); - return themesMvc.getMvcTemplate(uriInfo, "login-form"); + return themesMvc.getMvcTemplate(uriInfo, "login", "loginForm"); } @POST @@ -141,7 +141,7 @@ public class LoginController { @GET @Path("/recover-password") public String getRecoverPasswordForm(@Context final UriInfo uriInfo) { - return themesMvc.getMvcTemplate(uriInfo, "login-recover-password"); + return themesMvc.getMvcTemplate(uriInfo, "login", "recoverPassword"); } @POST @@ -160,7 +160,7 @@ public class LoginController { } } - return themesMvc.getMvcTemplate(uriInfo, "login-password-recovered"); + return themesMvc.getMvcTemplate(uriInfo, "login", "passwordRecovered"); } private boolean isEmailPrimaryIdentifier() { diff --git a/ccm-core/src/main/java/org/libreccm/ui/login/LogoutController.java b/ccm-core/src/main/java/org/libreccm/ui/login/LogoutController.java index 48f41ccf9..52b5406a7 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/login/LogoutController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/login/LogoutController.java @@ -49,7 +49,7 @@ public class LogoutController { public String logout(@Context final UriInfo uriInfo) { subject.logout(); - return themesMvc.getMvcTemplate(uriInfo, "logout"); + return themesMvc.getMvcTemplate(uriInfo, "logout", "loggedout"); } } diff --git a/ccm-core/src/main/resources/themes/ccm-freemarker/theme.json b/ccm-core/src/main/resources/themes/ccm-freemarker/theme.json index fce2189d4..935946ed8 100644 --- a/ccm-core/src/main/resources/themes/ccm-freemarker/theme.json +++ b/ccm-core/src/main/resources/themes/ccm-freemarker/theme.json @@ -5,103 +5,138 @@ "default-template": "category-page.html.ftl", "mvc-templates": { - "applications": { - "login-form": { - "description": { - "values": { - "value": [ - { - "lang": "en", - "value": "Login Form" - } - ] - } - }, - "name": "Login Form", - "path": "login/login-form.html.ftl", - "title": { - "values": { - "value": [ - { - "lang": "en", - "value": "Login Form" - } - ] - } + "category-page": { + "description": { + "values": { + "value": [ + { + "lang": "en", + "value": "Category Page Template" + } + ] } }, - "login-recover-password": { - "description": { - "values": { - "value": [ - { - "lang": "en", - "value": "Recover lost passwords" - } - ] - } - }, - "name": "login-recover-password", - "path": "login/login-recover-password.html.ftl", - "title": { - "values": { - "value": [ - { - "lang": "en", - "value": "Recover password" - } - ] - } - } - }, - "login-password-recovered": { - "description": { - "values": { - "value": [ - { - "lang": "en", - "value": "Password recovered" - } - ] - } - }, - "name": "login-password-recovered", - "path": "login/login-password-recovered.html.ftl", - "title": { - "values": { - "value": [ - { - "lang": "en", - "value": "Password recovered" - } - ] - } - } - }, - "logout": { - "description": { - "values": { - "value": [ - { - "lang": "en", - "value": "Logout successful" - } - ] - } - }, - "name": "loggedout", - "path": "logout/loggedout.html.ftl", - "title": { - "values": { - "value": [ - { - "lang": "en", - "value": "Logout succesful" - } - ] - } + "name": "Category Page", + "path": "categoryPage.html.ftl", + "title": { + "values": { + "value": [ + { + "lang": "en", + "value": "Category Page" + } + ] } } + }, + "login-form": { + "description": { + "values": { + "value": [ + { + "lang": "en", + "value": "Login Form" + } + ] + } + }, + "name": "Login Form", + "path": "login/login-form.html.ftl", + "title": { + "values": { + "value": [ + { + "lang": "en", + "value": "Login Form" + } + ] + } + } + }, + "login-recover-password": { + "description": { + "values": { + "value": [ + { + "lang": "en", + "value": "Recover lost passwords" + } + ] + } + }, + "name": "login-recover-password", + "path": "login/login-recover-password.html.ftl", + "title": { + "values": { + "value": [ + { + "lang": "en", + "value": "Recover password" + } + ] + } + } + }, + "login-password-recovered": { + "description": { + "values": { + "value": [ + { + "lang": "en", + "value": "Password recovered" + } + ] + } + }, + "name": "login-password-recovered", + "path": "login/login-password-recovered.html.ftl", + "title": { + "values": { + "value": [ + { + "lang": "en", + "value": "Password recovered" + } + ] + } + } + }, + "loggedout": { + "description": { + "values": { + "value": [ + { + "lang": "en", + "value": "Logout successful" + } + ] + } + }, + "name": "loggedout", + "path": "logout/loggedout.html.ftl", + "title": { + "values": { + "value": [ + { + "lang": "en", + "value": "Logout succesful" + } + ] + } + } + } + }, + "views": { + "default": { + "default": "category-page" + }, + "login": { + "loginForm": "login-form", + "passwordRecovered": "login-password-recovered", + "recoverPassword": "login-recover-password" + }, + "logout": { + "loggedout": "loggedout" } } }