diff --git a/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml b/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml
index ff0533652..427cbcdd0 100644
--- a/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml
+++ b/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml
@@ -80,10 +80,7 @@
-
-
-
Jens Pelzetter
- */
-class CcmUriResolver implements URIResolver {
-
- private static final Logger LOGGER = LogManager
- .getLogger(CcmUriResolver.class);
-
- private final String theme;
- private final ThemeVersion version;
- private final ThemeProvider themeProvider;
-
- protected CcmUriResolver(final String theme,
- final ThemeVersion version,
- final ThemeProvider themeProvider) {
-
- Objects.requireNonNull(theme);
- Objects.requireNonNull(version);
- Objects.requireNonNull(themeProvider);
-
- LOGGER.debug("Creating new instance of {} with these parameters:",
- getClass().getName());
- LOGGER.debug("\ttheme = {}", theme);
- LOGGER.debug("\tversion = {}", Objects.toString(version));
- LOGGER.debug("\tthemeProvider = {}",
- themeProvider.getClass().getName());
-
- this.theme = theme;
- this.version = version;
- this.themeProvider = themeProvider;
- }
-
- @Override
- public Source resolve(final String href,
- final String base) throws TransformerException {
-
- LOGGER.debug("Resolving href = \"{}\" using base = \"{}\"...",
- href,
- base);
-
- final String path;
- if (base == null) {
- path = href;
- } else {
- path = String.join("/", base, href);
- }
- LOGGER.debug("Using path \"{}\"...", path);
-
- final InputStream inputStream = themeProvider
- .getThemeFileAsStream(theme, version, path)
- .orElseThrow(() -> new TransformerException(String
- .format("Failed to resolve URI with href = \"%s\" and base = \"%s\" "
- + "for theme \"%s\" (version = \"%s\" using "
- + "ThemeProvider \"%s\".",
- href,
- base,
- theme,
- version,
- themeProvider.getClass().getName())));
-
- LOGGER.debug("Resolved href = \"{}\" with base \"{}\" successfully.",
- href,
- path);
- return new StreamSource(inputStream);
- }
-
-}
-
diff --git a/ccm-core/src/main/java/org/libreccm/theming/xslt/XsltThemeProcessor.java b/ccm-core/src/main/java/org/libreccm/theming/xslt/XsltThemeProcessor.java
deleted file mode 100644
index fdafe86e0..000000000
--- a/ccm-core/src/main/java/org/libreccm/theming/xslt/XsltThemeProcessor.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * 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.theming.xslt;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
-import com.fasterxml.jackson.dataformat.xml.XmlMapper;
-import org.libreccm.core.UnexpectedErrorException;
-import org.libreccm.theming.ThemeInfo;
-import org.libreccm.theming.ThemeProcessor;
-import org.libreccm.theming.ThemeProvider;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.util.Map;
-
-import javax.enterprise.context.RequestScoped;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import static org.libreccm.theming.ThemeConstants.*;
-
-import com.fasterxml.jackson.databind.SerializationFeature;
-import net.sf.saxon.Configuration;
-import net.sf.saxon.TransformerFactoryImpl;
-import net.sf.saxon.expr.XPathContext;
-import net.sf.saxon.lib.ExtensionFunctionCall;
-import net.sf.saxon.lib.ExtensionFunctionDefinition;
-import net.sf.saxon.om.Item;
-import net.sf.saxon.om.Sequence;
-import net.sf.saxon.om.StructuredQName;
-import net.sf.saxon.trans.XPathException;
-import net.sf.saxon.value.SequenceType;
-import net.sf.saxon.value.StringValue;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.libreccm.l10n.GlobalizationHelper;
-import org.libreccm.theming.ProcessesThemes;
-import org.libreccm.theming.Themes;
-import org.libreccm.theming.manifest.ThemeTemplate;
-import org.libreccm.theming.utils.L10NUtils;
-import org.libreccm.theming.utils.SettingsUtils;
-import org.libreccm.theming.utils.SystemInfoUtils;
-import org.libreccm.theming.utils.TextUtils;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-import java.util.Optional;
-import java.util.PropertyResourceBundle;
-import java.util.ResourceBundle;
-
-import javax.inject.Inject;
-import javax.xml.transform.ErrorListener;
-import javax.xml.transform.Result;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-/**
- * A {@link ThemeProcessor} implementation for XSLT based themes.
- *
- * @author Jens Pelzetter
- */
-@ProcessesThemes("xsl")
-@RequestScoped
-public class XsltThemeProcessor implements ThemeProcessor {
-
- private static final long serialVersionUID = -3883625727845105417L;
-
- private static final String FUNCTION_XMLNS = "http://xmlns.libreccm.org";
- private static final String FUNCTION_XMLNS_PREFIX = "ccm";
-
- private static final Logger LOGGER = LogManager
- .getLogger(XsltThemeProcessor.class);
-
- @Inject
- private L10NUtils l10nUtils;
-
- @Inject
- private SettingsUtils settingsUtils;
-
- @Inject
- private SystemInfoUtils systemInfoUtils;
-
- @Inject
- private TextUtils textUtils;
-
- @Inject
- private Themes themes;
-
- @Override
- public String process(final Map page,
- final ThemeInfo theme,
- final ThemeProvider themeProvider) {
-
- //Convert page to XML
- final JacksonXmlModule xmlModule = new JacksonXmlModule();
- final ObjectMapper mapper = new XmlMapper(xmlModule);
- mapper.enable(SerializationFeature.INDENT_OUTPUT);
-
- final String pageAsXml;
- try {
- pageAsXml = mapper
- .writer()
- .withRootName("page")
- .writeValueAsString(page);
- } catch (JsonProcessingException ex) {
- throw new UnexpectedErrorException(ex);
- }
-
- final DocumentBuilderFactory documentBuilderFactory
- = DocumentBuilderFactory.newInstance();
- final DocumentBuilder documentBuilder;
- try {
- documentBuilder = documentBuilderFactory.newDocumentBuilder();
- } catch (ParserConfigurationException ex) {
- throw new UnexpectedErrorException(ex);
- }
-
- final Document document;
- try {
- final InputStream xmlBytesStream = new ByteArrayInputStream(
- pageAsXml.getBytes(StandardCharsets.UTF_8));
- document = documentBuilder.parse(xmlBytesStream);
- } catch (SAXException | IOException ex) {
- throw new UnexpectedErrorException(ex);
- }
-
- final String pathToTemplate;
- if (page.containsKey(PAGE_PARAMETER_TEMPLATE)) {
-
- final String templateName = (String) page
- .get(PAGE_PARAMETER_TEMPLATE);
-
- final Optional template = theme
- .getManifest()
- .getTemplates()
- .stream()
- .filter(current -> current.getName().equals(templateName))
- .findAny();
-
- if (template.isPresent()) {
- pathToTemplate = template.get().getPath();
- } else {
- throw new UnexpectedErrorException(String
- .format("Theme \"%s\" does provide template \"%s\".",
- theme.getName(),
- templateName));
- }
- } else {
- pathToTemplate = theme.getManifest().getDefaultTemplate();
- }
-
- final InputStream xslFileInputStream = themes
- .getFileFromTheme(theme,
- pathToTemplate)
- .orElseThrow(() -> new UnexpectedErrorException(String
- .format("Failed to open XSL file \"%s\" from theme \"%s\" for "
- + "reading.",
- pathToTemplate,
- theme.getName())));
-
- final Reader reader;
- try {
- reader = new InputStreamReader(xslFileInputStream, "UTF-8");
- } catch (UnsupportedEncodingException ex) {
- throw new UnexpectedErrorException(ex);
- }
-
- final StreamSource xslFileStreamSource = new StreamSource(reader);
- final TransformerFactory transformerFactory = TransformerFactory
- .newInstance(TransformerFactoryImpl.class.getName(),
- getClass().getClassLoader());
- transformerFactory.setURIResolver(new CcmUriResolver(theme.getName(),
- theme.getVersion(),
- themeProvider));
- final TransformerFactoryImpl transformerFactoryImpl
- = (TransformerFactoryImpl) transformerFactory;
- final Configuration configuration = transformerFactoryImpl
- .getConfiguration();
- configuration
- .registerExtensionFunction(new GetContextPathFunctionDefinition());
- configuration
- .registerExtensionFunction(
- new GetSettingFunctionDefinition(theme, themeProvider));
- configuration
- .registerExtensionFunction(
- new LocalizeFunctionDefinition(theme, themeProvider));
- configuration
- .registerExtensionFunction(new TruncateTextFunctionDefinition());
- final Transformer transformer;
- try {
- transformer = transformerFactory.newTransformer(xslFileStreamSource);
- transformer.setErrorListener(new ErrorListener() {
-
- @Override
- public void warning(final TransformerException te)
- throws TransformerException {
-
- LOGGER.warn("A WARNING was reported by the "
- + "XSLT Transformer:",
- te);
- }
-
- @Override
- public void error(final TransformerException te)
- throws TransformerException {
-
- LOGGER.warn("An ERROR was reported by the "
- + "XSLT Transformer:",
- te);
- }
-
- @Override
- public void fatalError(final TransformerException te)
- throws TransformerException {
-
- LOGGER.warn("An FATAL ERROR was reported by the "
- + "XSLT Transformer:",
- te);
- }
-
- });
- } catch (TransformerConfigurationException ex) {
- throw new UnexpectedErrorException(ex);
- }
-
- final StringWriter resultWriter = new StringWriter();
- final Result result = new StreamResult(resultWriter);
- try {
- transformer.transform(new DOMSource(document), result);
- } catch (TransformerException ex) {
- throw new UnexpectedErrorException(ex);
- }
-
- return resultWriter.toString();
- }
-
- private class GetContextPathFunctionDefinition
- extends ExtensionFunctionDefinition {
-
- @Override
- public StructuredQName getFunctionQName() {
- return new StructuredQName(FUNCTION_XMLNS_PREFIX,
- FUNCTION_XMLNS,
- "getContextPath");
- }
-
- @Override
- public SequenceType[] getArgumentTypes() {
- return new SequenceType[]{};
- }
-
- @Override
- public SequenceType getResultType(final SequenceType[] arguments) {
- return SequenceType.SINGLE_STRING;
- }
-
- @Override
- public ExtensionFunctionCall makeCallExpression() {
- return new ExtensionFunctionCall() {
-
- @Override
- public Sequence call(final XPathContext xPathContext,
- final Sequence[] arguments)
- throws XPathException {
-
- return StringValue
- .makeStringValue(systemInfoUtils.getContextPath());
- }
-
- };
- }
-
- }
-
- private class GetSettingFunctionDefinition
- extends ExtensionFunctionDefinition {
-
- private final ThemeInfo theme;
- private final ThemeProvider themeProvider;
-
- public GetSettingFunctionDefinition(final ThemeInfo themeInfo,
- final ThemeProvider themeProvider) {
- this.theme = themeInfo;
- this.themeProvider = themeProvider;
- }
-
- @Override
- public StructuredQName getFunctionQName() {
- return new StructuredQName(FUNCTION_XMLNS_PREFIX,
- FUNCTION_XMLNS,
- "getSetting");
- }
-
- @Override
- public SequenceType[] getArgumentTypes() {
- return new SequenceType[]{SequenceType.SINGLE_STRING,
- SequenceType.SINGLE_STRING,
- SequenceType.SINGLE_STRING};
- }
-
- @Override
- public int getMinimumNumberOfArguments() {
- return 2;
- }
-
- @Override
- public int getMaximumNumberOfArguments() {
- return 3;
- }
-
- @Override
- public SequenceType getResultType(final SequenceType[] arguments) {
- return SequenceType.SINGLE_STRING;
- }
-
- @Override
- public ExtensionFunctionCall makeCallExpression() {
-
- return new ExtensionFunctionCall() {
-
- @Override
- public Sequence call(final XPathContext xPathContext,
- final Sequence[] arguments)
- throws XPathException {
-
- final String result;
- final String filePath = ((Item) arguments[0])
- .getStringValue();
- final String settingName = ((Item) arguments[1])
- .getStringValue();
- switch (arguments.length) {
- case 2:
- result = settingsUtils.getSetting(theme,
- themeProvider,
- filePath,
- settingName);
- break;
- case 3:
- final String defaultValue = ((Item) arguments[2])
- .getStringValue();
- result = settingsUtils.getSetting(theme,
- themeProvider,
- filePath,
- settingName,
- defaultValue);
- break;
- default:
- throw new UnexpectedErrorException(
- "Illegal number of arguments.");
- }
-
- return StringValue.makeStringValue(result);
- }
-
- };
- }
-
- }
-
- /**
- * Definition for XSL function for localising texts in the theme. Allows use
- * of {@link ResourceBundle}s instead of a custom XML format which was used
- * in legacy versions.
- *
- * The XSL function {@code ccm:localize} expects one mandatory parameter,
- * the {@code key} of the text to localise. The optional second parameter
- * {@code bundle} identifies the {@link ResourceBundle} to use. The
- * {@code bundle} parameter is passed to
- * {@link ResourceBundle#getBundle(java.lang.String)}. All bundle paths are
- * resolved relative to the root of the theme using {@link ThemeProvider}.
- * If the {@code bundle} parameter is omitted the function will look for
- * {@link PropertyResourceBundle} named {@code theme-bundle.properties} in
- * the root of the theme. Examples:
- *
- * {@code }
- *
- * In this case this function will load the file
- * {@code theme-bundle.properties} from the root of the theme and use it to
- * create an instance of {@link PropertyResourceBundle}. If this is
- * successful the key {@code footer.privacy} is lookup in the resource
- * bundle.
- *
- * {@code }
- *
- * In this case the function tries find a property file called
- * {@code footer.properties} in the texts directory in the theme.
- *
- * Of course the function, or better {@link ResourceBundle} will also take
- * into account the current locale, therefore in both examples the first
- * file name will be {@code footer_$locale.properties} where {@code $locale}
- * is the the locale returned by
- * {@link GlobalizationHelper#getNegotiatedLocale()}.
- */
- private class LocalizeFunctionDefinition
- extends ExtensionFunctionDefinition {
-
- private final ThemeInfo theme;
- private final ThemeProvider themeProvider;
-
- public LocalizeFunctionDefinition(final ThemeInfo theme,
- final ThemeProvider themeProvider) {
- super();
- this.theme = theme;
- this.themeProvider = themeProvider;
- }
-
- @Override
- public StructuredQName getFunctionQName() {
- return new StructuredQName(FUNCTION_XMLNS_PREFIX,
- FUNCTION_XMLNS,
- "localize");
- }
-
- @Override
- public SequenceType[] getArgumentTypes() {
- return new SequenceType[]{SequenceType.SINGLE_STRING};
- }
-
- @Override
- public int getMaximumNumberOfArguments() {
- return 2;
- }
-
- @Override
- public SequenceType getResultType(final SequenceType[] arguments) {
- return SequenceType.SINGLE_STRING;
- }
-
- @Override
- public ExtensionFunctionCall makeCallExpression() {
- return new ExtensionFunctionCall() {
-
- @Override
- public Sequence call(final XPathContext xPathContext,
- final Sequence[] arguments)
- throws XPathException {
-
- final String bundle;
- if (arguments.length > 1) {
- bundle = ((Item) arguments[1]).getStringValue();
- } else {
- bundle = "theme-bundle";
- }
- final String key = ((Item) arguments[0]).getStringValue();
-
- LOGGER.debug("Localizing key \"{}\" from bundle \"{}\"...",
- key,
- bundle);
-
- return StringValue
- .makeStringValue(l10nUtils.getText(theme,
- themeProvider,
- bundle,
- key));
- }
-
- };
- }
-
- }
-
- private class TruncateTextFunctionDefinition
- extends ExtensionFunctionDefinition {
-
- @Override
- public StructuredQName getFunctionQName() {
- return new StructuredQName(FUNCTION_XMLNS_PREFIX,
- FUNCTION_XMLNS,
- "truncateText");
- }
-
- @Override
- public SequenceType[] getArgumentTypes() {
- return new SequenceType[]{SequenceType.SINGLE_STRING,
- SequenceType.SINGLE_INTEGER};
- }
-
- @Override
- public SequenceType getResultType(final SequenceType[] arguments) {
- return SequenceType.SINGLE_STRING;
- }
-
- @Override
- public ExtensionFunctionCall makeCallExpression() {
- return new ExtensionFunctionCall() {
-
- @Override
- public Sequence call(final XPathContext xPathContext,
- final Sequence[] arguments)
- throws XPathException {
-
- final String text = ((Item) arguments[0]).getStringValue();
- final int length = Integer
- .parseInt(((Item) arguments[1]).getStringValue());
- return StringValue
- .makeStringValue(textUtils.truncateText(text, length));
- }
-
- };
- }
-
- }
-
-}
diff --git a/ccm-core/src/main/java/org/libreccm/theming/xslt/package-info.java b/ccm-core/src/main/java/org/libreccm/theming/xslt/package-info.java
deleted file mode 100644
index 43076b904..000000000
--- a/ccm-core/src/main/java/org/libreccm/theming/xslt/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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
- */
-/**
- * Support of legacy XSL based themes.
- */
-package org.libreccm.theming.xslt;