JavaDoc for the integration of EE MVC and the themeing system
parent
32d5eed14d
commit
375e5eff65
|
|
@ -58,6 +58,22 @@ import javax.mvc.engine.ViewEngineException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Customized version of the Freemarker View Engine. This class is based of the
|
||||
* View Engine from the Krazo project, but has been extended:
|
||||
* <ul>
|
||||
* <li>Named Beans are supported</li>
|
||||
* <li>Freemarker template have access to the MvcContext under the name
|
||||
* {@code mvc}, as in Facelet-based templates</li>
|
||||
* <li>The current {@link HttpServletRequest} is made avaiable in Freemarker
|
||||
* templates as {@link request}.</li>
|
||||
* <li>The following utility functions are made available:
|
||||
* <ul>
|
||||
* <li>{@code getSetting}: retreives the value of a setting from the theme</li>
|
||||
* <li>{@code localize}: retreives a localized value from the theme</li>
|
||||
* <li>{@code truncateText}: Truncates text to a specific length.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
|
|
@ -123,8 +139,6 @@ public class FreemarkerViewEngine extends ViewEngineBase {
|
|||
);
|
||||
}
|
||||
model.put("truncateText", new TruncateTextMethod());
|
||||
|
||||
|
||||
|
||||
final Map<String, Object> namedBeans = beanManager
|
||||
.getBeans(Object.class)
|
||||
|
|
@ -149,6 +163,13 @@ public class FreemarkerViewEngine extends ViewEngineBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for retrieving a an instance of a named bean using CDI.
|
||||
*
|
||||
* @param bean The bean to retrieve.
|
||||
*
|
||||
* @return An instance of the bean.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Optional<NamedBeanInstance> findBeanInstance(final Bean<?> bean) {
|
||||
final Context context = beanManager.getContext(bean.getScope());
|
||||
|
|
@ -166,10 +187,19 @@ public class FreemarkerViewEngine extends ViewEngineBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class encapsulating the information about a named bean.
|
||||
*/
|
||||
private class NamedBeanInstance {
|
||||
|
||||
/**
|
||||
* The name of the bean.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The bean instance.
|
||||
*/
|
||||
private final Object beanInstance;
|
||||
|
||||
public NamedBeanInstance(String name, Object beanInstance) {
|
||||
|
|
@ -187,6 +217,9 @@ public class FreemarkerViewEngine extends ViewEngineBase {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a setting from the theme using the {@link SettingsUtils}.
|
||||
*/
|
||||
private class GetSettingMethod implements TemplateMethodModelEx {
|
||||
|
||||
private final ThemeInfo fromTheme;
|
||||
|
|
@ -241,6 +274,9 @@ public class FreemarkerViewEngine extends ViewEngineBase {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a localized value from the theme using the {@link L10NUtils}.
|
||||
*/
|
||||
private class LocalizeMethod implements TemplateMethodModelEx {
|
||||
|
||||
private final ThemeInfo fromTheme;
|
||||
|
|
@ -275,6 +311,9 @@ public class FreemarkerViewEngine extends ViewEngineBase {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates text to a specific length.
|
||||
*/
|
||||
private class TruncateTextMethod implements TemplateMethodModelEx {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -21,13 +21,20 @@ package org.libreccm.mvc.freemarker;
|
|||
import org.libreccm.theming.ThemeInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* Encapulates the data of a template.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class TemplateInfo {
|
||||
|
||||
/**
|
||||
* Info about the theme providing the template.
|
||||
*/
|
||||
private final ThemeInfo themeInfo;
|
||||
|
||||
/**
|
||||
* The path of the template,
|
||||
*/
|
||||
private final String filePath;
|
||||
|
||||
public TemplateInfo(ThemeInfo themeInfo, String filePath) {
|
||||
|
|
|
|||
|
|
@ -34,13 +34,15 @@ import javax.enterprise.inject.Instance;
|
|||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Utility class for retreving a {@link TemplateInfo} instance for a template.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class ThemeTemplateUtil {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(ThemeTemplateUtil.class);
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
ThemeTemplateUtil.class);
|
||||
|
||||
@Inject
|
||||
private Instance<ThemeProvider> themeProviders;
|
||||
|
|
@ -48,11 +50,28 @@ class ThemeTemplateUtil {
|
|||
@Inject
|
||||
private Themes themes;
|
||||
|
||||
/**
|
||||
* Checks if the provided path points to a template.
|
||||
*
|
||||
* @param templatePath The path of the template.
|
||||
*
|
||||
* @return {@code true} if the path points to a template, {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isValidTemplatePath(final String templatePath) {
|
||||
return templatePath.startsWith("@themes")
|
||||
|| templatePath.startsWith("/@themes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link TemplateInfo} for the template.
|
||||
*
|
||||
* @param templatePath The path of the template.
|
||||
*
|
||||
* @return An {@link Optional} with a {@link TemplateInfo} for the template.
|
||||
* If the template is not available, an empty {@link Optional} is
|
||||
* returned.
|
||||
*/
|
||||
public Optional<TemplateInfo> getTemplateInfo(final String templatePath) {
|
||||
if (!isValidTemplatePath(templatePath)) {
|
||||
throw new IllegalArgumentException(
|
||||
|
|
@ -74,6 +93,13 @@ class ThemeTemplateUtil {
|
|||
return getTemplateInfo(tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the {@link ThemeProvider} for a theme.
|
||||
*
|
||||
* @param forTheme The theme
|
||||
*
|
||||
* @return The {@link ThemeProvider} for the theme.
|
||||
*/
|
||||
public ThemeProvider findThemeProvider(final ThemeInfo forTheme) {
|
||||
final Instance<? extends ThemeProvider> provider = themeProviders
|
||||
.select(forTheme.getProvider());
|
||||
|
|
@ -92,6 +118,15 @@ class ThemeTemplateUtil {
|
|||
return provider.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the {@link TemplateInfo} for a template.
|
||||
*
|
||||
* @param tokens The tokens of the template path.
|
||||
*
|
||||
* @return An {@link Optional} with a {@link TemplateInfo} for the template.
|
||||
* If the template is not available, an empty {@link Optional} is
|
||||
* returned.
|
||||
*/
|
||||
private Optional<TemplateInfo> getTemplateInfo(final String[] tokens) {
|
||||
if (tokens.length >= 4) {
|
||||
final String themeName = tokens[1];
|
||||
|
|
@ -108,7 +143,7 @@ class ThemeTemplateUtil {
|
|||
final Optional<ThemeInfo> themeInfo = themes.getTheme(
|
||||
themeName, themeVersion
|
||||
);
|
||||
|
||||
|
||||
if (themeInfo.isPresent()) {
|
||||
return Optional.of(new TemplateInfo(themeInfo.get(), filePath));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
package org.libreccm.mvc.freemarker;
|
||||
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import org.libreccm.theming.ThemeInfo;
|
||||
import org.libreccm.theming.ThemeVersion;
|
||||
import org.libreccm.theming.Themes;
|
||||
|
||||
|
|
@ -27,7 +26,6 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ package org.libreccm.theming.mvc;
|
|||
import org.libreccm.theming.ThemeFileInfo;
|
||||
import org.libreccm.theming.ThemeProvider;
|
||||
import org.libreccm.theming.ThemeVersion;
|
||||
import org.libreccm.theming.manager.Themes;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -38,6 +37,9 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* Provides access to the resources/assets of themes.
|
||||
*
|
||||
* @see ThemeResources
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
|
|
@ -45,13 +47,30 @@ import javax.ws.rs.core.Response;
|
|||
@Path("/")
|
||||
public class ThemeResourceProvider {
|
||||
|
||||
/**
|
||||
* Injection point for the available {@link ThemeProvider}s.
|
||||
*/
|
||||
@Inject
|
||||
@Any
|
||||
private Instance<ThemeProvider> providers;
|
||||
|
||||
@Inject
|
||||
private Themes themes;
|
||||
|
||||
/**
|
||||
* Serves a resources from a theme. This endpoint is mounted at
|
||||
* {@code /@themes/{theme}/{themeVersion}/{path:.+}}. If the provided theme
|
||||
* is not found, the provided theme is not available in the requested
|
||||
* version, or if the theme does not provide the requested resource the
|
||||
* endpoint will response with a 404 response. If the response is found, a
|
||||
* response with the asset and the correct mime type is returned.
|
||||
*
|
||||
* @param themeName The name of the theme providing the resource.
|
||||
* @param themeVersionParam The version of the theme to use (either
|
||||
* {@code LIVE} or {@code DRAFT}.
|
||||
* @param pathParam The path of the resource to serve.
|
||||
*
|
||||
* @return A response with the resource and the correct mime type, or a 404
|
||||
* response if the resource, the theme version or the theme is not
|
||||
* available.
|
||||
*/
|
||||
@GET
|
||||
@Path("/{theme}/{themeVersion}/{path:.+}")
|
||||
public Response getThemeFile(
|
||||
|
|
@ -123,8 +142,15 @@ public class ThemeResourceProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for finding the provider of a theme.
|
||||
*
|
||||
* @param forTheme The theme.
|
||||
*
|
||||
* @return An {@link Optional} with the provider of the theme. If there is
|
||||
* no matching provider, an empty {@link Optional} is returned.
|
||||
*/
|
||||
private Optional<ThemeProvider> findProvider(final String forTheme) {
|
||||
|
||||
final List<ThemeProvider> providersList = new ArrayList<>();
|
||||
providers
|
||||
.forEach(provider -> providersList.add(provider));
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import javax.ws.rs.ApplicationPath;
|
|||
import javax.ws.rs.core.Application;
|
||||
|
||||
/**
|
||||
* JAX-RS application providing the resources/assets of a theme (images, CSS
|
||||
* files, etc) under the {@code /@themes} URL.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
|
|
@ -37,7 +39,5 @@ public class ThemeResources extends Application {
|
|||
classes.add(ThemeResourceProvider.class);
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
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;
|
||||
|
|
@ -30,7 +29,6 @@ import org.libreccm.theming.manifest.ThemeTemplate;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -42,6 +40,7 @@ import javax.ws.rs.core.Response;
|
|||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
* Main integration point for MVC application with the theme system.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
|
|
@ -60,6 +59,16 @@ public class ThemesMvc {
|
|||
@Inject
|
||||
private Themes themes;
|
||||
|
||||
/**
|
||||
* Get the template for a specific application and view from the current
|
||||
* theme.
|
||||
*
|
||||
* @param uriInfo URI is required for some tasks in inside the method.
|
||||
* @param application The application for which the template is requested.
|
||||
* @param view The view for which the template is requested.
|
||||
*
|
||||
* @return The path of the template to use for the view of the application.
|
||||
*/
|
||||
public String getMvcTemplate(
|
||||
final UriInfo uriInfo,
|
||||
final String application,
|
||||
|
|
@ -136,6 +145,13 @@ public class ThemesMvc {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method of retrieving the current site.
|
||||
*
|
||||
* @param uriInfo Used to extract the current site.
|
||||
*
|
||||
* @return The current site.
|
||||
*/
|
||||
private Site getSite(final UriInfo uriInfo) {
|
||||
Objects.requireNonNull(uriInfo);
|
||||
|
||||
|
|
@ -154,6 +170,16 @@ public class ThemesMvc {
|
|||
return site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for retrieving a the theme to use.
|
||||
*
|
||||
* @param site The current site.
|
||||
* @param theme The theme to retrieve.
|
||||
* @param themeVersion The version of the theme to retrieve.
|
||||
*
|
||||
* @return A {@link ThemeInfo} object providing access to to the theme and
|
||||
* its resources.
|
||||
*/
|
||||
private ThemeInfo getTheme(
|
||||
final Site site,
|
||||
final String theme,
|
||||
|
|
@ -187,6 +213,15 @@ public class ThemesMvc {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for parsing the {@code theme} query parameter which can be
|
||||
* used to override the default theme of a site.
|
||||
*
|
||||
* @param uriInfo Information about the current URI.
|
||||
*
|
||||
* @return The value of the {@link theme} query parameter if present, or
|
||||
* {@code --DEFAULT--} if the query parameter is not present.
|
||||
*/
|
||||
private String parseThemeParam(final UriInfo uriInfo) {
|
||||
if (uriInfo.getQueryParameters().containsKey("theme")) {
|
||||
return uriInfo.getQueryParameters().getFirst("theme");
|
||||
|
|
@ -195,6 +230,18 @@ public class ThemesMvc {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for parsing the {@code preview} query parameter. The
|
||||
* {@code preview} query parameter allows it to test the draft version of a
|
||||
* theme.
|
||||
*
|
||||
* @param uriInfo Information about the current URI.
|
||||
*
|
||||
* @return If the value of the parameter is {@code theme} or {@code all}
|
||||
* {@link ThemeVersion#DRAFT} is returned. If the query parameter is
|
||||
* not present or has another value, {@link ThemeVersion#LIVE} is
|
||||
* returned.
|
||||
*/
|
||||
private ThemeVersion parsePreviewParam(final UriInfo uriInfo) {
|
||||
if (uriInfo.getQueryParameters().containsKey("preview")) {
|
||||
final List<String> values = uriInfo
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 Theming System with Jakarta EE MVC.
|
||||
*/
|
||||
package org.libreccm.theming.mvc;
|
||||
Loading…
Reference in New Issue