You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by su...@apache.org on 2011/01/18 05:54:10 UTC
svn commit: r1060189 - in
/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary:
./ EnrichMediator.java Source.java Target.java
Author: supun
Date: Tue Jan 18 04:54:10 2011
New Revision: 1060189
URL: http://svn.apache.org/viewvc?rev=1060189&view=rev
Log:
adding the enrich mediator
Added:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/EnrichMediator.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Source.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/EnrichMediator.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/EnrichMediator.java?rev=1060189&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/EnrichMediator.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/EnrichMediator.java Tue Jan 18 04:54:10 2011
@@ -0,0 +1,112 @@
+/*
+ * 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.elementary;
+
+import org.apache.axiom.om.OMNode;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.SynapseLog;
+import org.apache.synapse.mediators.AbstractMediator;
+import org.jaxen.JaxenException;
+
+import java.util.ArrayList;
+
+/**
+ * Syntax for EnrichMediator
+ * <p/>
+ * <xmlStore>
+ * <source [clone=true | false] type=[custom|envelope|body|property] xpath="" property=""/>
+ * <target [replace=true | false] type=[custom|envelope|body|property] xpath="" property=""/>
+ * </xmlStore>
+ * <p/>
+ * This mediator will first get an OMELement from the source. Then put it to the current message
+ * according to the target element.
+ * <p/>
+ * Both target and source can specify a type. These are the types supported
+ * <p/>
+ * custom : xpath expression should be provided to get the xml
+ * envelope : the soap envelope
+ * body : first child of the soap body
+ * property : synapse property
+ * <p/>
+ * When specifying the source one can clone the xml by setting the clone to true. The default
+ * value for clone is false.
+ * <p/>
+ * When specifying the target one can replace the existing xml. replace is only valid for custom
+ * and body types. By default replace is true.
+ */
+
+public class EnrichMediator extends AbstractMediator {
+ public static final int CUSTOM = 0;
+
+ public static final int ENVELOPE = 1;
+
+ public static final int BODY = 2;
+
+ public static final int PROPERTY = 3;
+
+ public static final int INLINE = 4;
+
+ private Source source = null;
+
+ private Target target = null;
+
+ public boolean mediate(MessageContext synCtx) {
+ SynapseLog synLog = getLog(synCtx);
+
+ if (synLog.isTraceOrDebugEnabled()) {
+ synLog.traceOrDebug("Start : Enrich mediator");
+
+ if (synLog.isTraceTraceEnabled()) {
+ synLog.traceTrace("Message : " + synCtx.getEnvelope());
+ }
+ }
+
+ ArrayList<OMNode> sourceNodeList;
+
+ try {
+ sourceNodeList = source.evaluate(synCtx, synLog);
+ if (sourceNodeList == null) {
+ handleException("Failed to get the source for Enriching : ", synCtx);
+ } else {
+ target.insert(synCtx, sourceNodeList, synLog);
+ }
+ } catch (JaxenException e) {
+ handleException("Failed to get the source for Enriching", e, synCtx);
+ }
+
+ synLog.traceOrDebug("End : Enrich mediator");
+ return true;
+ }
+
+ public Source getSource() {
+ return source;
+ }
+
+ public Target getTarget() {
+ return target;
+ }
+
+ public void setSource(Source source) {
+ this.source = source;
+ }
+
+ public void setTarget(Target target) {
+ this.target = target;
+ }
+}
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Source.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Source.java?rev=1060189&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Source.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Source.java Tue Jan 18 04:54:10 2011
@@ -0,0 +1,272 @@
+/*
+* 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.elementary;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMText;
+import org.apache.axiom.om.impl.builder.StAXBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axiom.soap.SOAP12Constants;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.SynapseLog;
+import org.apache.synapse.util.MessageHelper;
+import org.apache.synapse.util.xpath.SynapseXPath;
+import org.jaxen.JaxenException;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The source of the XML node to be stored. The source can be a
+ * 1. Property
+ * 2. XPath Expression
+ * 3. SOAP Envelope
+ * 4. SOAP Body
+ * <p/>
+ * If clone is true a clone will be create and stored from the origincal content. Otherwise a
+ * reference will be stored.
+ * <p/>
+ * In case of property a OMElement is stored in a property and it will be fetched.
+ * <p/>
+ * In case of a XPath expression, it will be evaluated to get the OMElement
+ * <p/>
+ * In case of SOAPEnvelope entire SOAP envelope will be stored
+ * <p/>
+ * In case of Body, the first child of body will be stored
+ */
+
+public class Source {
+
+ private SynapseXPath xpath = null;
+
+ private String property = null;
+
+ private int sourceType = EnrichMediator.CUSTOM;
+
+ private boolean clone = true;
+
+ private OMElement inlineElement = null;
+
+ private String inlineKey = null;
+
+
+ public ArrayList<OMNode> evaluate(MessageContext synCtx, SynapseLog synLog)
+ throws JaxenException {
+
+ ArrayList<OMNode> sourceNodeList = new ArrayList<OMNode>();
+
+ if (sourceType == EnrichMediator.CUSTOM) {
+ assert xpath != null : "XPath should be non null in case of CUSTOM";
+
+ List selectedNodeList = xpath.selectNodes(synCtx);
+ if (selectedNodeList != null && selectedNodeList.size() != 0) {
+ for (Object o : selectedNodeList) {
+ if (o instanceof OMElement) {
+ if (clone) {
+ sourceNodeList.add(((OMElement) o).cloneOMElement());
+ } else {
+ sourceNodeList.add((OMElement) o);
+ }
+ } else if (o instanceof OMText) {
+ sourceNodeList.add((OMText) o);
+ }
+ }
+ } else {
+ synLog.error("Specified node by xpath cannot be found.");
+ }
+ } else if (sourceType == EnrichMediator.BODY) {
+ if (clone) {
+ sourceNodeList.add(synCtx.getEnvelope().getBody().getFirstElement().cloneOMElement());
+ } else {
+ sourceNodeList.add(synCtx.getEnvelope().getBody().getFirstElement());
+ }
+ } else if (sourceType == EnrichMediator.ENVELOPE) {
+ if (clone) {
+ sourceNodeList.add(MessageHelper.cloneSOAPEnvelope(synCtx.getEnvelope()));
+ } else {
+ sourceNodeList.add(synCtx.getEnvelope());
+ }
+ } else if (sourceType == EnrichMediator.PROPERTY) {
+ assert property != null : "property shouldn't be null when type is PROPERTY";
+
+ Object o = synCtx.getProperty(property);
+
+ if (o instanceof OMElement) {
+ if (clone) {
+ sourceNodeList.add(((OMElement) o).cloneOMElement());
+ }
+ } else if (o instanceof String) {
+ String soap = (String) o;
+ try {
+ XMLStreamReader xmlReader =
+ StAXUtils.createXMLStreamReader(new ByteArrayInputStream(soap.getBytes()));
+ StAXBuilder builder = new StAXSOAPModelBuilder(xmlReader);
+ OMElement elem = builder.getDocumentElement();
+ elem.build();
+ if (elem instanceof SOAPEnvelope) {
+ SOAPEnvelope soapEnvelope = (SOAPEnvelope) elem;
+ String soapNamespace = soapEnvelope.getNamespace().getNamespaceURI();
+ if (soapEnvelope.getHeader() == null) {
+ SOAPFactory soapFactory;
+ if (soapNamespace.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
+ soapFactory = OMAbstractFactory.getSOAP12Factory();
+ } else {
+ soapFactory = OMAbstractFactory.getSOAP11Factory();
+ }
+ soapFactory.createSOAPHeader(soapEnvelope);
+ }
+ sourceNodeList.add(soapEnvelope);
+ } else {
+ sourceNodeList.add(elem);
+ }
+ } catch (XMLStreamException e) {
+ synLog.error("Source Property cannot be parsed : " + e.getStackTrace().toString());
+ }
+ } else if (o instanceof ArrayList) {
+ ArrayList nodesList = (ArrayList) o;
+ for (Object node : nodesList) {
+ if (node instanceof OMElement) {
+ if (node instanceof SOAPEnvelope) {
+ SOAPEnvelope soapEnvelope = (SOAPEnvelope) node;
+ String soapNamespace = null;
+
+ if (soapEnvelope.getNamespace() != null) {
+ soapNamespace = soapEnvelope.getNamespace().getNamespaceURI();
+ }
+ if (soapEnvelope.getHeader() == null && soapNamespace != null) {
+ SOAPFactory soapFactory;
+ if (soapNamespace.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
+ soapFactory = OMAbstractFactory.getSOAP12Factory();
+ } else {
+ soapFactory = OMAbstractFactory.getSOAP11Factory();
+ }
+ soapFactory.createSOAPHeader(soapEnvelope);
+ }
+ sourceNodeList.add(soapEnvelope);
+ } else {
+ OMElement ele = (OMElement) node;
+ sourceNodeList.add(ele);
+ }
+ }
+ }
+ } else {
+ synLog.error("Invalid source property type.");
+ }
+ } else if (sourceType == EnrichMediator.INLINE) {
+ if (inlineElement != null) {
+ if (inlineElement.getQName().getLocalPart().equals("Envelope")) {
+ SOAPEnvelope soapEnvelope = getSOAPEnvFromOM(inlineElement);
+ if (soapEnvelope != null) {
+ sourceNodeList.add(soapEnvelope);
+ } else {
+ synLog.error("Inline Source is not a valid SOAPEnvelope.");
+ }
+ } else {
+ sourceNodeList.add(inlineElement.cloneOMElement());
+ }
+ } else if (inlineKey != null) {
+ Object inlineObj = synCtx.getEntry(inlineKey);
+ if (inlineObj instanceof OMElement) {
+ if (((OMElement) inlineObj).getQName().getLocalPart().equals("Envelope")) {
+ SOAPEnvelope soapEnvelope = getSOAPEnvFromOM((OMElement) inlineObj);
+ if (soapEnvelope != null) {
+ sourceNodeList.add(soapEnvelope);
+ } else {
+ synLog.error("Specified Resource as Source is not a valid SOAPEnvelope.");
+ }
+ } else {
+ sourceNodeList.add((OMElement) inlineObj);
+ }
+ }
+ }
+ }
+ return sourceNodeList;
+ }
+
+ private SOAPEnvelope getSOAPEnvFromOM(OMElement inlineElement) {
+ SOAPFactory soapFactory;
+ if (inlineElement.getQName().getNamespaceURI().equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
+ soapFactory = OMAbstractFactory.getSOAP12Factory();
+ } else {
+ soapFactory = OMAbstractFactory.getSOAP11Factory();
+ }
+
+ StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(inlineElement.getXMLStreamReader(), soapFactory, inlineElement.getQName().getNamespaceURI());
+ return builder.getSOAPEnvelope();
+ }
+
+ public SynapseXPath getXpath() {
+ return xpath;
+ }
+
+ public void setXpath(SynapseXPath xpath) {
+ this.xpath = xpath;
+ }
+
+ public int getSourceType() {
+ return sourceType;
+ }
+
+ public void setSourceType(int sourceType) {
+ this.sourceType = sourceType;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ public boolean isClone() {
+ return clone;
+ }
+
+ public void setClone(boolean clone) {
+ this.clone = clone;
+ }
+
+ public void setInlineElement(OMElement inlineElement) {
+ this.inlineElement = inlineElement;
+ }
+
+ public OMElement getInlineElement() {
+ return inlineElement;
+ }
+
+ public String getInlineKey() {
+ return inlineKey;
+ }
+
+ public void setInlineKey(String inlineKey) {
+ this.inlineKey = inlineKey;
+ }
+}
+
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java?rev=1060189&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java Tue Jan 18 04:54:10 2011
@@ -0,0 +1,206 @@
+/*
+ * 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.elementary;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMText;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axis2.AxisFault;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.SynapseException;
+import org.apache.synapse.SynapseLog;
+import org.apache.synapse.util.xpath.SynapseXPath;
+import org.jaxen.JaxenException;
+
+import java.util.ArrayList;
+
+/**
+ * Inset an Axiom element to the current message. The target to insert the OMElement can be
+ * 1. A property
+ * 2. SOAP Body child element
+ * 3. SOAP envelope
+ * 4. A XPath expression to get the correct node
+ * <p/>
+ * In case the target is an SOAP Envelope, the current SOAP envelope will be replaced by the
+ * OMNode. So the OMNode must me a SOAPEnvelope.
+ * <p/>
+ * In case of Body the first child of the Body will be replaced by the new Node or a sibling
+ * will be added to it depending on the replace property.
+ * <p/>
+ * In case of Expression a SOAP Element will be chosen based on the XPath. If replace is true
+ * that element will be replaced, otherwise a sibling will be added to that element.
+ * <p/>
+ * Property case is simple. The OMNode will be stored in the given property
+ */
+
+public class Target {
+
+ private SynapseXPath xpath = null;
+
+ private String property = null;
+
+ private int targetType = EnrichMediator.CUSTOM;
+
+ public static final String ACTION_REPLACE = "replace";
+
+ public static final String ACTION_ADD_CHILD = "child";
+
+ public static final String ACTION_ADD_SIBLING = "sibiling";
+
+ //private boolean replace = true;
+ private String action = ACTION_REPLACE;
+
+ public void insert(MessageContext synContext,
+ ArrayList<OMNode> sourceNodeList, SynapseLog synLog) throws JaxenException {
+
+ if (targetType == EnrichMediator.CUSTOM) {
+ assert xpath != null : "Xpath cannot be null for CUSTOM";
+
+ if (sourceNodeList.isEmpty()) {
+ synLog.error("Cannot Enrich message from an empty source.");
+ return;
+ }
+
+ Object targetObj = xpath.selectSingleNode(synContext);
+
+ if (targetObj instanceof OMElement) {
+ OMElement targetElem = (OMElement) targetObj;
+ insertElement(sourceNodeList, targetElem, synLog);
+ } else if (targetObj instanceof OMText) {
+ OMText targetText = (OMText) targetObj;
+ if (sourceNodeList.get(0) instanceof OMText) {
+ if (targetText.getParent() != null) {
+ Object parent = targetText.getParent();
+ if (parent instanceof OMElement) {
+ ((OMElement)parent).setText(((OMText) sourceNodeList.get(0)).getText());
+ }
+ }
+ } else if (sourceNodeList.get(0) instanceof OMElement) {
+ Object targetParent = targetText.getParent();
+ if (targetParent instanceof OMElement) {
+ targetText.detach();
+ ((OMElement)targetParent).addChild(sourceNodeList.get(0));
+ }
+ }
+ } else {
+ synLog.error("Invalid Target object to be enrich.");
+ throw new SynapseException("Invalid Target object to be enrich.");
+ }
+ } else if (targetType == EnrichMediator.BODY) {
+ SOAPEnvelope env = synContext.getEnvelope();
+ SOAPBody body = env.getBody();
+
+ OMElement e = body.getFirstElement();
+
+ if (e != null) {
+ insertElement(sourceNodeList, e, synLog);
+ } else {
+ // if the body is empty just add as a child
+ for (OMNode elem : sourceNodeList) {
+ if (elem instanceof OMElement) {
+ body.addChild(elem);
+ } else {
+ synLog.error("Invalid Object type to be inserted into message body");
+ }
+ }
+ }
+ } else if (targetType == EnrichMediator.ENVELOPE) {
+ OMNode node = sourceNodeList.get(0); /*TODO*/
+ if (node instanceof SOAPEnvelope) {
+ try {
+ synContext.setEnvelope((SOAPEnvelope) node);
+ } catch (AxisFault axisFault) {
+ synLog.error("Failed to set the SOAP Envelope");
+ throw new SynapseException("Failed to set the SOAP Envelope");
+ }
+ } else {
+ synLog.error("SOAPEnvelope is expected");
+ throw new SynapseException("A SOAPEnvelope is expected");
+ }
+ } else if (targetType == EnrichMediator.PROPERTY) {
+ assert property != null : "Property cannot be null for PROPERTY type";
+ synContext.setProperty(property, sourceNodeList);
+ }
+ }
+
+ private void insertElement(ArrayList<OMNode> sourceNodeList, OMElement e, SynapseLog synLog) {
+ if (action.equals(ACTION_REPLACE)) {
+ boolean isInserted = false;
+ for (OMNode elem : sourceNodeList) {
+ if (elem instanceof OMElement) {
+ e.insertSiblingAfter(elem);
+ isInserted = true;
+ } else {
+ synLog.error("Invalid Source object to be inserted.");
+ }
+ }
+ if (isInserted) {
+ e.detach();
+ }
+ } else if (action.equals(ACTION_ADD_CHILD)) {
+ for (OMNode elem : sourceNodeList) {
+ if (elem instanceof OMElement) {
+ e.addChild(elem);
+ }
+ }
+ } else if (action.equals(ACTION_ADD_SIBLING)) {
+ for (OMNode elem : sourceNodeList) {
+ if (elem instanceof OMElement) {
+ e.insertSiblingAfter(elem);
+ }
+ }
+ }
+ }
+
+ public SynapseXPath getXpath() {
+ return xpath;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+
+ public int getTargetType() {
+ return targetType;
+ }
+
+ public void setXpath(SynapseXPath xpath) {
+ this.xpath = xpath;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ public void setTargetType(int targetType) {
+ this.targetType = targetType;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public void setAction(String action) {
+ this.action = action;
+ }
+}
+
+