diff --git a/modules/core/src/main/java/org/apache/synapse/mediators/transform/pfutils/RegexTemplateProcessor.java b/modules/core/src/main/java/org/apache/synapse/mediators/transform/pfutils/RegexTemplateProcessor.java
index 1a6ba8958c..ee3b1aa542 100644
--- a/modules/core/src/main/java/org/apache/synapse/mediators/transform/pfutils/RegexTemplateProcessor.java
+++ b/modules/core/src/main/java/org/apache/synapse/mediators/transform/pfutils/RegexTemplateProcessor.java
@@ -19,15 +19,29 @@
package org.apache.synapse.mediators.transform.pfutils;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
+import org.apache.axis2.AxisFault;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.text.StringEscapeUtils;
import org.apache.synapse.MessageContext;
+import org.apache.synapse.SynapseException;
+import org.apache.synapse.commons.json.JsonUtil;
import org.apache.synapse.mediators.transform.ArgumentDetails;
+import org.apache.synapse.util.xpath.SynapseExpression;
+import org.jaxen.JaxenException;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.xml.stream.XMLStreamException;
/**
* TemplateProcessor implementation for Regex based templates
@@ -35,7 +49,10 @@
public class RegexTemplateProcessor extends TemplateProcessor {
private static final Log log = LogFactory.getLog(RegexTemplateProcessor.class);
- private final Pattern pattern = Pattern.compile("\\$(\\d)+");
+ // Pattern matches "${...}" (quoted), ${...} (unquoted), and $n
+ private final Pattern pattern = Pattern.compile("\"\\$\\{(.+?)\\}\"|\\$\\{(.+?)\\}|\\$(\\d+)");
+
+ private final Gson gson = new Gson();
@Override
public String processTemplate(String template, String mediaType, MessageContext synCtx) {
@@ -72,25 +89,125 @@ private void replace(String format, StringBuffer result, String mediaType, Messa
}
try {
while (matcher.find()) {
- String matchSeq = matcher.group();
- replacement = getReplacementValue(argValues, matchSeq);
- replacementEntry = replacement.entrySet().iterator().next();
- replacementValue = prepareReplacementValue(mediaType, synCtx, replacementEntry);
- matcher.appendReplacement(result, replacementValue);
+ if (matcher.group(1) != null) {
+ // Handle "${...}" pattern (with quotes)
+ String expression = matcher.group(1);
+ Object expressionResult = new SynapseExpression(expression).objectValueOf(synCtx);
+ if (expressionResult instanceof JsonPrimitive) {
+ replacementValue = ((JsonPrimitive) expressionResult).getAsString();
+ if (XML_TYPE.equals(mediaType)) {
+ replacementValue = StringEscapeUtils.escapeXml10(replacementValue);
+ } else if (JSON_TYPE.equals(mediaType)) {
+ replacementValue = escapeSpecialChars(replacementValue);
+ }
+ } else if (expressionResult instanceof JsonElement) {
+ replacementValue = escapeJson(Matcher.quoteReplacement(gson.toJson(expressionResult)));
+ if (XML_TYPE.equals(mediaType)) {
+ replacementValue = convertJsonToXML(replacementValue);
+ }
+ } else {
+ replacementValue = expressionResult.toString();
+ }
+ if (JSON_TYPE.equals(mediaType) && isXML(replacementValue)) {
+ // consider the replacement value as a literal XML
+ replacementValue = Matcher.quoteReplacement(replacementValue);
+ replacementValue = escapeSpecialChars(replacementValue);
+ }
+ matcher.appendReplacement(result, "\"" + replacementValue + "\"");
+ } else if (matcher.group(2) != null) {
+ // Handle ${...} pattern (without quotes)
+ String expression = matcher.group(2);
+ Object expressionResult = new SynapseExpression(expression).objectValueOf(synCtx);
+ replacementValue = expressionResult.toString();
+ if (expressionResult instanceof JsonPrimitive) {
+ replacementValue = ((JsonPrimitive) expressionResult).getAsString();
+ if (XML_TYPE.equals(mediaType)) {
+ replacementValue = StringEscapeUtils.escapeXml10(replacementValue);
+ }
+ } else if (expressionResult instanceof JsonElement) {
+ if (XML_TYPE.equals(mediaType)) {
+ replacementValue = convertJsonToXML(expressionResult.toString());
+ } else {
+ replacementValue = Matcher.quoteReplacement(gson.toJson(expressionResult));
+ }
+ }
+ if (JSON_TYPE.equals(mediaType) && isXML(replacementValue)) {
+ replacementValue = convertXMLToJSON(replacementValue);
+ }
+ matcher.appendReplacement(result, replacementValue);
+ } else if (matcher.group(3) != null) {
+ // Handle $n pattern
+ String matchSeq = matcher.group(3);
+ replacement = getReplacementValue(argValues, matchSeq);
+ replacementEntry = replacement.entrySet().iterator().next();
+ replacementValue = prepareReplacementValue(mediaType, synCtx, replacementEntry);
+ matcher.appendReplacement(result, replacementValue);
+ }
}
} catch (ArrayIndexOutOfBoundsException e) {
log.error("#replace. Mis-match detected between number of formatters and arguments", e);
+ } catch (JaxenException e) {
+ throw new SynapseException("Error evaluating expression" , e);
}
matcher.appendTail(result);
}
+ private String escapeJson(String value) {
+ // Manual escape for JSON: escaping double quotes and backslashes
+ return value.replace("\"", "\\\"").replace("\\", "\\\\");
+ }
+
+ private String convertJsonToXML(String replacementValue) {
+
+ try {
+ replacementValue = escapeSpecialCharactersOfXml(replacementValue);
+ OMElement omXML = JsonUtil.toXml(IOUtils.toInputStream(replacementValue), false);
+ if (JsonUtil.isAJsonPayloadElement(omXML)) { // remove from result.
+ Iterator children = omXML.getChildElements();
+ String childrenStr = "";
+ while (children.hasNext()) {
+ childrenStr += (children.next()).toString().trim();
+ }
+ replacementValue = childrenStr;
+ } else {
+ replacementValue = omXML.toString();
+ }
+ } catch (AxisFault e) {
+ handleException(
+ "Error converting JSON to XML, please check your expressions return valid JSON: ");
+ }
+ return replacementValue;
+ }
+
+ private String convertXMLToJSON(String replacementValue) {
+
+ try {
+ replacementValue = "" + replacementValue + "";
+ OMElement omXML = convertStringToOM(replacementValue);
+ replacementValue = JsonUtil.toJsonString(omXML).toString();
+ replacementValue = escapeSpecialCharactersOfJson(replacementValue);
+ } catch (XMLStreamException e) {
+ handleException(
+ "Error parsing XML for JSON conversion, please check your expressions return valid XML: ");
+ } catch (AxisFault e) {
+ handleException("Error converting XML to JSON");
+ } catch (OMException e) {
+ // if the logic comes to this means, it was tried as a XML, which means it has
+ // "<" as starting element and ">" as end element, so basically if the logic comes here, that means
+ // value is a string value, that means No conversion required, as path evaluates to regular String.
+ replacementValue = escapeSpecialChars(replacementValue);
+
+ }
+ return replacementValue;
+ }
+
private HashMap getReplacementValue(HashMap[] argValues,
String matchSeq) {
HashMap replacement;
int argIndex;
try {
- argIndex = Integer.parseInt(matchSeq.substring(1));
+ argIndex = Integer.parseInt(matchSeq);
} catch (NumberFormatException e) {
argIndex = Integer.parseInt(matchSeq.substring(2, matchSeq.length() - 1));
}