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>
- * &lt;property name="string" [action=set/remove] (value="literal" | 
expression="xpath")/&gt;
+ * &lt;property name="string" [action=set/remove] (value="literal" | 
expression="xpath") [type="literal"]&gt;
+ *     [Random XML]
+ * &lt;/property&gt;
  * </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


Reply via email to