This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.scripting.thymeleaf-1.0.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-thymeleaf.git
commit 1e705d1df8bede4eba93b12eb84a4085794d06f2 Author: Oliver Lietz <[email protected]> AuthorDate: Mon Dec 7 12:23:45 2015 +0000 SLING-5075 Upgrade Thymeleaf to 3.0 * update to Thymeleaf 3.0.0.BETA01 and AttoParser 2.0.0.BETA04 * update dependencies * merge supporting attribute tag processors into Sling include processor * fix bug with HTML PatternSpec in NonCachingTemplateResolver git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/scripting/thymeleaf@1718329 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 27 +++--- .../internal/NonCachingTemplateResolver.java | 55 ++++++++----- .../internal/ResourceBundleMessageResolver.java | 18 ++-- .../thymeleaf/internal/SlingResourceResolver.java | 95 ---------------------- .../thymeleaf/internal/SlingTemplateResource.java | 69 ++++++++++++++++ .../thymeleaf/internal/ThymeleafScriptEngine.java | 2 + .../internal/ThymeleafScriptEngineFactory.java | 21 ++--- .../thymeleaf/internal/dialect/SlingDialect.java | 10 --- .../SlingAddSelectorsAttributeProcessor.java | 40 --------- .../SlingIncludeAttributeTagProcessor.java | 65 ++++++++++----- .../SlingLocalVariableAttributeTagProcessor.java | 50 ------------ ...SlingReplaceSelectorsAttributeTagProcessor.java | 40 --------- .../SlingReplaceSuffixAttributeTagProcessor.java | 40 --------- .../SlingResourceTypeAttributeTagProcessor.java | 40 --------- .../SlingUnwrapAttributeTagProcessor.java | 40 --------- .../OSGI-INF/metatype/metatype.properties | 3 + 16 files changed, 181 insertions(+), 434 deletions(-) diff --git a/pom.xml b/pom.xml index f8792d8..fc65b5c 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ <parent> <groupId>org.apache.sling</groupId> <artifactId>sling</artifactId> - <version>25</version> + <version>26-SNAPSHOT</version> <relativePath /> </parent> @@ -38,8 +38,8 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> - <org.thymeleaf.version>3.0.0.ALPHA03</org.thymeleaf.version> - <org.attoparser.version>2.0.0.BETA3</org.attoparser.version> + <org.thymeleaf.version>3.0.0.BETA01</org.thymeleaf.version> + <org.attoparser.version>2.0.0.BETA04</org.attoparser.version> <org.unbescape.version>1.1.1.RELEASE</org.unbescape.version> <ognl.version>3.1</ognl.version> </properties> @@ -79,31 +79,31 @@ <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> - <version>2.7.0</version> + <version>2.9.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.scripting.api</artifactId> - <version>2.1.6</version> + <version>2.1.8</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.scripting.core</artifactId> - <version>2.0.30</version> + <version>2.0.34</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.commons.osgi</artifactId> - <version>2.2.0</version> + <version>2.3.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.i18n</artifactId> - <version>2.2.8</version> + <version>2.4.4</version> <scope>provided</scope> </dependency> <!-- Apache Felix --> @@ -148,7 +148,7 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.7</version> + <version>1.7.13</version> <scope>provided</scope> </dependency> </dependencies> @@ -172,21 +172,14 @@ <instructions> <Export-Package> org.apache.sling.scripting.thymeleaf, - org.thymeleaf.*;version=${org.thymeleaf.version}, + org.thymeleaf.*;version=${org.thymeleaf.version};-split-package:=merge-first, org.attoparser.*;version=${org.attoparser.version}, org.unbescape.*;version=${org.unbescape.version}, ognl.*;version=${ognl.version} </Export-Package> - <Import-Package> - org.apache.commons.io.input;version="1.4.9999", - * - </Import-Package> <DynamicImport-Package> * </DynamicImport-Package> - <Embed-Dependency> - *;scope=compile;inline=true - </Embed-Dependency> <ScriptEngine-Name>${project.name}</ScriptEngine-Name> <ScriptEngine-Version>${project.version}</ScriptEngine-Version> <_removeheaders> diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java index aeda2a1..8e71908 100644 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java +++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java @@ -21,6 +21,7 @@ package org.apache.sling.scripting.thymeleaf.internal; import java.util.Collections; import java.util.Dictionary; import java.util.HashSet; +import java.util.Map; import java.util.Set; import org.apache.felix.scr.annotations.Activate; @@ -30,8 +31,10 @@ import org.apache.felix.scr.annotations.Modified; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.PropertyUnbounded; -import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingScriptConstants; import org.apache.sling.commons.osgi.PropertiesUtil; import org.osgi.framework.Constants; import org.osgi.service.component.ComponentContext; @@ -41,10 +44,10 @@ import org.thymeleaf.IEngineConfiguration; import org.thymeleaf.cache.ICacheEntryValidity; import org.thymeleaf.cache.NonCacheableCacheEntryValidity; import org.thymeleaf.context.IContext; -import org.thymeleaf.resourceresolver.IResourceResolver; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ITemplateResolver; import org.thymeleaf.templateresolver.TemplateResolution; +import org.thymeleaf.templateresource.ITemplateResource; import org.thymeleaf.util.PatternSpec; @Component( @@ -66,9 +69,6 @@ import org.thymeleaf.util.PatternSpec; }) public class NonCachingTemplateResolver implements ITemplateResolver { - @Reference - private IResourceResolver resourceResolver; - private Integer order; public static final int DEFAULT_ORDER = 0; @@ -76,13 +76,6 @@ public class NonCachingTemplateResolver implements ITemplateResolver { @Property(intValue = DEFAULT_ORDER) public static final String ORDER_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.order"; - private String encoding; - - public static final String DEFAULT_ENCODING = "UTF-8"; - - @Property(value = DEFAULT_ENCODING) - public static final String ENCODING_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.encoding"; - private final PatternSpec htmlPatternSpec = new PatternSpec(); @Property(unbounded = PropertyUnbounded.ARRAY) @@ -108,6 +101,11 @@ public class NonCachingTemplateResolver implements ITemplateResolver { @Property(unbounded = PropertyUnbounded.ARRAY) public static final String CSS_PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.cssPatterns"; + private final PatternSpec rawPatternSpec = new PatternSpec(); + + @Property(unbounded = PropertyUnbounded.ARRAY) + public static final String RAW_PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.rawPatterns"; + private final Logger logger = LoggerFactory.getLogger(NonCachingTemplateResolver.class); public NonCachingTemplateResolver() { @@ -133,22 +131,30 @@ public class NonCachingTemplateResolver implements ITemplateResolver { private void configure(final ComponentContext componentContext) { final Dictionary properties = componentContext.getProperties(); order = PropertiesUtil.toInteger(properties.get(ORDER_PARAMETER), DEFAULT_ORDER); - encoding = PropertiesUtil.toString(properties.get(ENCODING_PARAMETER), DEFAULT_ENCODING); // HTML final String[] htmlPatterns = PropertiesUtil.toStringArray(properties.get(HTML_PATTERNS_PARAMETER), new String[]{}); setPatterns(htmlPatterns, htmlPatternSpec); + logger.debug("HTML Pattern Spec: {}", htmlPatternSpec.getPatterns()); // XML final String[] xmlPatterns = PropertiesUtil.toStringArray(properties.get(XML_PATTERNS_PARAMETER), new String[]{}); - setPatterns(xmlPatterns, htmlPatternSpec); + setPatterns(xmlPatterns, xmlPatternSpec); + logger.debug("XML Pattern Spec: {}", xmlPatternSpec.getPatterns()); // TEXT final String[] textPatterns = PropertiesUtil.toStringArray(properties.get(TEXT_PATTERNS_PARAMETER), new String[]{}); setPatterns(textPatterns, textPatternSpec); + logger.debug("TEXT Pattern Spec: {}", textPatternSpec.getPatterns()); // JAVASCRIPT final String[] javascriptPatterns = PropertiesUtil.toStringArray(properties.get(JAVASCRIPT_PATTERNS_PARAMETER), new String[]{}); setPatterns(javascriptPatterns, javascriptPatternSpec); + logger.debug("JAVASCRIPT Pattern Spec: {}", javascriptPatternSpec.getPatterns()); // CSS final String[] cssPatterns = PropertiesUtil.toStringArray(properties.get(CSS_PATTERNS_PARAMETER), new String[]{}); setPatterns(cssPatterns, cssPatternSpec); + logger.debug("CSS Pattern Spec: {}", cssPatternSpec.getPatterns()); + // RAW + final String[] rawPatterns = PropertiesUtil.toStringArray(properties.get(RAW_PATTERNS_PARAMETER), new String[]{}); + setPatterns(rawPatterns, rawPatternSpec); + logger.debug("RAW Pattern Spec: {}", rawPatternSpec.getPatterns()); } private void setPatterns(final String[] strings, final PatternSpec patternSpec) { @@ -168,16 +174,18 @@ public class NonCachingTemplateResolver implements ITemplateResolver { } @Override - public TemplateResolution resolveTemplate(final IEngineConfiguration configuration, final IContext context, final String templateName) { - final String resourceName = templateName; - final String characterEncoding = encoding; - final TemplateMode templateMode = computeTemplateMode(templateName); - final ICacheEntryValidity cacheEntryValidity = new NonCacheableCacheEntryValidity(); + public TemplateResolution resolveTemplate(final IEngineConfiguration engineConfiguration, final IContext context, final String ownerTemplate, final String template, final Map<String, Object> templateResolutionAttributes) { + logger.debug("resolving template '{}'", template); + final TemplateMode templateMode = computeTemplateMode(template); if (templateMode != null) { - logger.debug("using template mode '{}' for template '{}'", templateMode, templateName); - return new TemplateResolution(templateName, resourceName, resourceResolver, characterEncoding, templateMode, cacheEntryValidity); + logger.debug("using template mode '{}' for template '{}'", templateMode, template); + final ResourceResolver resourceResolver = (ResourceResolver) context.getVariable(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER); + final Resource resource = resourceResolver.getResource(template); + final ITemplateResource templateResource = new SlingTemplateResource(resource); + final ICacheEntryValidity cacheEntryValidity = new NonCacheableCacheEntryValidity(); + return new TemplateResolution(templateResource, templateMode, cacheEntryValidity); } else { - logger.warn("no template mode for template '{}'", templateName); + logger.warn("no template mode for template '{}'", template); return null; // will fail at caller } } @@ -198,6 +206,9 @@ public class NonCachingTemplateResolver implements ITemplateResolver { if (cssPatternSpec.matches(templateName)) { return TemplateMode.CSS; } + if (rawPatternSpec.matches(templateName)) { + return TemplateMode.RAW; + } return null; } diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java index 69e028c..bfeb2db 100644 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java +++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java @@ -18,10 +18,7 @@ */ package org.apache.sling.scripting.thymeleaf.internal; -import java.text.MessageFormat; import java.util.Dictionary; -import java.util.Locale; -import java.util.ResourceBundle; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; @@ -37,9 +34,8 @@ import org.osgi.framework.Constants; import org.osgi.service.component.ComponentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.thymeleaf.context.ITemplateProcessingContext; +import org.thymeleaf.context.ITemplateContext; import org.thymeleaf.messageresolver.IMessageResolver; -import org.thymeleaf.messageresolver.MessageResolution; @Component( label = "Apache Sling Scripting Thymeleaf “Resource Bundle Message Resolver”", @@ -104,6 +100,17 @@ public class ResourceBundleMessageResolver implements IMessageResolver { } @Override + public String resolveMessage(ITemplateContext context, Class<?> origin, String key, Object[] messageParameters) { + return null; + } + + @Override + public String createAbsentMessageRepresentation(ITemplateContext context, Class<?> origin, String key, Object[] messageParameters) { + return null; + } + + /* + @Override public MessageResolution resolveMessage(final ITemplateProcessingContext processingContext, final String key, final Object[] messageParameters) { logger.debug("processingContext: {}, key: {}, message parameters: {}", processingContext, key, messageParameters); final Locale locale = processingContext.getLocale(); @@ -113,5 +120,6 @@ public class ResourceBundleMessageResolver implements IMessageResolver { final String message = messageFormat.format((messageParameters != null ? messageParameters : EMPTY_MESSAGE_PARAMETERS)); return new MessageResolution(message); } + */ } diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingResourceResolver.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingResourceResolver.java deleted file mode 100644 index bf5bb14..0000000 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingResourceResolver.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sling.scripting.thymeleaf.internal; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.io.IOUtils; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Properties; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.Service; -import org.apache.sling.api.resource.Resource; -import org.apache.sling.api.resource.ResourceResolver; -import org.apache.sling.api.scripting.SlingScriptConstants; -import org.apache.sling.scripting.thymeleaf.SlingContext; -import org.osgi.framework.Constants; -import org.thymeleaf.IEngineConfiguration; -import org.thymeleaf.context.IContext; -import org.thymeleaf.context.IWebVariablesMap; -import org.thymeleaf.exceptions.TemplateProcessingException; -import org.thymeleaf.resource.CharArrayResource; -import org.thymeleaf.resource.IResource; -import org.thymeleaf.resourceresolver.IResourceResolver; -import org.thymeleaf.util.Validate; - -@Component( - label = "Apache Sling Scripting Thymeleaf “Sling Resource Resolver”", - description = "Sling resource resolver for Sling Scripting Thymeleaf", - immediate = true, - metatype = true -) -@Service -@Properties({ - @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"), - @Property(name = Constants.SERVICE_DESCRIPTION, value = "Sling resource resolver for Sling Scripting Thymeleaf"), - @Property(name = Constants.SERVICE_RANKING, intValue = 0, propertyPrivate = false) -}) -public class SlingResourceResolver implements IResourceResolver { - - public SlingResourceResolver() { - } - - @Override - public String getName() { - return getClass().getName(); - } - - @Override - public IResource resolveResource(final IEngineConfiguration engineConfiguration, final IContext context, final String resourceName, final String characterEncoding) { - Validate.notNull(context, "context cannot be null"); - Validate.notNull(context, "resource name cannot be null"); - if (context instanceof SlingContext) { - final SlingContext slingContext = (SlingContext) context; - final ResourceResolver resourceResolver = slingContext.getResourceResolver(); - return resolveResource(resourceResolver, resourceName); - } else if (context instanceof IWebVariablesMap) { // TODO Thymeleaf #388 - final IWebVariablesMap webVariablesMap = (IWebVariablesMap) context; - final ResourceResolver resourceResolver = (ResourceResolver) webVariablesMap.getVariable(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER); - return resolveResource(resourceResolver, resourceName); - } else { - final String message = String.format("Cannot handle context: %s", context.getClass().getName()); - throw new TemplateProcessingException(message); - } - } - - private IResource resolveResource(final ResourceResolver resourceResolver, final String resourceName) { - final Resource resource = resourceResolver.getResource(resourceName); - final InputStream inputStream = resource.adaptTo(InputStream.class); - try { - final char[] content = IOUtils.toCharArray(inputStream); - return new CharArrayResource(resourceName, content); - } catch (IOException e) { - final String message = String.format("Cannot read from resource '%s'", resourceName); - throw new TemplateProcessingException(message, e); - } - } - -} diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingTemplateResource.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingTemplateResource.java new file mode 100644 index 0000000..0422d1a --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingTemplateResource.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.thymeleaf.internal; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import org.apache.sling.api.resource.NonExistingResource; +import org.apache.sling.api.resource.Resource; +import org.thymeleaf.templateresource.ITemplateResource; + +public class SlingTemplateResource implements ITemplateResource { + + private final Resource resource; + + private Reader reader; + + public SlingTemplateResource(final Resource resource) { + this.resource = resource; + } + + @Override + public String getDescription() { + return resource.getPath(); + } + + @Override + public String getBaseName() { + return resource.getName(); + } + + @Override + public boolean exists() { + return !(resource instanceof NonExistingResource); + } + + @Override + public Reader reader() throws IOException { + if (reader == null) { + final InputStream inputStream = resource.adaptTo(InputStream.class); + reader = new InputStreamReader(inputStream); + } + return reader; + } + + @Override + public ITemplateResource relative(final String relativeLocation) throws IOException { + return null; // TODO + } + +} diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java index 05ae90b..736bbb4 100644 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java +++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java @@ -68,6 +68,8 @@ public final class ThymeleafScriptEngine extends AbstractSlingScriptEngine { try { final IContext context = new DefaultSlingContext(resourceResolver, locale, bindings); + // TODO optimize, process() calls TemplateManager which does resolving, parsing and processing + // resolving is already done by Sling, so we need a parsing and processing only call into TemplateEngine thymeleafScriptEngineFactory.getTemplateEngine().process(scriptName, context, writer); } catch (Exception e) { logger.error("Failure rendering Thymeleaf template '{}': {}", scriptName, e.getMessage()); diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java index a1afadd..615a3a8 100644 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java +++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java @@ -163,23 +163,18 @@ public final class ThymeleafScriptEngineFactory extends AbstractScriptEngineFact // the configuration of the Thymeleaf TemplateEngine is static and we need to recreate on modification private synchronized void configureTemplateEngine() { - logger.info("configure template engine"); - final TemplateEngine templateEngine = new TemplateEngine(); - if (templateResolvers.size() > 0) { - templateEngine.setTemplateResolvers(templateResolvers); - } - if (messageResolvers.size() > 0) { - templateEngine.setMessageResolvers(messageResolvers); - } - if (dialects.size() > 0) { - templateEngine.setDialects(dialects); - final IDialect standardDialect = new StandardDialect(); - templateEngine.addDialect(standardDialect); + logger.info("configuring template engine"); + if (templateEngine == null || templateEngine.isInitialized()) { + templateEngine = new TemplateEngine(); } + templateEngine.setTemplateResolvers(templateResolvers); + templateEngine.setMessageResolvers(messageResolvers); + templateEngine.setDialects(dialects); + final IDialect standardDialect = new StandardDialect(); + templateEngine.addDialect(standardDialect); // TODO // final ICacheManager cacheManager = null; // templateEngine.setCacheManager(cacheManager); - this.templateEngine = templateEngine; } @Override diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java index 1ffe8bd..ccaa3eb 100644 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java +++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java @@ -25,12 +25,7 @@ import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Service; -import org.apache.sling.scripting.thymeleaf.internal.processor.SlingAddSelectorsAttributeProcessor; import org.apache.sling.scripting.thymeleaf.internal.processor.SlingIncludeAttributeTagProcessor; -import org.apache.sling.scripting.thymeleaf.internal.processor.SlingReplaceSelectorsAttributeTagProcessor; -import org.apache.sling.scripting.thymeleaf.internal.processor.SlingReplaceSuffixAttributeTagProcessor; -import org.apache.sling.scripting.thymeleaf.internal.processor.SlingResourceTypeAttributeTagProcessor; -import org.apache.sling.scripting.thymeleaf.internal.processor.SlingUnwrapAttributeTagProcessor; import org.osgi.framework.Constants; import org.thymeleaf.dialect.AbstractProcessorDialect; import org.thymeleaf.processor.IProcessor; @@ -62,12 +57,7 @@ public final class SlingDialect extends AbstractProcessorDialect { @Override public Set<IProcessor> getProcessors(final String prefix) { final Set<IProcessor> processors = new HashSet<IProcessor>(); - processors.add(new SlingAddSelectorsAttributeProcessor(this, prefix)); processors.add(new SlingIncludeAttributeTagProcessor(this, prefix)); - processors.add(new SlingReplaceSelectorsAttributeTagProcessor(this, prefix)); - processors.add(new SlingReplaceSuffixAttributeTagProcessor(this, prefix)); - processors.add(new SlingResourceTypeAttributeTagProcessor(this, prefix)); - processors.add(new SlingUnwrapAttributeTagProcessor(this, prefix)); return processors; } diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingAddSelectorsAttributeProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingAddSelectorsAttributeProcessor.java deleted file mode 100644 index c63df81..0000000 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingAddSelectorsAttributeProcessor.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sling.scripting.thymeleaf.internal.processor; - -import org.thymeleaf.dialect.IProcessorDialect; - -public final class SlingAddSelectorsAttributeProcessor extends SlingLocalVariableAttributeTagProcessor { - - public static final int ATTRIBUTE_PRECEDENCE = 99; - - public static final String ATTRIBUTE_NAME = "addSelectors"; - - public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME); - - public SlingAddSelectorsAttributeProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) { - super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE); - } - - @Override - protected String getLocalVariableName() { - return NODE_PROPERTY_NAME; - } - -} diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingIncludeAttributeTagProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingIncludeAttributeTagProcessor.java index 304afb7..01fed6b 100644 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingIncludeAttributeTagProcessor.java +++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingIncludeAttributeTagProcessor.java @@ -29,13 +29,12 @@ import org.apache.sling.api.request.RequestDispatcherOptions; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceUtil; import org.apache.sling.api.resource.SyntheticResource; +import org.apache.sling.api.scripting.SlingBindings; import org.apache.sling.scripting.core.servlet.CaptureResponseWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.thymeleaf.IEngineConfiguration; -import org.thymeleaf.context.ITemplateProcessingContext; -import org.thymeleaf.context.IVariablesMap; -import org.thymeleaf.context.IWebVariablesMap; +import org.thymeleaf.context.ITemplateContext; import org.thymeleaf.dialect.IProcessorDialect; import org.thymeleaf.engine.AttributeName; import org.thymeleaf.model.IProcessableElementTag; @@ -50,6 +49,16 @@ public class SlingIncludeAttributeTagProcessor extends SlingHtmlAttributeTagProc public static final String ATTRIBUTE_NAME = "include"; + public static final String ADD_SELECTORS_ATTRIBUTE_NAME = "addSelectors"; + + public static final String REPLACE_SELECTORS_ATTRIBUTE_NAME = "replaceSelectors"; + + public static final String REPLACE_SUFFIX_ATTRIBUTE_NAME = "replaceSuffix"; + + public static final String RESOURCE_TYPE_ATTRIBUTE_NAME = "resourceType"; + + public static final String UNWRAP_ATTRIBUTE_NAME = "unwrap"; + private final Logger logger = LoggerFactory.getLogger(SlingIncludeAttributeTagProcessor.class); public SlingIncludeAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) { @@ -57,18 +66,15 @@ public class SlingIncludeAttributeTagProcessor extends SlingHtmlAttributeTagProc } @Override - protected void doProcess(final ITemplateProcessingContext processingContext, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final String tagTemplateName, final int tagLine, final int tagCol, final IElementTagStructureHandler elementTagStructureHandler) { - // final IContext context = arguments.getTemplateProcessingParameters().getContext(); - // if (context instanceof SlingWebContext) { + protected void doProcess(final ITemplateContext templateContext, final IProcessableElementTag processableElementTag, final AttributeName attributeName, final String attributeValue, final String tagTemplateName, final int tagLine, final int tagCol, final IElementTagStructureHandler elementTagStructureHandler) { try { - final IWebVariablesMap webVariablesMap = (IWebVariablesMap) processingContext.getVariables(); - final SlingHttpServletRequest slingHttpServletRequest = (SlingHttpServletRequest) webVariablesMap.getRequest(); - final SlingHttpServletResponse slingHttpServletResponse = (SlingHttpServletResponse) webVariablesMap.getResponse(); + final SlingHttpServletRequest slingHttpServletRequest = (SlingHttpServletRequest) templateContext.getVariable(SlingBindings.REQUEST); + final SlingHttpServletResponse slingHttpServletResponse = (SlingHttpServletResponse) templateContext.getVariable(SlingBindings.RESPONSE); - final IEngineConfiguration configuration = processingContext.getConfiguration(); + final IEngineConfiguration configuration = templateContext.getConfiguration(); final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration); - final IStandardExpression expression = expressionParser.parseExpression(processingContext, attributeValue); - final Object include = expression.execute(processingContext); + final IStandardExpression expression = expressionParser.parseExpression(templateContext, attributeValue); + final Object include = expression.execute(templateContext); String path = null; if (include instanceof String) { @@ -79,14 +85,13 @@ public class SlingIncludeAttributeTagProcessor extends SlingHtmlAttributeTagProc resource = (Resource) include; } // request dispatcher options - final RequestDispatcherOptions requestDispatcherOptions = prepareRequestDispatcherOptions(webVariablesMap); + final RequestDispatcherOptions requestDispatcherOptions = prepareRequestDispatcherOptions(expressionParser, templateContext, processableElementTag); // dispatch final String content = dispatch(resource, path, slingHttpServletRequest, slingHttpServletResponse, requestDispatcherOptions); - // cleanup - tag.getAttributes().removeAttribute(attributeName); - // element.clearChildren(); + // cleanup TODO: still needed? + // processableElementTag.getAttributes().removeAttribute(attributeName); // add output - final Boolean unwrap = (Boolean) webVariablesMap.getVariable(SlingUnwrapAttributeTagProcessor.NODE_PROPERTY_NAME); + final Boolean unwrap = (Boolean) parseAttribute(expressionParser, templateContext, processableElementTag, UNWRAP_ATTRIBUTE_NAME); if (unwrap != null && unwrap) { elementTagStructureHandler.replaceWith(content, false); } else { @@ -97,11 +102,27 @@ public class SlingIncludeAttributeTagProcessor extends SlingHtmlAttributeTagProc } } - protected RequestDispatcherOptions prepareRequestDispatcherOptions(final IVariablesMap variablesMap) { - final String resourceType = (String) variablesMap.getVariable(SlingResourceTypeAttributeTagProcessor.NODE_PROPERTY_NAME); - final String replaceSelectors = (String) variablesMap.getVariable(SlingReplaceSelectorsAttributeTagProcessor.NODE_PROPERTY_NAME); - final String addSelectors = (String) variablesMap.getVariable(SlingAddSelectorsAttributeProcessor.NODE_PROPERTY_NAME); - final String replaceSuffix = (String) variablesMap.getVariable(SlingReplaceSuffixAttributeTagProcessor.NODE_PROPERTY_NAME); + protected Object parseAttribute(final IStandardExpressionParser expressionParser, final ITemplateContext templateContext, final IProcessableElementTag processableElementTag, final String name) { + final String attributeValue = processableElementTag.getAttributes().getValue(getDialect().getPrefix(), name); + final IStandardExpression expression = expressionParser.parseExpression(templateContext, attributeValue); + return expression.execute(templateContext); + } + + protected RequestDispatcherOptions prepareRequestDispatcherOptions(final IStandardExpressionParser expressionParser, final ITemplateContext templateContext, final IProcessableElementTag processableElementTag) { + final String prefix = getDialect().getPrefix(); + + final String resourceType = (String) parseAttribute(expressionParser, templateContext, processableElementTag, RESOURCE_TYPE_ATTRIBUTE_NAME); + processableElementTag.getAttributes().removeAttribute(prefix, RESOURCE_TYPE_ATTRIBUTE_NAME); + + final String replaceSelectors = (String) parseAttribute(expressionParser, templateContext, processableElementTag, REPLACE_SELECTORS_ATTRIBUTE_NAME); + processableElementTag.getAttributes().removeAttribute(prefix, REPLACE_SELECTORS_ATTRIBUTE_NAME); + + final String addSelectors = (String) parseAttribute(expressionParser, templateContext, processableElementTag, ADD_SELECTORS_ATTRIBUTE_NAME); + processableElementTag.getAttributes().removeAttribute(prefix, ADD_SELECTORS_ATTRIBUTE_NAME); + + final String replaceSuffix = (String) parseAttribute(expressionParser, templateContext, processableElementTag, REPLACE_SUFFIX_ATTRIBUTE_NAME); + processableElementTag.getAttributes().removeAttribute(prefix, REPLACE_SUFFIX_ATTRIBUTE_NAME); + final RequestDispatcherOptions options = new RequestDispatcherOptions(); options.setForceResourceType(resourceType); options.setReplaceSelectors(replaceSelectors); diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingLocalVariableAttributeTagProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingLocalVariableAttributeTagProcessor.java deleted file mode 100644 index 867719a..0000000 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingLocalVariableAttributeTagProcessor.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sling.scripting.thymeleaf.internal.processor; - -import org.thymeleaf.IEngineConfiguration; -import org.thymeleaf.context.ITemplateProcessingContext; -import org.thymeleaf.dialect.IProcessorDialect; -import org.thymeleaf.engine.AttributeName; -import org.thymeleaf.model.IProcessableElementTag; -import org.thymeleaf.processor.element.IElementTagStructureHandler; -import org.thymeleaf.standard.expression.IStandardExpression; -import org.thymeleaf.standard.expression.IStandardExpressionParser; -import org.thymeleaf.standard.expression.StandardExpressions; - -public abstract class SlingLocalVariableAttributeTagProcessor extends SlingHtmlAttributeTagProcessor { - - public static final String LOCAL_VARIABLE_PREFIX = "sling"; - - public SlingLocalVariableAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix, final String attributeName, final int precedence) { - super(processorDialect, dialectPrefix, attributeName, precedence, true); - } - - protected abstract String getLocalVariableName(); - - @Override - protected void doProcess(final ITemplateProcessingContext templateProcessingContext, final IProcessableElementTag processableElementTag, final AttributeName attributeName, final String attributeValue, final String attributeTemplateName, final int attributeLine, final int attributeCol, final IElementTagStructureHandler structureHandler) { - final IEngineConfiguration configuration = templateProcessingContext.getConfiguration(); - final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration); - final IStandardExpression expression = expressionParser.parseExpression(templateProcessingContext, attributeValue); - final Object result = expression.execute(templateProcessingContext); - structureHandler.setLocalVariable(getLocalVariableName(), result); - } - -} diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSelectorsAttributeTagProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSelectorsAttributeTagProcessor.java deleted file mode 100644 index dec3409..0000000 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSelectorsAttributeTagProcessor.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sling.scripting.thymeleaf.internal.processor; - -import org.thymeleaf.dialect.IProcessorDialect; - -public final class SlingReplaceSelectorsAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor { - - public static final int ATTRIBUTE_PRECEDENCE = 99; - - public static final String ATTRIBUTE_NAME = "replaceSelectors"; - - public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME); - - public SlingReplaceSelectorsAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) { - super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE); - } - - @Override - protected String getLocalVariableName() { - return NODE_PROPERTY_NAME; - } - -} diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSuffixAttributeTagProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSuffixAttributeTagProcessor.java deleted file mode 100644 index 1d7ae66..0000000 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSuffixAttributeTagProcessor.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sling.scripting.thymeleaf.internal.processor; - -import org.thymeleaf.dialect.IProcessorDialect; - -public final class SlingReplaceSuffixAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor { - - public static final int ATTRIBUTE_PRECEDENCE = 99; - - public static final String ATTRIBUTE_NAME = "replaceSuffix"; - - public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME); - - public SlingReplaceSuffixAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) { - super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE); - } - - @Override - protected String getLocalVariableName() { - return NODE_PROPERTY_NAME; - } - -} diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingResourceTypeAttributeTagProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingResourceTypeAttributeTagProcessor.java deleted file mode 100644 index 589e9fa..0000000 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingResourceTypeAttributeTagProcessor.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sling.scripting.thymeleaf.internal.processor; - -import org.thymeleaf.dialect.IProcessorDialect; - -public final class SlingResourceTypeAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor { - - public static final int ATTRIBUTE_PRECEDENCE = 99; - - public static final String ATTRIBUTE_NAME = "resourceType"; - - public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME); - - public SlingResourceTypeAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) { - super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE); - } - - @Override - protected String getLocalVariableName() { - return NODE_PROPERTY_NAME; - } - -} diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingUnwrapAttributeTagProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingUnwrapAttributeTagProcessor.java deleted file mode 100644 index ee0e0dc..0000000 --- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingUnwrapAttributeTagProcessor.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sling.scripting.thymeleaf.internal.processor; - -import org.thymeleaf.dialect.IProcessorDialect; - -public final class SlingUnwrapAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor { - - public static final int ATTRIBUTE_PRECEDENCE = 99; - - public static final String ATTRIBUTE_NAME = "unwrap"; - - public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME); - - public SlingUnwrapAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) { - super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE); - } - - @Override - protected String getLocalVariableName() { - return NODE_PROPERTY_NAME; - } - -} diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties index 17f23e4..93dbaa7 100644 --- a/src/main/resources/OSGI-INF/metatype/metatype.properties +++ b/src/main/resources/OSGI-INF/metatype/metatype.properties @@ -52,6 +52,9 @@ org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.javascr org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.cssPatterns.name = patterns for Template Mode CSS org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.cssPatterns.description = the template patterns (regular expressions) which should be handled by Template Mode CSS (e.g. /apps/sling/*.css) - NOTE: extension needs to be enabled for this script engine) +org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.rawPatterns.name = patterns for Template Mode RAW +org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.rawPatterns.description = the template patterns (regular expressions) which should be handled by Template Mode RAW (e.g. /apps/sling/*.raw) - NOTE: extension needs to be enabled for this script engine) + # ResourceBundleMessageResolver org.apache.sling.scripting.thymeleaf.internal.ResourceBundleMessageResolver.order.name = order org.apache.sling.scripting.thymeleaf.internal.ResourceBundleMessageResolver.order.description = property for ordering message resolvers inside the Thymeleaf template engine -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
