From 9eb51f95a4c32cc313d273514f211a7d1df77c51 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Thu, 10 Sep 2020 08:56:13 +0200 Subject: [PATCH 1/8] Added dependencies for Jakarata EE MVC and Eclipse Krazo --- ccm-bundle-devel-thorntail/pom.xml | 6 + ccm-bundle-devel-wildfly/pom.xml | 6 + ccm-core/pom.xml | 1 + ccm-wildfly/pom.xml | 173 +++++++++++++++++++++++++++++ pom.xml | 38 ++++++- 5 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 ccm-wildfly/pom.xml diff --git a/ccm-bundle-devel-thorntail/pom.xml b/ccm-bundle-devel-thorntail/pom.xml index 6178bfbf9..8882c9e6a 100644 --- a/ccm-bundle-devel-thorntail/pom.xml +++ b/ccm-bundle-devel-thorntail/pom.xml @@ -123,6 +123,12 @@ undertow + + org.libreccm + ccm-wildfly + 7.0.0-SNAPSHOT + + com.h2database h2 diff --git a/ccm-bundle-devel-wildfly/pom.xml b/ccm-bundle-devel-wildfly/pom.xml index 3b5274fa5..d8ff7fd71 100644 --- a/ccm-bundle-devel-wildfly/pom.xml +++ b/ccm-bundle-devel-wildfly/pom.xml @@ -24,6 +24,12 @@ http://www.libreccm.org/modules/web/wildfly + + org.libreccm + ccm-wildfly + 7.0.0-SNAPSHOT + + org.webjars font-awesome diff --git a/ccm-core/pom.xml b/ccm-core/pom.xml index e4b86ea4f..75349003c 100644 --- a/ccm-core/pom.xml +++ b/ccm-core/pom.xml @@ -398,6 +398,7 @@ true true false + --frames diff --git a/ccm-wildfly/pom.xml b/ccm-wildfly/pom.xml new file mode 100644 index 000000000..24c449f77 --- /dev/null +++ b/ccm-wildfly/pom.xml @@ -0,0 +1,173 @@ + + + + 4.0.0 + + + UTF-8 + ${maven.build.timestamp} + yyyy-MM-dd'T'HH:mm:ss'Z'Z + + + + org.libreccm + libreccm-parent + 7.0.0-SNAPSHOT + + + org.libreccm + ccm-wildfly + 7.0.0-SNAPSHOT + CCM Wildfly Integration + + Wildfly specific stuff for CCM. + + + http://maven.apache.org + + + + Lesser GPL 2.1 + http://www.gnu.org/licenses/old-licenses/lgpl-2.1 + + + + + + javax.mvc + javax.mvc-api + + + org.eclipse.krazo + krazo-resteasy + + + + junit + junit + test + + + + + ccm-wildfly + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + true + true + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-surefire-plugin + + org.libreccm.tests.categories.UnitTest + false + + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + false + false + private + true + UTF-8 + UTF-8 + UTF-8 + true + true + true + true + false + + + + org.apache.maven.plugins + maven-jxr-plugin + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + org.jacoco + jacoco-maven-plugin + + + + com.github.spotbugs + spotbugs-maven-plugin + + + + org.apache.maven.plugins + maven-pmd-plugin + + true + utf-8 + 1.8 + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + dependencies + + licenses + + + + + + false + + + + + + diff --git a/pom.xml b/pom.xml index e691dcc52..484336ed1 100644 --- a/pom.xml +++ b/pom.xml @@ -95,8 +95,8 @@ ccm-cms-archetype-contenttype - - + ccm-wildfly + true @@ -532,6 +532,38 @@ jaxb-runtime 2.4.0-b180830.0438 + + + + javax.mvc + javax.mvc-api + 1.0.0 + + + + org.eclipse.krazo + krazo-jersey + 1.1.0-M1 + + + + org.eclipse.krazo + krazo-resteasy + 1.1.0-M1 + + + + org.eclipse.krazo.ext + krazo-freemarker + 1.1.0-M1 + @@ -912,4 +944,4 @@ - + \ No newline at end of file From 402ea5614df5cb1304e90d1dace37b9d6874db33 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sun, 13 Sep 2020 12:08:59 +0200 Subject: [PATCH 2/8] Integration of CCM themes and EE/MVC Krazo --- .../mvc/freemarker/KrazoTemplateLoader.java | 90 +++++++++++ .../MvcFreemarkerConfigurationProducer.java | 89 +++++++++++ .../mvc/freemarker/ThemesTemplateLoader.java | 149 ++++++++++++++++++ .../libreccm/mvc/freemarker/package-info.java | 22 +++ .../java/org/libreccm/mvc/package-info.java | 25 +++ 5 files changed, 375 insertions(+) create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/freemarker/MvcFreemarkerConfigurationProducer.java create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/freemarker/package-info.java create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/package-info.java diff --git a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java new file mode 100644 index 000000000..86c635ed7 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 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.mvc.freemarker; + +import freemarker.cache.MultiTemplateLoader; +import freemarker.cache.TemplateLoader; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import javax.servlet.ServletContext; + +/** + * + * @author Jens Pelzetter + */ +/** + * A copy of the {@link TemplateLoader} used by Krazo. + * + * The {@code TemplateLoader} used by Krazo is defined as inner class. This + * class provides the same behaviour as "real" class so that we can use it with + * Freemarker {@link MultiTemplateLoader}. + * + * As extension this implementation of the {@code TemplateLoader} interface will + * not process template paths which start with {@code @themes/} or + * {@code /@themes/}. These path are processed by the templates loaders for the + * theming system. + * + * @author Jens Pelzetter + */ +public class KrazoTemplateLoader implements TemplateLoader { + + private final ServletContext servletContext; + + public KrazoTemplateLoader(final ServletContext servletContext) { + super(); + this.servletContext = servletContext; + } + + @Override + public Object findTemplateSource(final String name) throws IOException { + if (name.startsWith("@themes") || name.startsWith("/@themes")) { + return null; + } else { + // Freemarker drops "/" + return servletContext.getResourceAsStream( + String.format("/%s", name) + ); + } + } + + @Override + public long getLastModified(final Object templateSource) { + return -1; + } + + @Override + public Reader getReader( + final Object templateSource, final String encoding + ) throws IOException { + return new InputStreamReader((InputStream) templateSource, encoding); + } + + @Override + public void closeTemplateSource( + final Object templateSource + ) throws IOException { + final InputStream inputStream = (InputStream) templateSource; + inputStream.close(); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/MvcFreemarkerConfigurationProducer.java b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/MvcFreemarkerConfigurationProducer.java new file mode 100644 index 000000000..a209a462a --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/MvcFreemarkerConfigurationProducer.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 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.mvc.freemarker; + +import freemarker.cache.ClassTemplateLoader; +import freemarker.cache.MultiTemplateLoader; +import freemarker.cache.TemplateLoader; +import freemarker.cache.WebappTemplateLoader; +import freemarker.template.Configuration; +import freemarker.template.TemplateExceptionHandler; +import org.eclipse.krazo.engine.ViewEngineConfig; +import org.eclipse.krazo.ext.freemarker.DefaultConfigurationProducer; +import org.libreccm.theming.Themes; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Specializes; +import javax.inject.Inject; +import javax.servlet.ServletContext; +import javax.ws.rs.Produces; + +/** + * Extends the default configuration for Freemarker of Eclipse Krazo to + * support Freemarker templates in CCM themes. + * + * @author Jens Pelzetter + */ +@ApplicationScoped +public class MvcFreemarkerConfigurationProducer + extends DefaultConfigurationProducer { + + @Inject + private ServletContext servletContext; + + @Inject + private Themes themes; + + @Produces + @ViewEngineConfig + @Specializes + @Override + public Configuration getConfiguration() { + final Configuration configuration = new Configuration( + Configuration.VERSION_2_3_30 + ); + + configuration.setDefaultEncoding("UTF-8"); + configuration.setTemplateExceptionHandler( + TemplateExceptionHandler.RETHROW_HANDLER + ); + configuration.setLogTemplateExceptions(false); + configuration.setWrapUncheckedExceptions(false); + configuration.setLocalizedLookup(false); + configuration.setTemplateLoader( + new MultiTemplateLoader( + new TemplateLoader[]{ + new KrazoTemplateLoader(servletContext), + new ThemesTemplateLoader(themes), + // For loading Freemarker macro libraries from WEB-INF + // resources + new WebappTemplateLoader( + servletContext, "/themes/freemarker" + ), + // For loading Freemarker macro libraries from classpath + // resources + new ClassTemplateLoader(getClass(), "/themes/freemarker") + } + ) + ); + + return configuration; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java new file mode 100644 index 000000000..677046738 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2020 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.mvc.freemarker; + +import freemarker.cache.TemplateLoader; +import org.libreccm.theming.ThemeInfo; +import org.libreccm.theming.ThemeVersion; +import org.libreccm.theming.Themes; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Arrays; +import java.util.Optional; + +/** + * Loads Freemarker templates from a theme. + * + * @author Jens Pelzetter + */ +public class ThemesTemplateLoader implements TemplateLoader { + + private final Themes themes; + + public ThemesTemplateLoader(final Themes themes) { + this.themes = themes; + } + + /** + * Loads the template from a theme. The path of the theme file must follow + * the following format: + * + * {@code @themes/$themeName/$version/$path/$to/$file} + * + * The {@code @themes} prefix is mandantory. {@code $themeName} is the name + * of the theme from which the template is loaded. {@code $version} is the + * version of the theme to use. This token is converted to + * {@link ThemeVersion}. Valid values are therefore {@code DRAFT} and + * {@code LIVE}. The remainder of the path is the path to the file inside the + * theme. + * + * @param path The path of the file. The path must include the theme and its + * version. + * + * @return An {@link InputStream} for the template if the template was found + * in the theme. Otherwise {@code null} is returned. + * + * @throws IOException + */ + @Override + public Object findTemplateSource(final String path) throws IOException { + if (path.startsWith("@themes") || path.startsWith("/@themes")) { + final String[] tokens; + if (path.startsWith("/")) { + tokens = path.substring(1).split("/"); + } else { + tokens = path.split("/"); + } + return findTemplateSource(tokens); + } else { + return null; + } + } + + private InputStream findTemplateSource(final String[] tokens) { + if (tokens.length >= 4) { + final String themeName = tokens[1]; + final ThemeVersion themeVersion = ThemeVersion + .valueOf(tokens[2]); + final String filePath = String.join( + "/", + Arrays.copyOfRange( + tokens, 3, tokens.length, String[].class + ) + ); + + return findTemplateSource(themeName, themeVersion, filePath); + } else { + return null; + } + } + + private InputStream findTemplateSource( + final String themeName, + final ThemeVersion themeVersion, + final String filePath + ) { + final Optional themeInfo = themes.getTheme( + themeName, themeVersion + ); + if (themeInfo.isPresent()) { + return findTemplateSource(themeInfo.get(), filePath); + } else { + return null; + } + } + + private InputStream findTemplateSource( + final ThemeInfo themeInfo, final String filePath + ) { + final Optional source = themes.getFileFromTheme( + themeInfo, filePath + ); + if (source.isPresent()) { + return source.get(); + } else { + return null; + } + } + + @Override + public long getLastModified(Object templateSource) { + return -1; + } + + @Override + public Reader getReader( + final Object templateSource, final String encoding + ) throws IOException { + final InputStream inputStream = (InputStream) templateSource; + return new InputStreamReader(inputStream, encoding); + } + + @Override + public void closeTemplateSource( + final Object templateSource + ) throws IOException { + final InputStream inputStream = (InputStream) templateSource; + inputStream.close(); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/package-info.java b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/package-info.java new file mode 100644 index 000000000..d3d2157ad --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 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 + */ +/** + * Integration of the Freemarker View Engine of Eclipse Krazo with LibreCCM. + */ +package org.libreccm.mvc.freemarker; diff --git a/ccm-core/src/main/java/org/libreccm/mvc/package-info.java b/ccm-core/src/main/java/org/libreccm/mvc/package-info.java new file mode 100644 index 000000000..5d3b11aa2 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/package-info.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 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 + */ +/** + * The classes in this package integrate LibreCCM with Jakarta EE MVC and its + * reference implementation Eclipse Krazo. + * + * @see https://www.mvc-spec.org/ + */ +package org.libreccm.mvc; From 8b06dc6cb268d9f80f8ac27f8d1167c2cc7fd453 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sun, 13 Sep 2020 16:50:49 +0200 Subject: [PATCH 3/8] Integration of EE MVC --- ccm-bundle-devel-wildfly/pom.xml | 19 +++++++++++++++++++ .../src/main/webapp/WEB-INF/faces-config.xml | 3 +++ ccm-core/pom.xml | 15 +++++++++++++++ ccm-wildfly/pom.xml | 4 ++++ .../org/libreccm/wildfly/LibreCcmWildfly.java | 17 +++++++++++++++++ pom.xml | 9 +++++++++ 6 files changed, 67 insertions(+) create mode 100644 ccm-wildfly/src/main/java/org/libreccm/wildfly/LibreCcmWildfly.java diff --git a/ccm-bundle-devel-wildfly/pom.xml b/ccm-bundle-devel-wildfly/pom.xml index d8ff7fd71..fe0fefee9 100644 --- a/ccm-bundle-devel-wildfly/pom.xml +++ b/ccm-bundle-devel-wildfly/pom.xml @@ -208,6 +208,22 @@ assets/ + + org.libreccm + ccm-core + jar + + views/ + + + + org.libreccm + ccm-core + jar + + resources/ + + org.librecms ccm-cms @@ -250,6 +266,9 @@ false ${project.basedir}/wildfly.properties + + -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8787 + diff --git a/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/faces-config.xml b/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/faces-config.xml index 59d6547c7..a1999da81 100644 --- a/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/faces-config.xml +++ b/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/faces-config.xml @@ -4,4 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"> + + org.libreccm.ui.CcmFaceletsResourceHandler + diff --git a/ccm-core/pom.xml b/ccm-core/pom.xml index 75349003c..1c5e2aae8 100644 --- a/ccm-core/pom.xml +++ b/ccm-core/pom.xml @@ -102,6 +102,21 @@ provided + + javax.mvc + javax.mvc-api + + + org.eclipse.krazo + krazo-core + provided + + + org.eclipse.krazo.ext + krazo-freemarker + provided + + diff --git a/ccm-wildfly/pom.xml b/ccm-wildfly/pom.xml index 24c449f77..b52f5806a 100644 --- a/ccm-wildfly/pom.xml +++ b/ccm-wildfly/pom.xml @@ -42,6 +42,10 @@ org.eclipse.krazo krazo-resteasy + + org.eclipse.krazo.ext + krazo-freemarker + junit diff --git a/ccm-wildfly/src/main/java/org/libreccm/wildfly/LibreCcmWildfly.java b/ccm-wildfly/src/main/java/org/libreccm/wildfly/LibreCcmWildfly.java new file mode 100644 index 000000000..8e156c242 --- /dev/null +++ b/ccm-wildfly/src/main/java/org/libreccm/wildfly/LibreCcmWildfly.java @@ -0,0 +1,17 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.libreccm.wildfly; + +/** + * Does nothing, only reuquired to get the Maven JAR working. + * + * To be removed when other classes are added to this module. + * + * @author Jens Pelzetter + */ +public class LibreCcmWildfly { + +} diff --git a/pom.xml b/pom.xml index 484336ed1..017bab17b 100644 --- a/pom.xml +++ b/pom.xml @@ -546,6 +546,15 @@ javax.mvc-api 1.0.0 + + + org.eclipse.krazo + krazo-core + 1.1.0-M1 + org.eclipse.krazo From ef02a6c7a01d114581dce509f91cc2a9b5c2ce18 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sun, 13 Sep 2020 16:51:13 +0200 Subject: [PATCH 4/8] Formatting --- .../java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java | 2 +- .../java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java index 86c635ed7..c11b975bf 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java @@ -46,7 +46,7 @@ import javax.servlet.ServletContext; * * @author Jens Pelzetter */ -public class KrazoTemplateLoader implements TemplateLoader { +class KrazoTemplateLoader implements TemplateLoader { private final ServletContext servletContext; diff --git a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java index 677046738..478a505a5 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/ThemesTemplateLoader.java @@ -35,7 +35,7 @@ import java.util.Optional; * * @author Jens Pelzetter */ -public class ThemesTemplateLoader implements TemplateLoader { +class ThemesTemplateLoader implements TemplateLoader { private final Themes themes; From fc4d838bc784899f883f5e59c37505ab83f38855 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sun, 13 Sep 2020 16:51:50 +0200 Subject: [PATCH 5/8] Integrate Krazo Facelets View Engine with LibreCCM themes --- .../mvc/facelets/CcmThemeUrlConnection.java | 104 ++++++++++++++++++ .../facelets/CcmThemeUrlStreamHandler.java | 45 ++++++++ .../mvc/facelets/CcmThemeViewResource.java | 59 ++++++++++ .../mvc/facelets/CcmViewResourceHandler.java | 72 ++++++++++++ 4 files changed, 280 insertions(+) create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmViewResourceHandler.java diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java new file mode 100644 index 000000000..cde1d8636 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2020 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.mvc.facelets; + +import org.libreccm.theming.ThemeInfo; +import org.libreccm.theming.ThemeVersion; +import org.libreccm.theming.Themes; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; +import java.util.Objects; + +/** + * + * @author Jens Pelzetter + */ +class CcmThemeUrlConnection extends URLConnection { + + private final Themes themes; + + private final String path; + + private ThemeInfo themeInfo; + + private String filePath; + + public CcmThemeUrlConnection(final Themes themes, final URL url) { + super(url); + this.themes = themes; + + final String urlStr = url.toString(); + + if (urlStr.startsWith("/")) { + path = urlStr.substring(1); + } else { + path = urlStr; + } + } + + @Override + public void connect() throws IOException { + final String[] tokens = path.split("/"); + if (tokens.length >= 4) { + final String themeName = tokens[1]; + final ThemeVersion version = ThemeVersion.valueOf(tokens[2]); + filePath = String.join( + "/", + Arrays.copyOfRange( + tokens, 3, tokens.length, String[].class + ) + ); + + themeInfo = themes.getTheme(themeName, version) + .orElseThrow(() -> new IOException( + String.format( + "Theme %s is available as %s version.", + themeName, + Objects.toString(version) + ))); + } else { + throw new IOException( + "Illegal URL for loading a facelets template from a theme." + ); + } + + } + + @Override + public InputStream getInputStream() throws IOException { + return themes + .getFileFromTheme(themeInfo, filePath) + .orElseThrow( + () -> new IOException( + String.format( + "Template %s not found in %s version of the theme %s.", + filePath, + themeInfo.getVersion(), + themeInfo.getName() + ) + ) + ); + + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java new file mode 100644 index 000000000..2242bf47e --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 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.mvc.facelets; + +import org.libreccm.theming.Themes; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +/** + * + * @author Jens Pelzetter + */ +class CcmThemeUrlStreamHandler extends URLStreamHandler { + + private final Themes themes; + + public CcmThemeUrlStreamHandler(final Themes themes) { + this.themes = themes; + } + + @Override + protected URLConnection openConnection(final URL url) throws IOException { + return new CcmThemeUrlConnection(themes, url); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java new file mode 100644 index 000000000..4d70648c2 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 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.mvc.facelets; + +import org.libreccm.core.UnexpectedErrorException; +import org.libreccm.theming.Themes; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.faces.application.ViewResource; + +/** + * + * @author Jens Pelzetter + */ +class CcmThemeViewResource extends ViewResource { + + private final String path; + + private final Themes themes; + + public CcmThemeViewResource(final Themes themes, final String path) { + this.themes = themes; + this.path = path; + } + + @Override + public URL getURL() { + try { + return new URL( + "libreccm", + null, + 0, + path, + new CcmThemeUrlStreamHandler(themes) + ); + } catch (MalformedURLException ex) { + throw new UnexpectedErrorException(ex); + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmViewResourceHandler.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmViewResourceHandler.java new file mode 100644 index 000000000..88332b49e --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmViewResourceHandler.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 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.mvc.facelets; + +import org.libreccm.theming.Themes; + +import javax.faces.application.ResourceHandler; +import javax.faces.application.ResourceHandlerWrapper; +import javax.faces.application.ViewResource; +import javax.faces.context.FacesContext; +import javax.inject.Inject; + +/** + * A Facelets resource handler that loads Facelets templates from LibreCCM + * themes. + * + * This handler only works for view resources. Only resource path which are + * starting with {@code @themes} or {@code /@themes} are used processed. All + * other paths are delegated to the wrapped resource handler. + * + * To enable this resource handler to following snippet must be present in the + * {@code faces-config.xml} file of the WAR (bundle): + * + *
+ * <application>
+        &tl;resource-handler>org.libreccm.ui.CcmFaceletsResourceHandler</resource-handler>
+    </application>
+
+ * 
+ * + * @author Jens Pelzetter + */ +public class CcmViewResourceHandler extends ResourceHandlerWrapper { + + @Inject + private Themes themes; + + private final ResourceHandler wrapped; + + public CcmViewResourceHandler(final ResourceHandler wrapped) { + super(wrapped); + this.wrapped = wrapped; + } + + @Override + public ViewResource createViewResource( + final FacesContext context, final String path + ) { + if (path.startsWith("@themes") || path.startsWith("/@themes")) { + return new CcmThemeViewResource(themes, path); + } else { + return super.createViewResource(context, path); + } + } + +} From 4de618558828f5d966973549c7192eee87ce51d6 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sun, 13 Sep 2020 17:59:02 +0200 Subject: [PATCH 6/8] JavaDoc for CcmThemeUrlConnection --- .../mvc/facelets/CcmThemeUrlConnection.java | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java index cde1d8636..30bcda28f 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java @@ -30,19 +30,41 @@ import java.util.Arrays; import java.util.Objects; /** + * Special {@link URLConnection} for loading Facelets templates from a LibreCCM + * theme. * * @author Jens Pelzetter */ class CcmThemeUrlConnection extends URLConnection { + /** + * Themes instance used as interface to the theme system + */ private final Themes themes; + /** + * Path of the template to load. + */ private final String path; + /** + * Theme to use. Initialized by {@link #connect()}. + */ private ThemeInfo themeInfo; + /** + * Path of the file relative to the theme root. Initialized by + * {@link #connect()} + */ private String filePath; + /** + * Constructor for initalizing the instance, providing the required + * parameters. + * + * @param themes Themes instance to use. + * @param url URL of the template to load. + */ public CcmThemeUrlConnection(final Themes themes, final URL url) { super(url); this.themes = themes; @@ -56,6 +78,13 @@ class CcmThemeUrlConnection extends URLConnection { } } + /** + * Called by Java to connect to the source of the URL. In this case we + * retrieve the {@link ThemeInfo} for the theme to use, and initalize the + * {@link #filePath} property. + * + * @throws IOException If the theme is not found or if the URL is malformed. + */ @Override public void connect() throws IOException { final String[] tokens = path.split("/"); @@ -78,12 +107,21 @@ class CcmThemeUrlConnection extends URLConnection { ))); } else { throw new IOException( - "Illegal URL for loading a facelets template from a theme." + "Malformed URL for loading a facelets template from a theme." ); } } + /** + * Get an {@link InputStream} for the resource to which the URL points. In + * this case we delagate the retrieval of the the template to + * {@link Themes#getFileFromTheme(org.libreccm.theming.ThemeInfo, java.lang.String)}. + * + * @return An {@code InputStream} for the requested template. + * + * @throws IOException If the template was not found in the theme. + */ @Override public InputStream getInputStream() throws IOException { return themes From 48ee764e5f384a4ef456e2222bcf2bc0d40a9e24 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sun, 13 Sep 2020 18:51:29 +0200 Subject: [PATCH 7/8] JavaDoc for the integration of Krazos Facelets ViewEngine with LibreCCM and a small bugfix --- .../mvc/facelets/CcmThemeUrlConnection.java | 8 +++---- .../facelets/CcmThemeUrlStreamHandler.java | 4 +++- .../mvc/facelets/CcmThemeViewResource.java | 18 ++++++++++++++- .../libreccm/mvc/facelets/package-info.java | 23 +++++++++++++++++++ 4 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java index 30bcda28f..3006ab4c4 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlConnection.java @@ -69,12 +69,12 @@ class CcmThemeUrlConnection extends URLConnection { super(url); this.themes = themes; - final String urlStr = url.toString(); + final String urlPath = url.getPath(); - if (urlStr.startsWith("/")) { - path = urlStr.substring(1); + if (urlPath.startsWith("/")) { + path = urlPath.substring(1); } else { - path = urlStr; + path = urlPath; } } diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java index 2242bf47e..b25face03 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeUrlStreamHandler.java @@ -26,7 +26,9 @@ import java.net.URLConnection; import java.net.URLStreamHandler; /** - * + * Implementation of {@link URLStreamHandler} for handling URLs to LibreCCM + * theme templates. + * * @author Jens Pelzetter */ class CcmThemeUrlStreamHandler extends URLStreamHandler { diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java index 4d70648c2..5e005b679 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/CcmThemeViewResource.java @@ -27,7 +27,8 @@ import java.net.URL; import javax.faces.application.ViewResource; /** - * + * A {@link ViewResource} implementation for templates from LibreCCM themes. + * * @author Jens Pelzetter */ class CcmThemeViewResource extends ViewResource { @@ -36,13 +37,28 @@ class CcmThemeViewResource extends ViewResource { private final Themes themes; + /** + * Constructor for the {@code ViewResource} instance. + * + * @param themes Interface to the theme system + * @param path The path of the template. + */ public CcmThemeViewResource(final Themes themes, final String path) { this.themes = themes; this.path = path; } + /** + * Gets the URL of the URL of the template as {@code ViewResource}. + * + * @return The URL of the {@code ViewResource}. + */ @Override public URL getURL() { + // The URL build here is a "pseudo" URL. Most of the parts of the URL + // are no relevant. An special URLStreamHandler implementation is + // also passed to the URL. This URLStreamHandler implementation takes + // care of retrieving the template from the theme. try { return new URL( "libreccm", diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java new file mode 100644 index 000000000..335aff91a --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 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 + */ +/** + * Integration of the LibreCCM theme system with the Facelet ViewEngine of + * Eclipse Krazo. + */ +package org.libreccm.mvc.facelets; From eb73092c37233810c777342132a873f50b23f71c Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Wed, 16 Sep 2020 08:40:53 +0200 Subject: [PATCH 8/8] JavaDoc update --- .../libreccm/mvc/facelets/package-info.java | 11 +++++++++- .../mvc/freemarker/KrazoTemplateLoader.java | 16 ++++++-------- .../java/org/libreccm/mvc/package-info.java | 21 ++++++++++++++++++- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java b/ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java index 335aff91a..04b4a3562 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/facelets/package-info.java @@ -18,6 +18,15 @@ */ /** * Integration of the LibreCCM theme system with the Facelet ViewEngine of - * Eclipse Krazo. + * Eclipse Krazo. The integration allows it to load Facelets either from + * a theme using a {@link Themes} or from the default locations. To enable the + * integration the following snippet has to be added to the + * {@code faces-config.xml}: + *
+ *     <application>
+ *         &tl;resource-handler>org.libreccm.ui.CcmFaceletsResourceHandler</resource-handler>
+ *     </application>
+ * 
+ * */ package org.libreccm.mvc.facelets; diff --git a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java index c11b975bf..6b31bbc11 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/freemarker/KrazoTemplateLoader.java @@ -28,21 +28,17 @@ import java.io.Reader; import javax.servlet.ServletContext; -/** - * - * @author Jens Pelzetter - */ /** * A copy of the {@link TemplateLoader} used by Krazo. * * The {@code TemplateLoader} used by Krazo is defined as inner class. This - * class provides the same behaviour as "real" class so that we can use it with - * Freemarker {@link MultiTemplateLoader}. + * class provides the same behaviour as this inner class so that we can use it + * with Freemarker's {@link MultiTemplateLoader}. * - * As extension this implementation of the {@code TemplateLoader} interface will - * not process template paths which start with {@code @themes/} or - * {@code /@themes/}. These path are processed by the templates loaders for the - * theming system. + * As extension to Krazo's implementation this implementation of the + * {@code TemplateLoader} interface will not process template paths which start + * with {@code @themes/} or {@code /@themes/}. These path are processed by the + * {@link ThemesTemplateLoader} for the theming system. * * @author Jens Pelzetter */ diff --git a/ccm-core/src/main/java/org/libreccm/mvc/package-info.java b/ccm-core/src/main/java/org/libreccm/mvc/package-info.java index 5d3b11aa2..f5b36a939 100644 --- a/ccm-core/src/main/java/org/libreccm/mvc/package-info.java +++ b/ccm-core/src/main/java/org/libreccm/mvc/package-info.java @@ -18,8 +18,27 @@ */ /** * The classes in this package integrate LibreCCM with Jakarta EE MVC and its - * reference implementation Eclipse Krazo. + * reference implementation Eclipse Krazo. + * + * And the the moment the ViewEngines for Facelets and Freemarker are supported. + * The integration allows it to load templates for these ViewEngines either from + * the default locations or from a theme. If the path of template starts with + * {@code @themes/} or {@code /@themes/} the integration will delegate loading of + * the template to {@link Themes} of the theme. The path must follow the following + * pattern: * + *
+ *     @themes/$themeName/$version/$pathToTemplate
+ * 
+ * + * Where {@code $themeName} is the name of the theme, {@code $version} is the + * version of the theme (either {@code live} or {@code draft} and + * {@code $pathToFile} is the path the template. + * + * If the path does not start with {@code @themes/} or {@code /@themes/} the + * template will be loaded from the default location(s) used by Jakarta EE + * MVC/Eclipse Krazo. + * * @see https://www.mvc-spec.org/ */ package org.libreccm.mvc;