Author: hiranya
Date: Tue Nov 10 13:12:25 2009
New Revision: 834458
URL: http://svn.apache.org/viewvc?rev=834458&view=rev
Log:
Implementing data types support for the property mediator. With this
improvement property medaitor takes an optional attribute called 'type' which
can be used to specify a type for the property values being set. As of now
following types are supported:
* STRING (default)
* BOOLEAN
* INTEGER
* SHORT
* LONG
* FLOAT
* DOUBLE
* OM (for XML values)
In addition the property mediator can now be used to set XML properties to the
message context. We can specify a child XML element for the property mediator
and that will be set as a property value. Results obtained thru evaluating
expressions during mediation time can also be converted into one of above types
(including OM). I have also included four new test cases to cover the new
functionality. All the existing test cases are passed without any code changes.
This commit is related to issues at:
* SYNAPSE-596
* SYNAPSE-458
Modified:
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorFactory.java
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorSerializer.java
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/config/xml/PropertyMediatorSerializationTest.java
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/mediators/builtin/PropertyMediatorTest.java
Modified:
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorFactory.java
URL:
http://svn.apache.org/viewvc/synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorFactory.java?rev=834458&r1=834457&r2=834458&view=diff
==============================================================================
---
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorFactory.java
(original)
+++
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorFactory.java
Tue Nov 10 13:12:25 2009
@@ -38,6 +38,7 @@
public class PropertyMediatorFactory extends AbstractMediatorFactory {
private static final QName ATT_SCOPE = new QName("scope");
private static final QName ATT_ACTION = new QName("action");
+ private static final QName ATT_TYPE = new QName("type");
public Mediator createMediator(OMElement elem) {
@@ -47,29 +48,50 @@
OMAttribute expression = elem.getAttribute(ATT_EXPRN);
OMAttribute scope = elem.getAttribute(ATT_SCOPE);
OMAttribute action = elem.getAttribute(ATT_ACTION);
+ OMAttribute type = elem.getAttribute(ATT_TYPE);
+
+ OMElement valueElement = elem.getFirstElement();
if (name == null) {
String msg = "The 'name' attribute is required for the
configuration of a property mediator";
log.error(msg);
throw new SynapseException(msg);
- } else if ((value == null && expression == null) && !(action != null
&& "remove".equals(action.getAttributeValue()))) {
- String msg = "Either an 'value' or 'expression' attribute is
required for a property mediator when action is SET";
+ } else if ((value == null && valueElement == null && expression ==
null) &&
+ !(action != null &&
"remove".equals(action.getAttributeValue()))) {
+ String msg = "Either a child element or one of 'value',
'expression' attributes is " +
+ "required for a property mediator when action is SET";
log.error(msg);
throw new SynapseException(msg);
}
+
propMediator.setName(name.getAttributeValue());
+ String dataType = null;
+ if (type != null) {
+ dataType = type.getAttributeValue();
+ }
+
if (value != null) {
- propMediator.setValue(value.getAttributeValue());
+ propMediator.setValue(value.getAttributeValue(), dataType);
+ } else if (valueElement != null) {
+ propMediator.setValueElement(valueElement);
} else if (expression != null) {
try {
-
propMediator.setExpression(SynapseXPathFactory.getSynapseXPath(elem,
ATT_EXPRN));
-
+
propMediator.setExpression(SynapseXPathFactory.getSynapseXPath(elem, ATT_EXPRN),
+ dataType);
} catch (JaxenException e) {
- String msg = "Invalid XPath expression for attribute
'expression' : " + expression.getAttributeValue();
+ String msg = "Invalid XPath expression for attribute
'expression' : " +
+ expression.getAttributeValue();
log.error(msg);
throw new SynapseException(msg);
}
}
+
+ // The action attribute is optional, if provided and equals to
'remove' the
+ // property mediator will act as a property remove mediator
+ if (action != null && "remove".equals(action.getAttributeValue())) {
+ propMediator.setAction(PropertyMediator.ACTION_REMOVE);
+ }
+
if (scope != null) {
String valueStr = scope.getAttributeValue();
if (!XMLConfigConstants.SCOPE_AXIS2.equals(valueStr) &&
!XMLConfigConstants.SCOPE_TRANSPORT.equals(valueStr)
@@ -82,14 +104,11 @@
}
propMediator.setScope(valueStr);
}
+
// after successfully creating the mediator
// set its common attributes such as tracing etc
processAuditStatus(propMediator, elem);
- // The action attribute is optional, if provided and equals to
'remove' the
- // property mediator will act as a property remove mediator
- if (action != null && "remove".equals(action.getAttributeValue())) {
- propMediator.setAction(PropertyMediator.ACTION_REMOVE);
- }
+
return propMediator;
}
Modified:
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorSerializer.java
URL:
http://svn.apache.org/viewvc/synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorSerializer.java?rev=834458&r1=834457&r2=834458&view=diff
==============================================================================
---
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorSerializer.java
(original)
+++
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/PropertyMediatorSerializer.java
Tue Nov 10 13:12:25 2009
@@ -27,7 +27,9 @@
/**
* <pre>
- * <property name="string" [action=set/remove] (value="literal" |
expression="xpath")/>
+ * <property name="string" [action=set/remove] (value="literal" |
expression="xpath") [type="literal"]>
+ * [Random XML]
+ * </property>
* </pre>
*/
public class PropertyMediatorSerializer extends AbstractMediatorSerializer {
@@ -51,22 +53,30 @@
if (mediator.getValue() != null) {
property.addAttribute(fac.createOMAttribute(
- "value", nullNS, mediator.getValue()));
-
+ "value", nullNS, mediator.getValue().toString()));
+ } else if (mediator.getValueElement() != null) {
+ property.addChild(mediator.getValueElement());
} else if (mediator.getExpression() != null) {
- SynapseXPathSerializer.serializeXPath(mediator.getExpression(),
property, "expression");
-
+ SynapseXPathSerializer.serializeXPath(mediator.getExpression(),
+ property, "expression");
} else if (mediator.getAction() == PropertyMediator.ACTION_SET) {
- handleException("Invalid property mediator. Value or expression is
required if action is SET");
+ handleException("Invalid property mediator. Value or expression is
required if " +
+ "action is SET");
}
+
if (mediator.getScope() != null) {
// if we have already built a mediator with scope, scope should be
valid, now save it
property.addAttribute(fac.createOMAttribute("scope", nullNS,
mediator.getScope()));
}
+
if (mediator.getAction() == PropertyMediator.ACTION_REMOVE) {
property.addAttribute(fac.createOMAttribute(
"action", nullNS, "remove"));
+ } else if (mediator.getType() != null) {
+ property.addAttribute(fac.createOMAttribute(
+ "type" , nullNS, mediator.getType()));
}
+
if (parent != null) {
parent.addChild(property);
}
Modified:
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
URL:
http://svn.apache.org/viewvc/synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java?rev=834458&r1=834457&r2=834458&view=diff
==============================================================================
---
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
(original)
+++
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
Tue Nov 10 13:12:25 2009
@@ -43,6 +43,10 @@
public static final String SCOPE_CLIENT = "axis2-client";
/** The scope name for transport header properties */
public static final String SCOPE_TRANSPORT = "transport";
+ /** The set of supported data types */
+ public static enum DATA_TYPES {
+ STRING, BOOLEAN, INTEGER, LONG, SHORT, FLOAT, DOUBLE, OM
+ }
//-- WS-RM sequence mediator --
/** WS-RM version 1.0*/
Modified:
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java
URL:
http://svn.apache.org/viewvc/synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java?rev=834458&r1=834457&r2=834458&view=diff
==============================================================================
---
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java
(original)
+++
synapse/branches/1.3/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java
Tue Nov 10 13:12:25 2009
@@ -21,11 +21,15 @@
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseLog;
+import org.apache.synapse.SynapseException;
import org.apache.synapse.config.xml.XMLConfigConstants;
+import org.apache.synapse.config.SynapseConfigUtils;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.synapse.util.xpath.SynapseXPath;
+import org.apache.axiom.om.OMElement;
+import javax.xml.stream.XMLStreamException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -42,8 +46,12 @@
/** The Name of the property */
private String name = null;
- /** The Value to be set*/
- private String value = null;
+ /** The Value to be set */
+ private Object value = null;
+ /** The data type of the value */
+ private String type = null;
+ /** The XML value to be set */
+ private OMElement valueElement = null;
/** The XPath expr. to get value */
private SynapseXPath expression = null;
/** The scope for which decide properties where to go*/
@@ -75,7 +83,7 @@
if (action == ACTION_SET) {
- String resultValue = (value != null ? value :
expression.stringValueOf(synCtx));
+ Object resultValue = getResultValue(synCtx);
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Setting property : " + name + " at scope
: " +
@@ -177,12 +185,39 @@
this.name = name;
}
- public String getValue() {
+ public Object getValue() {
return value;
}
public void setValue(String value) {
- this.value = value;
+ setValue(value, null);
+ }
+
+ /**
+ * Set the value to be set by this property mediator and the data type
+ * to be used when setting the value. Accepted type names are defined in
+ * XMLConfigConstants.DATA_TYPES enumeration. Passing null as the type
+ * implies that 'STRING' type should be used.
+ *
+ * @param value the value to be set as a string
+ * @param type the type name
+ */
+ public void setValue(String value, String type) {
+ this.type = type;
+ // Convert the value into specified type
+ this.value = convertValue(value, type);
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public OMElement getValueElement() {
+ return valueElement;
+ }
+
+ public void setValueElement(OMElement valueElement) {
+ this.valueElement = valueElement;
}
public SynapseXPath getExpression() {
@@ -190,7 +225,15 @@
}
public void setExpression(SynapseXPath expression) {
+ setExpression(expression, null);
+ }
+
+ public void setExpression(SynapseXPath expression, String type) {
this.expression = expression;
+ // Save the type information for now
+ // We need to convert the result of the expression into this type
during mediation
+ // A null type would imply 'STRING' type
+ this.type = type;
}
public String getScope() {
@@ -208,4 +251,40 @@
public void setAction(int action) {
this.action = action;
}
+
+ private Object getResultValue(MessageContext synCtx) {
+ if (value != null) {
+ return value;
+ } else if (valueElement != null) {
+ return valueElement;
+ } else {
+ return convertValue(expression.stringValueOf(synCtx), type);
+ }
+ }
+
+ private Object convertValue(String value, String type) {
+ if (type == null) {
+ // If no type is set we simply return the string value
+ return value;
+ }
+
+ try {
+ XMLConfigConstants.DATA_TYPES dataType =
XMLConfigConstants.DATA_TYPES.valueOf(type);
+ switch (dataType) {
+ case BOOLEAN : return Boolean.parseBoolean(value);
+ case DOUBLE : return Double.parseDouble(value);
+ case FLOAT : return Float.parseFloat(value);
+ case INTEGER : return Integer.parseInt(value);
+ case LONG : return Long.parseLong(value);
+ case OM : return SynapseConfigUtils.stringToOM(value);
+ case SHORT : return Short.parseShort(value);
+ default : return value;
+ }
+ } catch (IllegalArgumentException e) {
+ String msg = "Unknown type : " + type + " for the property
mediator or the " +
+ "property value cannot be converted into the specified
type.";
+ log.error(msg, e);
+ throw new SynapseException(msg, e);
+ }
+ }
}
Modified:
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/config/xml/PropertyMediatorSerializationTest.java
URL:
http://svn.apache.org/viewvc/synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/config/xml/PropertyMediatorSerializationTest.java?rev=834458&r1=834457&r2=834458&view=diff
==============================================================================
---
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/config/xml/PropertyMediatorSerializationTest.java
(original)
+++
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/config/xml/PropertyMediatorSerializationTest.java
Tue Nov 10 13:12:25 2009
@@ -56,4 +56,16 @@
assertTrue(serialization(inputXml, propertyMediatorFactory,
propertyMediatorSerializer));
assertTrue(serialization(inputXml, propertyMediatorSerializer));
}
+
+ public void testPropertyMediatorSerializationScenarioFive() throws
Exception {
+ String inputXml = "<property xmlns=\"http://ws.apache.org/ns/synapse\"
name=\"DoubleProperty\" type=\"DOUBLE\" value=\"123.456\"/>";
+ assertTrue(serialization(inputXml, propertyMediatorFactory,
propertyMediatorSerializer));
+ assertTrue(serialization(inputXml, propertyMediatorSerializer));
+ }
+
+ public void testPropertyMediatorSerializationScenarioSix() throws
Exception {
+ String inputXml = "<property xmlns=\"http://ws.apache.org/ns/synapse\"
name=\"OMProperty\"><name>Synapse</name></property>";
+ assertTrue(serialization(inputXml, propertyMediatorFactory,
propertyMediatorSerializer));
+ assertTrue(serialization(inputXml, propertyMediatorSerializer));
+ }
}
Modified:
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/mediators/builtin/PropertyMediatorTest.java
URL:
http://svn.apache.org/viewvc/synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/mediators/builtin/PropertyMediatorTest.java?rev=834458&r1=834457&r2=834458&view=diff
==============================================================================
---
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/mediators/builtin/PropertyMediatorTest.java
(original)
+++
synapse/branches/1.3/modules/core/src/test/java/org/apache/synapse/mediators/builtin/PropertyMediatorTest.java
Tue Nov 10 13:12:25 2009
@@ -21,9 +21,15 @@
import junit.framework.TestCase;
import org.apache.synapse.MessageContext;
+import org.apache.synapse.SynapseException;
+import org.apache.synapse.core.axis2.Axis2MessageContext;
+import org.apache.synapse.config.xml.XMLConfigConstants;
import org.apache.synapse.mediators.MediatorProperty;
import org.apache.synapse.mediators.TestUtils;
import org.apache.synapse.util.xpath.SynapseXPath;
+import org.apache.axiom.om.OMElement;
+
+import java.util.Map;
public class PropertyMediatorTest extends TestCase {
@@ -59,6 +65,103 @@
}
+ public void testTypeAwarePropertyHandling() throws Exception {
+ PropertyMediator propMediatorOne = new PropertyMediator();
+ propMediatorOne.setName("nameOne");
+ propMediatorOne.setValue("valueOne",
XMLConfigConstants.DATA_TYPES.STRING.name());
+
+ PropertyMediator propMediatorTwo = new PropertyMediator();
+ propMediatorTwo.setName("nameTwo");
+ propMediatorTwo.setValue("25000",
XMLConfigConstants.DATA_TYPES.INTEGER.name());
+ propMediatorTwo.setScope(XMLConfigConstants.SCOPE_AXIS2);
+
+ PropertyMediator propMediatorThree = new PropertyMediator();
+ propMediatorThree.setName("nameThree");
+ propMediatorThree.setValue("123.456",
XMLConfigConstants.DATA_TYPES.DOUBLE.name());
+ propMediatorThree.setScope(XMLConfigConstants.SCOPE_TRANSPORT);
+
+ PropertyMediator propMediatorFour = new PropertyMediator();
+ propMediatorFour.setName("nameFour");
+ propMediatorFour.setValue("true",
XMLConfigConstants.DATA_TYPES.BOOLEAN.name());
+
+ PropertyMediator propMediatorFive = new PropertyMediator();
+ propMediatorFive.setName("nameFive");
+ propMediatorFive.setValue("123456",
XMLConfigConstants.DATA_TYPES.LONG.name());
+ propMediatorFive.setScope(XMLConfigConstants.SCOPE_AXIS2);
+
+ PropertyMediator propMediatorSix = new PropertyMediator();
+ propMediatorSix.setName("nameSix");
+ propMediatorSix.setValue("12345",
XMLConfigConstants.DATA_TYPES.SHORT.name());
+ propMediatorSix.setScope(XMLConfigConstants.SCOPE_TRANSPORT);
+
+ PropertyMediator propMediatorSeven = new PropertyMediator();
+ propMediatorSeven.setName("nameSeven");
+ propMediatorSeven.setValue("123.456",
XMLConfigConstants.DATA_TYPES.FLOAT.name());
+
+ MessageContext synCtx =
TestUtils.createLightweightSynapseMessageContext("<empty/>");
+ propMediatorOne.mediate(synCtx);
+ propMediatorTwo.mediate(synCtx);
+ propMediatorThree.mediate(synCtx);
+ propMediatorFour.mediate(synCtx);
+ propMediatorFive.mediate(synCtx);
+ propMediatorSix.mediate(synCtx);
+ propMediatorSeven.mediate(synCtx);
+
+ org.apache.axis2.context.MessageContext axisCtx =
((Axis2MessageContext) synCtx).getAxis2MessageContext();
+ Map transportHeaders = (Map) axisCtx.getProperty(
+ org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
+
+ Object valueOne = synCtx.getProperty("nameOne");
+ Object valueTwo = axisCtx.getProperty("nameTwo");
+ Object valueThree = transportHeaders.get("nameThree");
+ Object valueFour = synCtx.getProperty("nameFour");
+ Object valueFive = axisCtx.getProperty("nameFive");
+ Object valueSix = transportHeaders.get("nameSix");
+ Object valueSeven = synCtx.getProperty("nameSeven");
+
+ assertEquals("valueOne", valueOne);
+ assertEquals(new Integer(25000), valueTwo);
+ assertEquals(new Double(123.456), valueThree);
+ assertEquals(Boolean.TRUE, valueFour);
+ assertEquals(new Long(123456), valueFive);
+ assertEquals(new Short("12345"), valueSix);
+ assertEquals(new Float(123.456), valueSeven);
+ System.out.println("All property values are correctly in place - Test
SUCCESSFUL");
+ }
+
+ public void testXMLPropertyHandling() throws Exception {
+ PropertyMediator propMediatorOne = new PropertyMediator();
+ propMediatorOne.setName("nameOne");
+ String xml = "<Project><name>Synapse</name></Project>";
+ OMElement valueOne = TestUtils.createOMElement(xml);
+ propMediatorOne.setValueElement(valueOne);
+
+ // Test setting XML properties
+ MessageContext synCtx =
TestUtils.getTestContext("<getQuote><symbol>IBM</symbol></getQuote>");
+ propMediatorOne.mediate(synCtx);
+ Object prop = synCtx.getProperty("nameOne");
+ assertEquals(valueOne, prop);
+
+ // Test XML property retreival
+ String exprValue = new
SynapseXPath("synapse:get-property('nameOne')").stringValueOf(synCtx);
+ assertEquals(xml, exprValue);
+
+ // Test property removal
+ propMediatorOne.setAction(PropertyMediator.ACTION_REMOVE);
+ propMediatorOne.mediate(synCtx);
+ assertNull(synCtx.getProperty("nameOne"));
+
+ // Setting XML properties using expressions
+ synCtx.setProperty("nameOne", xml);
+ PropertyMediator propertyMediatorTwo = new PropertyMediator();
+ propertyMediatorTwo.setName("nameTwo");
+ propertyMediatorTwo.setExpression(new
SynapseXPath("synapse:get-property('nameOne')"),
+ XMLConfigConstants.DATA_TYPES.OM.name());
+ propertyMediatorTwo.mediate(synCtx);
+ Object exprProp = synCtx.getProperty("nameTwo");
+ assertTrue(exprProp != null && exprProp instanceof OMElement);
+ }
+
/**
* property being searched does not exist in context, and lookup should go
up into the config
* @throws Exception