/*
* Copyright 2002-2006,2009 The Apache Software Foundation.
*
* 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 com.opensymphony.xwork2.validator.validators;
import com.opensymphony.xwork2.TextProviderFactory;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.validator.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract implementation of the Validator interface suitable for subclassing.
*
* @author Jason Carreira
* @author tm_jee
* @author Martin Gilday
*/
public abstract class ValidatorSupport implements Validator, ShortCircuitableValidator {
private static final Logger LOG = LogManager.getLogger(ValidatorSupport.class);
public static final String EMPTY_STRING = "";
private ValidatorContext validatorContext;
private boolean shortCircuit;
private String type;
private String[] messageParameters;
protected String defaultMessage = "";
protected String messageKey;
protected ValueStack stack;
protected TextProviderFactory textProviderFactory;
@Inject
public void setTextProviderFactory(TextProviderFactory textProviderFactory) {
this.textProviderFactory = textProviderFactory;
}
public void setValueStack(ValueStack stack) {
this.stack = stack;
}
public void setDefaultMessage(String message) {
if (StringUtils.isNotEmpty(message)) {
this.defaultMessage = message;
}
}
public String getDefaultMessage() {
return defaultMessage;
}
public String getMessage(Object object) {
String message;
boolean pop = false;
if (!stack.getRoot().contains(object)) {
stack.push(object);
pop = true;
}
stack.push(this);
if (messageKey != null) {
if ((defaultMessage == null) || ("".equals(defaultMessage.trim()))) {
defaultMessage = messageKey;
}
if (validatorContext == null) {
validatorContext = new DelegatingValidatorContext(object, textProviderFactory);
}
List<Object> parsedMessageParameters = null;
if (messageParameters != null) {
parsedMessageParameters = new ArrayList<>();
for (String messageParameter : messageParameters) {
if (messageParameter != null) {
try {
Object val = stack.findValue(messageParameter);
parsedMessageParameters.add(val);
} catch (Exception e) {
// if there's an exception in parsing, we'll just treat the expression itself as the
// parameter
LOG.warn("exception while parsing message parameter [{}]", messageParameter, e);
parsedMessageParameters.add(messageParameter);
}
}
}
}
message = validatorContext.getText(messageKey, defaultMessage, parsedMessageParameters);
} else {
message = defaultMessage;
}
if (StringUtils.isNotBlank(message))
message = TextParseUtil.translateVariables(message, stack);
stack.pop();
if (pop) {
stack.pop();
}
return message;
}
public void setMessageKey(String key) {
messageKey = key;
}
public String getMessageKey() {
return messageKey;
}
public String[] getMessageParameters() {
return this.messageParameters;
}
public void setMessageParameters(String[] messageParameters) {
this.messageParameters = messageParameters;
}
public void setShortCircuit(boolean shortcircuit) {
shortCircuit = shortcircuit;
}
public boolean isShortCircuit() {
return shortCircuit;
}
public void setValidatorContext(ValidatorContext validatorContext) {
this.validatorContext = validatorContext;
}
public ValidatorContext getValidatorContext() {
return validatorContext;
}
public void setValidatorType(String type) {
this.type = type;
}
public String getValidatorType() {
return type;
}
/**
* Parse <code>expression</code> passed in against value stack.
*
* @param expression an OGNL expression
* @param type type to return
* @return Object
*/
protected Object parse(String expression, Class type) {
if (expression == null) {
return null;
}
return TextParseUtil.translateVariables('$', expression, stack, type);
}
/**
* Return the field value named <code>name</code> from <code>object</code>,
* <code>object</code> should have the appropriate getter/setter.
*
* @param name name of the field
* @param object to search field name on
* @return Object as field value
* @throws ValidationException in case of validation problems
*/
protected Object getFieldValue(String name, Object object) throws ValidationException {
boolean pop = false;
if (!stack.getRoot().contains(object)) {
stack.push(object);
pop = true;
}
Object retVal = stack.findValue(name);
if (pop) {
stack.pop();
}
return retVal;
}
protected void addActionError(Object object) {
validatorContext.addActionError(getMessage(object));
}
protected void addFieldError(String propertyName, Object object) {
validatorContext.addFieldError(propertyName, getMessage(object));
}
}