Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved synapse expression to an isolated package #2282

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 0 additions & 43 deletions modules/core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,45 +145,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<executions>
<execution>
<id>antlr</id>
<phase>generate-sources</phase>
<goals>
<goal>antlr4</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/antlr4</sourceDirectory>
<arguments>
<argument>-visitor</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<!-- Build Helper Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/antlr4</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>

<!-- Attach a JAR with the test classes so that we can reuse them in other
modules (see http://maven.apache.org/guides/mini/guide-attached-tests.html). -->
<plugin>
Expand Down Expand Up @@ -544,9 +505,5 @@
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -729,4 +729,14 @@ public enum ENDPOINT_TIMEOUT_TYPE { ENDPOINT_TIMEOUT, GLOBAL_TIMEOUT, HTTP_CONNE

public static final String DEFAULT_ERROR_TYPE = "ANY";
public static final String ERROR_STATS_REPORTED = "ERROR_STATS_REPORTED";
public static final String SYNAPSE_EXPRESSION_IDENTIFIER_START = "${";
public static final String SYNAPSE_EXPRESSION_IDENTIFIER_END = "}";

public static final String PAYLOAD = "payload";
public static final String PAYLOAD_$ = "$";
public static final String HEADERS = "headers";
public static final String ATTRIBUTES = "attributes";

// configure SynapseExpression implementation
public static final String SYNAPSE_EXPRESSION_IMPL = "synapse.expression.impl.class";
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.synapse.Mediator;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.mediators.Value;
import org.apache.synapse.mediators.builtin.PropertyMediator;
import org.apache.synapse.util.MediatorPropertyUtils;
import org.apache.synapse.util.synapse.expression.constants.ExpressionConstants;
import org.apache.synapse.util.xpath.SynapseJsonPath;
import org.apache.synapse.util.xpath.SynapseExpression;
import org.apache.synapse.util.xpath.SynapseXPath;
Expand Down Expand Up @@ -85,8 +85,8 @@ public Mediator createSpecificMediator(OMElement elem, Properties properties) {
String nameExpression = nameAttributeValue.substring(1, nameAttributeValue.length() - 1);
if(nameExpression.startsWith("json-eval(")) {
new SynapseJsonPath(nameExpression.substring(10, nameExpression.length() - 1));
} else if (nameExpression.startsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START) &&
nameExpression.endsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
} else if (nameExpression.startsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START) &&
nameExpression.endsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
new SynapseExpression(nameExpression.substring(2, nameExpression.length() - 1));
} else {
new SynapseXPath(nameExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.commons.logging.Log;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.transport.util.MessageHandlerProvider;
import org.apache.synapse.transport.passthru.PassThroughConstants;
import org.apache.synapse.transport.passthru.Pipe;
import org.apache.synapse.transport.passthru.config.PassThroughConfiguration;
import org.apache.synapse.util.streaming_xpath.custom.components.ParserComponent;
import org.apache.synapse.util.synapse.expression.constants.ExpressionConstants;
import org.apache.synapse.util.xpath.DOMSynapseXPathNamespaceMap;
import org.jaxen.JaxenException;

Expand Down Expand Up @@ -63,8 +63,8 @@ public SynapsePath(String path, String pathType, Log log) throws JaxenException
private String inferPathType(String expression) {
if (expression.startsWith("json-eval(")) {
return JSON_PATH;
} else if (expression.startsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START)
&& expression.endsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
} else if (expression.startsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START)
&& expression.endsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
return SYNAPSE_EXPRESSIONS_PATH;
} else {
return X_PATH;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.config.SynapsePropertiesLoader;
import org.apache.synapse.util.synapse.expression.constants.ExpressionConstants;
import org.apache.synapse.util.xpath.SynapseJsonPath;
import org.apache.synapse.util.xpath.SynapseExpression;
import org.apache.synapse.util.xpath.SynapseXPath;
Expand All @@ -51,8 +50,8 @@ public static org.apache.synapse.config.xml.SynapsePath getSynapsePath(OMElement

if(pathAttrib.getAttributeValue().startsWith("json-eval(")) {
path = new SynapseJsonPath(pathAttrib.getAttributeValue().substring(10, pathAttrib.getAttributeValue().length() - 1));
} else if (pathAttrib.getAttributeValue().startsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START) &&
pathAttrib.getAttributeValue().endsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
} else if (pathAttrib.getAttributeValue().startsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START) &&
pathAttrib.getAttributeValue().endsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
path = new SynapseExpression(pathAttrib.getAttributeValue().substring(2, pathAttrib.getAttributeValue().length() - 1));
} else {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.config.xml.SynapsePath;
import org.apache.synapse.util.synapse.expression.constants.ExpressionConstants;
import org.apache.synapse.util.xpath.SynapseJsonPath;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.apache.synapse.util.xpath.SynapseExpression;
Expand Down Expand Up @@ -103,8 +103,8 @@ public SynapsePath getExpression() {
new SynapseJsonPath(expressionString.substring(10, expressionString.length() - 1));
expression = expressionTypeKey;

} else if (expressionString.startsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START) &&
expressionString.endsWith(ExpressionConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
} else if (expressionString.startsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_START) &&
expressionString.endsWith(SynapseConstants.SYNAPSE_EXPRESSION_IDENTIFIER_END)) {
expression = new SynapseExpression(
expressionString.substring(2, expressionString.length() - 1));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
import org.apache.synapse.mediators.eip.EIPUtils;
import org.apache.synapse.util.CallMediatorEnrichUtil;
import org.apache.synapse.util.InlineExpressionUtil;
import org.apache.synapse.util.synapse.expression.constants.ExpressionConstants;
import org.apache.synapse.util.xpath.SynapseJsonPath;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.apache.synapse.util.xpath.SynapseXPathConstants;
Expand Down Expand Up @@ -248,12 +247,12 @@ public void insert(MessageContext synContext,
throw new SynapseException("Variable key cannot be null");
}
Map<String, Object> result = new HashMap<>();
result.put(ExpressionConstants.PAYLOAD, sourceNodeList);
result.put(SynapseConstants.PAYLOAD, sourceNodeList);
Map transportHeaders = (Map)((Axis2MessageContext) synContext).getAxis2MessageContext()
.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
JsonObject headers = EIPUtils.convertMapToJsonObj(transportHeaders);
result.put(ExpressionConstants.HEADERS, headers);
result.put(ExpressionConstants.ATTRIBUTES, CallMediatorEnrichUtil.populateTransportAttributes(synContext));
result.put(SynapseConstants.HEADERS, headers);
result.put(SynapseConstants.ATTRIBUTES, CallMediatorEnrichUtil.populateTransportAttributes(synContext));
synContext.setVariable(key, result);
} else {
synLog.error("Action " + action + " is not supported when enriching variables");
Expand Down Expand Up @@ -503,12 +502,12 @@ public void insertJson(MessageContext synCtx, Object sourceJsonElement, SynapseL
return;
}
Map<String, Object> result = new HashMap<>();
result.put(ExpressionConstants.PAYLOAD, sourceJsonElement);
result.put(SynapseConstants.PAYLOAD, sourceJsonElement);
Map transportHeaders = (Map)((Axis2MessageContext) synCtx).getAxis2MessageContext()
.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
JsonObject headers = EIPUtils.convertMapToJsonObj(transportHeaders);
result.put(ExpressionConstants.HEADERS, headers);
result.put(ExpressionConstants.ATTRIBUTES, CallMediatorEnrichUtil.populateTransportAttributes(synCtx));
result.put(SynapseConstants.HEADERS, headers);
result.put(SynapseConstants.ATTRIBUTES, CallMediatorEnrichUtil.populateTransportAttributes(synCtx));
synCtx.setVariable(key, result);
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.apache.synapse.SynapseException;
import org.apache.synapse.config.xml.SynapsePath;
import org.apache.synapse.util.xpath.SynapseExpression;
import org.apache.synapse.util.xpath.SynapseExpressionUtils;
import org.apache.synapse.util.xpath.SynapseJsonPath;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.jaxen.JaxenException;
Expand Down Expand Up @@ -216,8 +215,14 @@ public static boolean isInlineSynapseExpressionsContentAware(String inlineText)
while (matcher.find()) {
// Extract the expression inside ${...}
String expression = matcher.group(1);
if (SynapseExpressionUtils.isSynapseExpressionContentAware(expression)) {
return true;
try {
SynapseExpression synapseExpression = new SynapseExpression(expression);
if (synapseExpression.isContentAware()) {
return true;
}
} catch (JaxenException e) {
// If the expression is not a valid synapse expression, continue to the next expression
continue;
}
}
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2025, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
Expand All @@ -15,104 +15,60 @@
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.synapse.util.xpath;

import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;

import org.apache.synapse.SynapseConstants;
import org.apache.synapse.config.SynapsePropertiesLoader;
import org.apache.synapse.config.xml.SynapsePath;
import org.apache.synapse.util.synapse.expression.exception.SyntaxError;
import org.apache.synapse.util.synapse_expression.ExpressionLexer;
import org.apache.synapse.util.synapse_expression.ExpressionParser;
import org.apache.synapse.util.synapse.expression.ast.ExpressionNode;
import org.apache.synapse.util.synapse.expression.ast.ExpressionResult;
import org.apache.synapse.util.synapse.expression.context.EvaluationContext;
import org.apache.synapse.util.synapse.expression.exception.EvaluationException;
import org.apache.synapse.util.synapse.expression.exception.SyntaxErrorListener;
import org.apache.synapse.util.synapse.expression.visitor.ExpressionVisitor;
import org.jaxen.JaxenException;

import java.util.HashMap;
import java.util.Map;
import java.lang.reflect.InvocationTargetException;

/**
* Represents a Synapse Expression
* Create a Synapse Expression by loading the implementation class.
* Syntax ${ + expression + } ex: expression="${vars.test + 5}"
*/
public class SynapseExpression extends SynapsePath {
private static final Log log = LogFactory.getLog(SynapseExpression.class);
private final ExpressionNode expressionNode;
private final Map<String, String> namespaceMap = new HashMap<>();
private final boolean isContentAware;

public SynapseExpression(String synapseExpression) throws JaxenException {
super(synapseExpression, org.apache.synapse.config.xml.SynapsePath.JSON_PATH, log);
private final SynapsePath expression;

CharStream input = CharStreams.fromString(expression);
ExpressionLexer lexer = new ExpressionLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ExpressionParser parser = new ExpressionParser(tokens);
parser.removeErrorListeners();
SyntaxErrorListener errorListener = new SyntaxErrorListener();
parser.addErrorListener(errorListener);
private static final Log log = LogFactory.getLog(SynapseExpression.class);

ParseTree tree = parser.expression();
ExpressionVisitor visitor = new ExpressionVisitor();
expressionNode = visitor.visit(tree);
if (errorListener.hasErrors()) {
StringBuilder errorMessage = new StringBuilder("Syntax error in expression: " + synapseExpression);
for (SyntaxError error : errorListener.getErrors()) {
errorMessage.append(" ").append(error.getMessage());
public SynapseExpression(String synapseExpression) throws JaxenException {
super(synapseExpression, org.apache.synapse.config.xml.SynapsePath.SYNAPSE_EXPRESSIONS_PATH, log);
String expressionClass = SynapsePropertiesLoader.loadSynapseProperties().
getProperty(SynapseConstants.SYNAPSE_EXPRESSION_IMPL);
if (!StringUtils.isEmpty(expressionClass)) {
if (log.isDebugEnabled()) {
log.debug("Trying to load the SynapseExpression implementation");
}
throw new JaxenException(errorMessage.toString());
try {
Class<?> clazz = Class.forName(expressionClass);
this.expression = (SynapsePath) clazz.getConstructor(String.class).newInstance(synapseExpression);
} catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
throw new JaxenException("Error while loading the SynapseExpression implementation class", e);
}
} else {
throw new JaxenException("SynapseExpression implementation class is not defined in the properties");
}
isContentAware = SynapseExpressionUtils.isSynapseExpressionContentAware(synapseExpression);
}

@Override
public String stringValueOf(MessageContext synCtx) {
if (log.isDebugEnabled()) {
log.debug("Evaluating expression (stringValueOf): " + expression);
}
EvaluationContext context = new EvaluationContext();
context.setNamespaceMap(namespaceMap);
context.setSynCtx(synCtx);
ExpressionResult result = evaluateExpression(context, false);
return result != null ? result.asString() : "";
return this.expression.stringValueOf(synCtx);
}

@Override
public Object objectValueOf(MessageContext synCtx) {
if (log.isDebugEnabled()) {
log.debug("Evaluating expression (objectValueOf): " + expression);
}
EvaluationContext context = new EvaluationContext();
context.setNamespaceMap(namespaceMap);
context.setSynCtx(synCtx);
ExpressionResult result = evaluateExpression(context, true);
return result != null ? result.getValue() : "";
}

private ExpressionResult evaluateExpression(EvaluationContext context, boolean isObjectValue) {
try {
return expressionNode.evaluate(context, isObjectValue);
} catch (EvaluationException e) {
log.warn("Error evaluating expression: " + expression + " cause : " + e.getMessage());
return null;
}
}

public void addNamespace(String var1, String var2) throws JaxenException {
namespaceMap.put(var1, var2);
return this.expression.objectValueOf(synCtx);
}

@Override
public boolean isContentAware() {
return this.isContentAware;
return this.expression.isContentAware();
}
}
Loading
Loading