Removed XSLT theme processor, not used anymore.
parent
15dcc9a39e
commit
1161053c81
|
|
@ -80,10 +80,7 @@
|
|||
<Logger name="org.libreccm.security.Shiro"
|
||||
level="debug">
|
||||
</Logger>
|
||||
<Logger name="org.libreccm.theming.xslt.CcmUriResolver"
|
||||
level="debug">
|
||||
</Logger>
|
||||
<Logger name="org.libreccm.ui.admin.usersgroupsroles.RolesController"
|
||||
<Logger name="org.libreccm.ui.admin.usersgroupsroles.RolesController"
|
||||
level="debug">
|
||||
</Logger>
|
||||
<Logger name="org.librecms.contentsection.AssetRepository"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ package org.libreccm.theming.utils;
|
|||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.theming.ThemeInfo;
|
||||
import org.libreccm.theming.ThemeProvider;
|
||||
import org.libreccm.theming.xslt.XsltThemeProcessor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
|
|||
|
|
@ -1,102 +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 org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.theming.ThemeProvider;
|
||||
import org.libreccm.theming.ThemeVersion;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@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<String, Object> 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<ThemeTemplate> 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 <xsl:value-of select="ccm:localize('footer.privacy')" />}
|
||||
*
|
||||
* 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 <xsl:value-of select="ccm:localize('footer.privacy', '/texts/footer')" />}
|
||||
*
|
||||
* 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));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
Loading…
Reference in New Issue