/*
* Copyright 2015-Present Entando Inc. (http://www.entando.com) All rights reserved.
*
* 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.
*/
package com.agiletec.aps.system.common.entity.model.attribute.util;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
import org.jdom.CDATA;
import org.jdom.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.agiletec.aps.system.common.entity.model.AttributeFieldError;
import com.agiletec.aps.system.common.entity.model.AttributeTracer;
import com.agiletec.aps.system.common.entity.model.attribute.AttributeInterface;
import com.agiletec.aps.system.services.lang.ILangManager;
import com.agiletec.aps.system.services.lang.Lang;
/**
* @author E.Santoboni
*/
public class OgnlValidationRule implements Serializable {
private static final Logger _logger = LoggerFactory.getLogger(OgnlValidationRule.class);
public OgnlValidationRule() {}
public OgnlValidationRule(Element element) {
if (null == element) {
throw new RuntimeException("null jdom element");
}
String eval = element.getAttributeValue("evalOnValuedAttribute");
this.setEvalExpressionOnValuedAttribute(null != eval && eval.equalsIgnoreCase("true"));
Element ognlExpressionElement = element.getChild("ognlexpression");
this.setExpression(ognlExpressionElement.getText());
Element errorMessageElement = element.getChild("errormessage");
if (null != errorMessageElement) {
this.setErrorMessage(errorMessageElement.getText());
this.setErrorMessageKey(errorMessageElement.getAttributeValue("key"));
}
Element helpMessageElement = element.getChild("helpmessage");
if (null != helpMessageElement) {
this.setHelpMessage(helpMessageElement.getText());
this.setHelpMessageKey(helpMessageElement.getAttributeValue("key"));
}
}
protected OgnlValidationRule clone() {
OgnlValidationRule clone = new OgnlValidationRule();
clone.setErrorMessage(this.getErrorMessage());
clone.setErrorMessageKey(this.getErrorMessageKey());
clone.setEvalExpressionOnValuedAttribute(this.isEvalExpressionOnValuedAttribute());
clone.setExpression(this.getExpression());
clone.setHelpMessage(this.getHelpMessage());
clone.setHelpMessageKey(this.getHelpMessageKey());
return clone;
}
public Element getConfigElement() {
if (null == this.getExpression() || this.getExpression().trim().length() == 0) {
return null;
}
Element exprElement = new Element("expression");
exprElement.setAttribute("evalOnValuedAttribute", String.valueOf(this.isEvalExpressionOnValuedAttribute()));
Element ognlExprElement = new Element("ognlexpression");
CDATA cdata = new CDATA(this.getExpression());
ognlExprElement.addContent(cdata);
exprElement.addContent(ognlExprElement);
Element errorMessageElement = new Element("errormessage");
if (null != this.getErrorMessageKey() && this.getErrorMessageKey().trim().length() > 0) {
errorMessageElement.setAttribute("key", this.getErrorMessageKey());
}
if (null != this.getErrorMessage() && this.getErrorMessage().trim().length() > 0) {
CDATA label = new CDATA(this.getErrorMessage());
errorMessageElement.addContent(label);
}
exprElement.addContent(errorMessageElement);
Element helpMessageElement = new Element("helpmessage");
if (null != this.getHelpMessageKey() && this.getHelpMessageKey().trim().length() > 0) {
helpMessageElement.setAttribute("key", this.getHelpMessageKey());
}
if (null != this.getHelpMessage() && this.getHelpMessage().trim().length() > 0) {
CDATA label = new CDATA(this.getHelpMessage());
helpMessageElement.addContent(label);
}
exprElement.addContent(helpMessageElement);
return exprElement;
}
public AttributeFieldError validate(AttributeInterface attribute, AttributeTracer tracer, ILangManager langManager) {
AttributeFieldError error = null;
String expression = this.getExpression();
if (null == expression || expression.trim().length() == 0) {
return null;
}
if (this.isEvalExpressionOnValuedAttribute() && attribute.getStatus().equals(AttributeInterface.Status.EMPTY)) {
return null;
}
try {
Object expr = Ognl.parseExpression(expression);
OgnlContext ctx = this.createContextForExpressionValidation(attribute, tracer, langManager);
Boolean value = (Boolean) Ognl.getValue(expr, ctx, attribute, Boolean.class);
if (!value) {
error = new AttributeFieldError(attribute, AttributeFieldError.OGNL_VALIDATION, tracer);
error.setMessage(this.getErrorMessage());
error.setMessageKey(this.getErrorMessageKey());
}
} catch (OgnlException oe) {
//ApsSystemUtils.logThrowable(oe, this, "checkExpression", "Error on evaluation of expression : " + expression);
_logger.error("Error on evaluation of expression : {}", expression, oe);
} catch (Throwable t) {
//ApsSystemUtils.logThrowable(t, this, "checkExpression");
_logger.error("Generic Error on evaluation Ognl Expression : {}", expression, t);
throw new RuntimeException("Generic Error on evaluation Ognl Expression", t);
}
return error;
}
protected OgnlContext createContextForExpressionValidation(AttributeInterface attribute, AttributeTracer tracer, ILangManager langManager) {
OgnlContext context = new OgnlContext();
Map<String, Lang> langs = new HashMap<String, Lang>();
List<Lang> langList = langManager.getLangs();
for (int i = 0; i < langList.size(); i++) {
Lang lang = langList.get(i);
langs.put(lang.getCode(), lang);
}
context.put("langs", langs);
context.put("attribute", attribute);
context.put("entity", attribute.getParentEntity());
if (tracer.isCompositeElement()) {
context.put("parent", tracer.getParentAttribute());
} else {
if (tracer.isListElement() || tracer.isMonoListElement()) {
context.put("parent", attribute.getParentEntity().getAttribute(attribute.getName()));
context.put("index", tracer.getListIndex());
}
if (tracer.isListElement()) {
context.put("listLang", tracer.getListLang());
}
}
return context;
}
public String getExpression() {
return _expression;
}
public void setExpression(String expression) {
this._expression = expression;
}
public boolean isEvalExpressionOnValuedAttribute() {
return _evalExpressionOnValuedAttribute;
}
public void setEvalExpressionOnValuedAttribute(boolean evalExpressionOnValuedAttribute) {
this._evalExpressionOnValuedAttribute = evalExpressionOnValuedAttribute;
}
public String getErrorMessage() {
return _errorMessage;
}
public void setErrorMessage(String errorMessage) {
this._errorMessage = errorMessage;
}
public String getErrorMessageKey() {
return _errorMessageKey;
}
public void setErrorMessageKey(String errorMessageKey) {
this._errorMessageKey = errorMessageKey;
}
public String getHelpMessage() {
return _helpMessage;
}
public void setHelpMessage(String helpMessage) {
this._helpMessage = helpMessage;
}
public String getHelpMessageKey() {
return _helpMessageKey;
}
public void setHelpMessageKey(String helpMessageKey) {
this._helpMessageKey = helpMessageKey;
}
private String _expression;
private boolean _evalExpressionOnValuedAttribute;
private String _errorMessage;
private String _errorMessageKey;
private String _helpMessage;
private String _helpMessageKey;
}