All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.thymeleaf.processor.AbstractProcessor Maven / Gradle / Ivy

There is a newer version: 3.1.2.RELEASE
Show newest version
/*
 * =============================================================================
 * 
 *   Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org)
 * 
 *   Licensed 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.thymeleaf.processor;

import org.thymeleaf.Arguments;
import org.thymeleaf.dom.Node;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.util.MessageResolutionUtils;
import org.thymeleaf.util.Validate;


/**
 * 

* Common abstract superclass for all processors, including utility methods for * easily resolving template- and class-based externalized messages. This class * also takes care of processor precedence. *

* * @author Daniel Fernández * * @since 2.0.0 * */ public abstract class AbstractProcessor implements IProcessor { protected AbstractProcessor() { super(); } /** *

* Resolves a message, trying to resolve it first as a template message * (see {@link #getMessageForTemplate(Arguments, String, Object[])}) and, * if not found, as a processor message (see {@link #getMessageForProcessor(Arguments, String, Object[])}. *

*

* This method always returns a result: if no message is found for the specified * key, a default placeholder message is returned (as a String). *

* * @param arguments the execution arguments, containing Template Engine configuration and * execution context. * @param messageKey the message key * @param messageParameters the (optional) message parameters * @return the resolved message */ protected String getMessage( final Arguments arguments, final String messageKey, final Object[] messageParameters) { final String templateMessage = MessageResolutionUtils.resolveMessageForTemplate( arguments, messageKey, messageParameters, false); if (templateMessage != null) { return templateMessage; } final String processorMessage = MessageResolutionUtils.resolveMessageForClass( arguments.getConfiguration(), this.getClass(), arguments.getContext().getLocale(), messageKey, messageParameters, false); if (processorMessage != null) { return processorMessage; } return MessageResolutionUtils.getAbsentMessageRepresentation( messageKey, arguments.getContext().getLocale()); } /** *

* Resolves the specified message as a template message. *

*

* Template messages are resolved by the Message Resolver * ({@link org.thymeleaf.messageresolver.IMessageResolver}) instances * configured at the Template Engine (executed in chain) in exactly the same way as, * for example, a #{...} expression would when using the Standard * Dialect or the SpringStandard Dialect. *

*

* This method always returns a result: if no message is found for the specified * key, a default placeholder message is returned (as a String). *

* * @param arguments the execution arguments, containing Template Engine configuration and * execution context. * @param messageKey the message key * @param messageParameters the (optional) message parameters * @return the resolved message */ protected String getMessageForTemplate( final Arguments arguments, final String messageKey, final Object[] messageParameters) { return MessageResolutionUtils.resolveMessageForTemplate( arguments, messageKey, messageParameters); } /** *

* Resolves the specified message as a processor message. *

*

* Processor messages appear on .properties files that usually * live in the same package (i.e. source folder) as the processor class itself, * and have the same base name (for example, for a com.something.MyProc processor * we can have com/something/MyProc_en.properties, * com/something/MyProc_es.properties, com/something/MyProc.properties * (for defaults), etc.). This allows the encapsulation and packing of processors * along with all of its required internationalization resources. *

*

* If no message is found for the specified key in a .properties file with * the same base name as the attribute processor, then its superclasses are * also examined. *

*

* This method always returns a result: if at the end no message is found for the specified * key, a default placeholder message is returned (as a String). *

* * * @param arguments the execution arguments, containing Template Engine configuration and * execution context. * @param messageKey the message key * @param messageParameters the (optional) message parameters * @return the resolved message */ protected String getMessageForProcessor( final Arguments arguments, final String messageKey, final Object[] messageParameters) { Validate.notNull(arguments.getContext().getLocale(), "Locale in context cannot be null"); return MessageResolutionUtils.resolveMessageForClass( arguments.getConfiguration(), this.getClass(), arguments.getContext().getLocale(), messageKey, messageParameters); } public abstract int getPrecedence(); /** *

* Compare (and therefore order) processors according to their precedence. *

*

* Be careful: This implementation of compareTo breaks * (o1.compareTo(o2) == 0) == (o1.equals(o2)), as two different processors * can have the same precedence. *

* * @param o the object to compare to * @return the comparison result */ public int compareTo(final IProcessor o) { if (o == null) { return 1; } if (!(o instanceof AbstractProcessor)) { // The other object does not rely on precedence, so we should delegate to // the other object (and its comparison policy) and invert the result. final int result = o.compareTo(this); return (-1) * result; } final int thisPrecedence = getPrecedence(); final int otherPrecedence = ((AbstractProcessor)o).getPrecedence(); if (thisPrecedence > otherPrecedence) { return 1; } if (thisPrecedence < otherPrecedence) { return -1; } return 0; } public final ProcessorResult process( final Arguments arguments, final ProcessorMatchingContext processorMatchingContext, final Node node) { try { return doProcess(arguments, processorMatchingContext, node); } catch (final TemplateProcessingException e) { if (!e.hasTemplateName()) { e.setTemplateName(node.getDocumentName()); } if (!e.hasLineNumber()) { e.setLineNumber(node.getLineNumber()); } throw e; } catch (final Exception e) { throw new TemplateProcessingException( "Error during execution of processor '" + this.getClass().getName() + "'", node.getDocumentName(), node.getLineNumber(), e); } } protected abstract ProcessorResult doProcess(final Arguments arguments, final ProcessorMatchingContext processorMatchingContext, final Node node); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy