Author: hiranya
Date: Wed Dec  7 10:01:53 2011
New Revision: 1211361

URL: http://svn.apache.org/viewvc?rev=1211361&view=rev
Log:
Adding payload factory mediator. SYNAPSE-821. Thanks Sadeep for the patch

Added:
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorFactory.java
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorSerializer.java
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/PayloadFactoryMediator.java
Modified:
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java

Modified: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java?rev=1211361&r1=1211360&r2=1211361&view=diff
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java
 (original)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java
 Wed Dec  7 10:01:53 2011
@@ -82,7 +82,8 @@ public class MediatorFactoryFinder imple
         EnrichMediatorFactory.class,
         MessageStoreMediatorFactory.class,
         TemplateMediatorFactory.class,
-        InvokeMediatorFactory.class
+        InvokeMediatorFactory.class,
+        PayloadFactoryMediatorFactory.class
     };
 
     private final static MediatorFactoryFinder instance  = new 
MediatorFactoryFinder();

Modified: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java?rev=1211361&r1=1211360&r2=1211361&view=diff
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java
 (original)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java
 Wed Dec  7 10:01:53 2011
@@ -68,7 +68,8 @@ public class MediatorSerializerFinder {
         TemplateMediatorSerializer.class,
         InvokeMediatorSerializer.class,
         MessageStoreMediatorSerializer.class,
-        URLRewriteMediatorSerializer.class
+        URLRewriteMediatorSerializer.class,
+        PayloadFactoryMediatorSerializer.class
     };
 
     private final static MediatorSerializerFinder instance = new 
MediatorSerializerFinder();

Added: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorFactory.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorFactory.java?rev=1211361&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorFactory.java
 (added)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorFactory.java
 Wed Dec  7 10:01:53 2011
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.synapse.config.xml;
+
+import org.apache.axiom.om.*;
+import org.apache.synapse.Mediator;
+import org.apache.synapse.mediators.transform.PayloadFactoryMediator;
+import org.jaxen.JaxenException;
+
+import javax.xml.namespace.QName;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Creates a payloadFactory mediator from the provided XML configuration
+ * <p/>
+ * <pre>
+ * &lt;payloadFactory&gt;
+ *   &lt;format&gt;&quot;xmlstring&quot;&lt;/format&gt;
+ *   &lt;args&gt;
+ *     &lt;arg (value=&quot;literal&quot; | expression=&quot;xpath&quot;)/&gt;*
+ *   &lt;/args&gt;
+ * &lt;/payloadFactory&gt;
+ * </pre>
+ */
+public class PayloadFactoryMediatorFactory extends AbstractMediatorFactory {
+
+    private static final QName PAYLOAD_FACTORY_Q
+            = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, 
"payloadFactory");
+
+    private static final QName FORMAT_Q = new 
QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "format");
+    private static final QName ARGS_Q = new 
QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "args");
+
+    public Mediator createSpecificMediator(OMElement elem, Properties 
properties) {
+
+        PayloadFactoryMediator payloadFactoryMediator = new 
PayloadFactoryMediator();
+
+        OMElement formatElem = elem.getFirstChildWithName(FORMAT_Q);
+
+        if (formatElem != null) {
+            OMElement copy = formatElem.getFirstElement().cloneOMElement();
+            removeIndentations(copy);
+            payloadFactoryMediator.setFormat(copy.toString());
+        } else {
+            handleException("format element of payloadFactoryMediator is 
required");
+        }
+
+        OMElement argumentsElem = elem.getFirstChildWithName(ARGS_Q);
+
+        if (argumentsElem != null) {
+
+            Iterator itr = argumentsElem.getChildElements();
+
+            while (itr.hasNext()) {
+                OMElement argElem = (OMElement) itr.next();
+                PayloadFactoryMediator.Argument arg = new 
PayloadFactoryMediator.Argument();
+                String value;
+
+                if ((value = argElem.getAttributeValue(ATT_VALUE)) != null) {
+                    arg.setValue(value);
+                } else if ((value = argElem.getAttributeValue(ATT_EXPRN)) != 
null) {
+
+                    if (value.trim().length() == 0) {
+                        handleException("Value of 'expression' attribute is 
required");
+                    } else {
+                        try {
+                            
arg.setExpression(SynapseXPathFactory.getSynapseXPath(argElem, ATT_EXPRN));
+                        } catch (JaxenException e) {
+                            handleException("Invalid XPath expression is 
provided for " +
+                                    "'expression' attribute: " + value, e);
+                        }
+                    }
+
+                } else {
+                    handleException("Unsupported arg type. 'value' or 
'expression' attribute is " +
+                            "required");
+                }
+
+                payloadFactoryMediator.addArgument(arg);
+            }
+        }
+
+        return payloadFactoryMediator;
+    }
+
+    public QName getTagQName() {
+        return PAYLOAD_FACTORY_Q;
+    }
+
+    private void removeIndentations(OMElement element) {
+        List<OMText> removables = new ArrayList<OMText>();
+        removeIndentations(element, removables);
+        for (OMText node : removables) {
+            node.detach();
+        }
+    }
+
+    private void removeIndentations(OMElement element, List<OMText> 
removables) {
+        Iterator children = element.getChildren();
+        while (children.hasNext()) {
+            Object next = children.next();
+            if (next instanceof OMText) {
+                OMText text = (OMText) next;
+                if (text.getText().trim().equals("")) {
+                    removables.add(text);
+                }
+            } else if (next instanceof OMElement) {
+                removeIndentations((OMElement) next, removables);
+            }
+        }
+    }
+
+}

Added: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorSerializer.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorSerializer.java?rev=1211361&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorSerializer.java
 (added)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/PayloadFactoryMediatorSerializer.java
 Wed Dec  7 10:01:53 2011
@@ -0,0 +1,97 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.synapse.config.xml;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.apache.synapse.Mediator;
+import org.apache.synapse.mediators.transform.PayloadFactoryMediator;
+
+import javax.xml.stream.XMLStreamException;
+import java.util.List;
+
+/**
+ * Serializer for {@link PayloadFactoryMediator} instances.
+ *
+ * @see PayloadFactoryMediatorFactory
+ */
+public class PayloadFactoryMediatorSerializer extends 
AbstractMediatorSerializer {
+
+    private static final String PAYLOAD_FACTORY = "payloadFactory";
+    private static final String FORMAT = "format";
+    private static final String ARGS = "args";
+    private static final String ARG = "arg";
+    private static final String VALUE = "value";
+    private static final String EXPRESSION = "expression";
+
+
+    public OMElement serializeSpecificMediator(Mediator m) {
+
+        if (!(m instanceof PayloadFactoryMediator)) {
+            handleException("Unsupported mediator was passed in for 
serialization: " + m.getType());
+            return null;
+        }
+
+        PayloadFactoryMediator mediator = (PayloadFactoryMediator) m;
+
+        OMElement payloadFactoryElem = fac.createOMElement(PAYLOAD_FACTORY, 
synNS);
+        saveTracingState(payloadFactoryElem, mediator);
+
+        if (mediator.getFormat() != null) {
+
+            try {
+                OMElement formatElem = fac.createOMElement(FORMAT, synNS);
+                
formatElem.addChild(AXIOMUtil.stringToOM(mediator.getFormat()));
+                payloadFactoryElem.addChild(formatElem);
+            } catch (XMLStreamException e) {
+                handleException("Error while serializing payloadFactory 
mediator", e);
+            }
+        } else {
+            handleException("Invalid payloadFactory mediator, format is 
required");
+        }
+
+        List<PayloadFactoryMediator.Argument> argList = 
mediator.getArgumentList();
+
+        if (argList != null && argList.size() > 0) {
+
+            OMElement argumentsElem = fac.createOMElement(ARGS, synNS);
+
+            for (PayloadFactoryMediator.Argument arg : argList) {
+
+                OMElement argElem = fac.createOMElement(ARG, synNS);
+
+                if (arg.getValue() != null) {
+                    argElem.addAttribute(fac.createOMAttribute(VALUE, nullNS, 
arg.getValue()));
+                } else if (arg.getExpression() != null) {
+                    SynapseXPathSerializer.serializeXPath(arg.getExpression(), 
argElem, EXPRESSION);
+                }
+                argumentsElem.addChild(argElem);
+            }
+            payloadFactoryElem.addChild(argumentsElem);
+        }
+
+        return payloadFactoryElem;
+    }
+
+    public String getMediatorClassName() {
+        return PayloadFactoryMediator.class.getName();
+    }
+
+}

Added: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/PayloadFactoryMediator.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/PayloadFactoryMediator.java?rev=1211361&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/PayloadFactoryMediator.java
 (added)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/PayloadFactoryMediator.java
 Wed Dec  7 10:01:53 2011
@@ -0,0 +1,155 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.synapse.mediators.transform;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.mediators.AbstractMediator;
+import org.apache.synapse.util.xpath.SynapseXPath;
+
+import javax.xml.stream.XMLStreamException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Payload-factory mediator creates a new SOAP payload for the message, 
replacing the existing one.
+ * <pre>printf()</pre> style formatting is used to configure the 
transformation performed by the
+ * mediator.<p/>
+ * Each argument in the mediator configuration could be a static value or an 
XPath expression.
+ * When an expression is used, argument value is fetched at runtime by 
evaluating the provided XPath
+ * expression against the existing SOAP message/message context.
+ */
+public class PayloadFactoryMediator extends AbstractMediator {
+
+    private String format;
+    private List<Argument> argumentList = new ArrayList<Argument>();
+
+    private Pattern pattern = Pattern.compile("\\$(\\d)+");
+
+    public boolean mediate(MessageContext synCtx) {
+
+        SOAPBody soapBody = synCtx.getEnvelope().getBody();
+
+        StringBuffer result = new StringBuffer();
+        transformPayload(result, synCtx);
+
+        OMElement resultElement;
+        try {
+            resultElement = AXIOMUtil.stringToOM(result.toString());
+        } catch (XMLStreamException e) {
+            handleException("Unable to create a valid XML payload. Invalid 
format/arguments are " +
+                    "provided in the payloadFactory mediator configuration", 
synCtx);
+            return false;
+        }
+
+        // replace the existing payload with the new payload
+        for (Iterator itr = soapBody.getChildElements(); itr.hasNext();) {
+            OMElement child = (OMElement) itr.next();
+            child.detach();
+        }
+
+        for (Iterator itr = resultElement.getChildElements(); itr.hasNext();) {
+            OMElement child = (OMElement) itr.next();
+            soapBody.addChild(child);
+        }
+
+        return true;
+    }
+
+    private void transformPayload(StringBuffer result, MessageContext synCtx) {
+        Object[] argValues = getArgValues(synCtx);
+        Matcher matcher = pattern.matcher("<dummy>" + format + "</dummy>");
+        while (matcher.find()) {
+            String matchSeq = matcher.group();
+            int argIndex = Integer.parseInt(matchSeq.substring(1));
+            matcher.appendReplacement(result, argValues[argIndex - 
1].toString());
+        }
+        matcher.appendTail(result);
+    }
+
+    private Object[] getArgValues(MessageContext synCtx) {
+
+        Object[] argValues = new Object[argumentList.size()];
+        for (int i = 0; i < argumentList.size(); ++i) {
+            Argument arg = argumentList.get(i);
+            if (arg.getValue() != null) {
+                argValues[i] = arg.getValue();
+            } else if (arg.getExpression() != null) {
+                String value = arg.getExpression().stringValueOf(synCtx);
+                if (value != null) {
+                    argValues[i] = value;
+                } else {
+                    argValues[i] = "";
+                }
+            } else {
+                handleException("Unexpected argument type detected in the 
payloadFactory " +
+                        "mediator configuration", synCtx);
+            }
+        }
+        return argValues;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    public void setFormat(String format) {
+        this.format = format;
+    }
+
+    public void addArgument(Argument arg) {
+        argumentList.add(arg);
+    }
+
+    public List<Argument> getArgumentList() {
+        return argumentList;
+    }
+
+    /**
+     * Represents an argument provided in the payload factory mediator 
configuration.
+     */
+    public static class Argument {
+
+        private String value;
+        private SynapseXPath expression;
+
+        public String getValue() {
+            return value;
+        }
+
+        public void setValue(String value) {
+            this.value = value;
+        }
+
+        public SynapseXPath getExpression() {
+            return expression;
+        }
+
+        public void setExpression(SynapseXPath expression) {
+            this.expression = expression;
+        }
+    }
+
+}


Reply via email to