CCM NG: More utils for themes

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5211 8810af33-2d31-482b-a856-94f89814c4df
jensp 2018-01-21 13:57:40 +00:00
parent 6d05383adf
commit ed11b920a4
5 changed files with 196 additions and 27 deletions

View File

@ -25,26 +25,20 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.theming.ThemeInfo;
import org.libreccm.theming.ThemeProvider;
import org.libreccm.theming.Themes;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.io.Serializable;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.logging.Level;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
/**
* Methods for reading configuration options from the theme. Most themes have
@ -74,7 +68,9 @@ import javax.xml.stream.XMLStreamReader;
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class SettingsUtils {
public class SettingsUtils implements Serializable {
private static final long serialVersionUID = 8705552323418210749L;
private static final Logger LOGGER = LogManager
.getLogger(SettingsUtils.class);
@ -169,7 +165,7 @@ public class SettingsUtils {
/**
* Retrieve the boolean value of a setting. This method reads the value of a
* setting using null null null null null null null null null null null null
* null null null null null null null null null null {@link #getSetting(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
* null null null null null null null null null null null {@link #getSetting(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
* and converts it into a {@code boolean} value using
* {@link Boolean#parseBoolean(java.lang.String)}.
*

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2018 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.utils;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.servlet.ServletContext;
/**
* Several functions for usage in themes which provide access to system
* informations.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class SystemInfoUtils implements Serializable {
private static final long serialVersionUID = -4262885161214084949L;
@Inject
private ServletContext servletContext;
public String getContextPath() {
return servletContext.getContextPath();
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2018 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.utils;
import java.util.Objects;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class TextUtils {
/**
* Truncate a string to given length but preserve words. If the provided
* text is longer than the given length, this method will look for the
* last space before the index of the provided length can return the substring
* from the beginning to that position.
*
* @param text The text to truncate.
* @param length The length of the truncated text.
* @return The truncated text.
*/
public String truncateText(final String text,
final int length) {
Objects.requireNonNull(text);
if (text.length() <= length) {
return text;
} else {
final int lastSpace = text.lastIndexOf(" ", length);
return text.substring(0, lastSpace);
}
}
}

View File

@ -49,6 +49,8 @@ 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.Int64Value;
import net.sf.saxon.value.IntegerValue;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.StringValue;
import org.apache.logging.log4j.LogManager;
@ -56,6 +58,8 @@ import org.apache.logging.log4j.Logger;
import org.libreccm.theming.ProcessesThemes;
import org.libreccm.theming.manifest.ThemeTemplate;
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;
@ -88,12 +92,21 @@ 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 SettingsUtils settingsUtils;
@Inject
private SystemInfoUtils systemInfoUtils;
@Inject
private TextUtils textUtils;
@Override
public String process(final Map<String, Object> page,
final ThemeInfo theme,
@ -182,10 +195,13 @@ public class XsltThemeProcessor implements ThemeProcessor {
= (TransformerFactoryImpl) transformerFactory;
final Configuration configuration = transformerFactoryImpl
.getConfiguration();
configuration.registerExtensionFunction(new Greeter());
configuration
.registerExtensionFunction(new GetContextPathFunctionDefinition());
configuration
.registerExtensionFunction(
new GetSettingFunctionDefinition(theme, themeProvider));
configuration
.registerExtensionFunction(new TruncateTextFunctionDefinition());
final Transformer transformer;
try {
transformer = transformerFactory.newTransformer(xslFileStreamSource);
@ -237,7 +253,46 @@ public class XsltThemeProcessor implements ThemeProcessor {
return resultWriter.toString();
}
private class GetSettingFunctionDefinition extends ExtensionFunctionDefinition {
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;
@ -250,8 +305,8 @@ public class XsltThemeProcessor implements ThemeProcessor {
@Override
public StructuredQName getFunctionQName() {
return new StructuredQName("ccm",
"http://xmlns.libreccm.org",
return new StructuredQName(FUNCTION_XMLNS_PREFIX,
FUNCTION_XMLNS,
"getSetting");
}
@ -273,7 +328,7 @@ public class XsltThemeProcessor implements ThemeProcessor {
}
@Override
public SequenceType getResultType(final SequenceType[] sts) {
public SequenceType getResultType(final SequenceType[] arguments) {
return SequenceType.SINGLE_STRING;
}
@ -321,22 +376,24 @@ public class XsltThemeProcessor implements ThemeProcessor {
}
private class Greeter extends ExtensionFunctionDefinition {
private class TruncateTextFunctionDefinition
extends ExtensionFunctionDefinition {
@Override
public StructuredQName getFunctionQName() {
return new StructuredQName("ccm",
"http://xmlns.libreccm.org",
"greet");
return new StructuredQName(FUNCTION_XMLNS_PREFIX,
FUNCTION_XMLNS,
"truncateText");
}
@Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[]{SequenceType.SINGLE_STRING};
return new SequenceType[]{SequenceType.SINGLE_STRING,
SequenceType.SINGLE_INTEGER};
}
@Override
public SequenceType getResultType(final SequenceType[] sts) {
public SequenceType getResultType(final SequenceType[] arguments) {
return SequenceType.SINGLE_STRING;
}
@ -349,9 +406,11 @@ public class XsltThemeProcessor implements ThemeProcessor {
final Sequence[] arguments)
throws XPathException {
final String name = arguments[0].toString();
final String text = ((Item) arguments[0]).getStringValue();
final int length = Integer
.parseInt(((Item) arguments[1]).getStringValue());
return StringValue
.makeStringValue(String.format("Hello %s.", name));
.makeStringValue(textUtils.truncateText(text, length));
}
};

View File

@ -26,13 +26,16 @@
</p>
<xsl:value-of disable-output-escaping="true" select="./text" />
<h2>Example of Saxon Extension Function</h2>
<pre>
<xsl:value-of select="ccm:greet('John')" />
</pre>
<h2>Example of Theme Utils</h2>
<dl>
<dt>
<code>getContextPath</code>
</dt>
<dd>
<code>
<xsl:value-of select="ccm:getContextPath()" />
</code>
</dd>
<dt>
<code>getSetting</code>
</dt>
@ -41,6 +44,14 @@
<xsl:value-of select="ccm:getSetting('settings.properties', 'example.setting', 'n/a')" />
</code>
</dd>
<dt>
<code>truncateText</code>
</dt>
<dd>
<code>
<xsl:value-of select="ccm:truncateText('0123456789 123456789 123456789', 20)" />
</code>
</dd>
</dl>
</xsl:template>