001: package org.apache.synapse.util;
002:
003: import org.apache.synapse.MessageContext;
004: import org.apache.synapse.mediators.eip.EIPConstants;
005: import org.apache.synapse.core.axis2.Axis2MessageContext;
006: import org.apache.axiom.soap.SOAPEnvelope;
007: import org.apache.axiom.soap.SOAPHeader;
008: import org.apache.axiom.soap.SOAPHeaderBlock;
009: import org.apache.axiom.soap.SOAP11Constants;
010: import org.apache.axiom.attachments.Attachments;
011: import org.apache.axiom.om.OMElement;
012: import org.apache.axiom.om.OMNamespace;
013: import org.apache.axiom.om.OMAbstractFactory;
014: import org.apache.axiom.om.OMNode;
015: import org.apache.axis2.addressing.AddressingConstants;
016: import org.apache.axis2.AxisFault;
017: import org.apache.axis2.Constants;
018:
019: import java.util.Iterator;
020: import java.util.ArrayList;
021: import java.util.Map;
022: import java.util.HashMap;
023:
024: /**
025: *
026: */
027: public class MessageHelper {
028:
029: /**
030: * This method will simulate cloning the message context and creating an exact copy of the
031: * passed message. One should use this method with care; that is because, inside the new MC,
032: * most of the attributes of the MC like opCtx and so on are still kept as references inside
033: * the axis2 MessageContext for performance improvements. (Note: U dont have to worrie
034: * about the SOAPEnvelope, it is a cloned copy and not a reference from any other MC)
035: *
036: * @param synCtx - this will be cloned
037: * @return cloned Synapse MessageContext
038: * @throws AxisFault if there is a failure in creating the new Synapse MC or in a failure in
039: * clonning the underlying axis2 MessageContext
040: *
041: * @see MessageHelper#cloneAxis2MessageContext
042: */
043: public static MessageContext cloneMessageContext(
044: MessageContext synCtx) throws AxisFault {
045:
046: // creates the new MessageContext and clone the internal axis2 MessageContext
047: // inside the synapse message context and place that in the new one
048: MessageContext newCtx = synCtx.getEnvironment()
049: .createMessageContext();
050: Axis2MessageContext axis2MC = (Axis2MessageContext) newCtx;
051: axis2MC
052: .setAxis2MessageContext(cloneAxis2MessageContext(((Axis2MessageContext) synCtx)
053: .getAxis2MessageContext()));
054:
055: newCtx.setConfiguration(synCtx.getConfiguration());
056: newCtx.setEnvironment(synCtx.getEnvironment());
057: newCtx.setContextEntries(synCtx.getContextEntries());
058:
059: // set the parent corelation details to the cloned MC -
060: // for the use of aggregation like tasks
061: newCtx.setProperty(EIPConstants.AGGREGATE_CORRELATION, synCtx
062: .getMessageID());
063:
064: // copying the core parameters of the synapse MC
065: newCtx.setTo(synCtx.getTo());
066: newCtx.setReplyTo(synCtx.getReplyTo());
067: newCtx.setSoapAction(synCtx.getSoapAction());
068: newCtx.setWSAAction(synCtx.getWSAAction());
069: newCtx.setResponse(synCtx.isResponse());
070:
071: // copy all the synapse level properties to the newCtx
072: for (Object o : synCtx.getPropertyKeySet()) {
073: // If there are non String keyed properties neglect them rathern than trow exception
074: if (o instanceof String) {
075: newCtx.setProperty((String) o, synCtx
076: .getProperty((String) o));
077: }
078: }
079:
080: return newCtx;
081: }
082:
083: /**
084: * This method will simulate cloning the message context and creating an exact copy of the
085: * passed message. One should use this method with care; that is because, inside the new MC,
086: * most of the attributes of the MC like opCtx and so on are still kept as references. Otherwise
087: * there will be perf issues. But ..... this may reveal in some conflicts in the cloned message
088: * if you try to do advanced mediations with the cloned message, in which case you should
089: * mannually get a clone of the changing part of the MC and set that cloned part to your MC.
090: * Changing the MC after doing that will solve most of the issues. (Note: U dont have to worrie
091: * about the SOAPEnvelope, it is a cloned copy and not a reference from any other MC)
092: *
093: * @param mc - this will be cloned for getting an exact copy
094: * @return cloned MessageContext from the given mc
095: * @throws AxisFault if there is a failure in copying the certain attributes of the
096: * provided message context
097: */
098: public static org.apache.axis2.context.MessageContext cloneAxis2MessageContext(
099: org.apache.axis2.context.MessageContext mc)
100: throws AxisFault {
101:
102: org.apache.axis2.context.MessageContext newMC = clonePartially(mc);
103: newMC.setEnvelope(cloneSOAPEnvelope(mc.getEnvelope()));
104:
105: newMC.setServiceContext(mc.getServiceContext());
106: newMC.setOperationContext(mc.getOperationContext());
107: newMC.setAxisMessage(mc.getAxisMessage());
108: if (newMC.getAxisMessage() != null) {
109: newMC.getAxisMessage().setParent(mc.getAxisOperation());
110: }
111: newMC.setAxisService(mc.getAxisService());
112:
113: // copying transport related parts from the original
114: newMC.setTransportIn(mc.getTransportIn());
115: newMC.setTransportOut(mc.getTransportOut());
116: newMC
117: .setProperty(
118: org.apache.axis2.Constants.OUT_TRANSPORT_INFO,
119: mc
120: .getProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO));
121:
122: newMC
123: .setProperty(
124: org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS,
125: getClonedTransportHeaders(mc));
126:
127: return newMC;
128: }
129:
130: public static Map getClonedTransportHeaders(
131: org.apache.axis2.context.MessageContext msgCtx) {
132:
133: Map headers = (Map) msgCtx
134: .getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
135: Map clonedHeaders = new HashMap();
136:
137: if (headers != null && headers.isEmpty()) {
138: for (Object o : headers.keySet()) {
139: String headerName = (String) o;
140: clonedHeaders.put(headerName, headers.get(headerName));
141: }
142: }
143:
144: return clonedHeaders;
145: }
146:
147: public static org.apache.axis2.context.MessageContext clonePartially(
148: org.apache.axis2.context.MessageContext ori)
149: throws AxisFault {
150:
151: org.apache.axis2.context.MessageContext newMC = new org.apache.axis2.context.MessageContext();
152:
153: // do not copy options from the original
154: newMC.setConfigurationContext(ori.getConfigurationContext());
155: newMC.setMessageID(UUIDGenerator.getUUID());
156: newMC.setTo(ori.getTo());
157: newMC.setSoapAction(ori.getSoapAction());
158:
159: newMC
160: .setProperty(
161: org.apache.axis2.Constants.Configuration.CHARACTER_SET_ENCODING,
162: ori
163: .getProperty(org.apache.axis2.Constants.Configuration.CHARACTER_SET_ENCODING));
164: newMC
165: .setProperty(
166: org.apache.axis2.Constants.Configuration.ENABLE_MTOM,
167: ori
168: .getProperty(org.apache.axis2.Constants.Configuration.ENABLE_MTOM));
169: newMC
170: .setProperty(
171: org.apache.axis2.Constants.Configuration.ENABLE_SWA,
172: ori
173: .getProperty(org.apache.axis2.Constants.Configuration.ENABLE_SWA));
174: newMC.setProperty(Constants.Configuration.HTTP_METHOD, ori
175: .getProperty(Constants.Configuration.HTTP_METHOD));
176: //coping the Message type from req to res to get the message formatters working correctly.
177: newMC.setProperty(Constants.Configuration.MESSAGE_TYPE, ori
178: .getProperty(Constants.Configuration.MESSAGE_TYPE));
179:
180: newMC.setDoingREST(ori.isDoingREST());
181: newMC.setDoingMTOM(ori.isDoingMTOM());
182: newMC.setDoingSwA(ori.isDoingSwA());
183:
184: // if the original request carries any attachments, copy them to the clone
185: // as well, except for the soap part if any
186: Attachments attachments = ori.getAttachmentMap();
187: if (attachments != null
188: && attachments.getAllContentIDs().length > 0) {
189: String[] cIDs = attachments.getAllContentIDs();
190: String soapPart = attachments.getSOAPPartContentID();
191: for (String cID : cIDs) {
192: if (!cID.equals(soapPart)) {
193: newMC.addAttachment(cID, attachments
194: .getDataHandler(cID));
195: }
196: }
197: }
198:
199: for (Object o : ori.getOptions().getProperties().keySet()) {
200: String key = (String) o;
201: newMC.getOptions().setProperty(key,
202: ori.getOptions().getProperty(key));
203: }
204:
205: for (Object o1 : ori.getProperties().keySet()) {
206: String key = (String) o1;
207: if (key != null) {
208: // In a clustered environment, all the properties that need to be relpicated,
209: // are replicated explicitly by the corresponding Mediators (Ex: throttle,
210: // cache), and therefore we should avoid any implicit replication
211: newMC.setNonReplicableProperty(key, ori
212: .getPropertyNonReplicable(key));
213: }
214: }
215:
216: newMC.setServerSide(false);
217:
218: return newMC;
219: }
220:
221: /**
222: * This method will clone the provided SOAPEnvelope and returns the cloned envelope
223: * as an exact copy of the provided envelope
224: *
225: * @param envelope - this will be cloned to get the new envelope
226: * @return cloned SOAPEnvelope from the provided one
227: */
228: public static SOAPEnvelope cloneSOAPEnvelope(SOAPEnvelope envelope) {
229: SOAPEnvelope newEnvelope;
230: if (SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(envelope
231: .getBody().getNamespace().getNamespaceURI())) {
232: newEnvelope = OMAbstractFactory.getSOAP11Factory()
233: .getDefaultEnvelope();
234: } else {
235: newEnvelope = OMAbstractFactory.getSOAP12Factory()
236: .getDefaultEnvelope();
237: }
238:
239: if (envelope.getHeader() != null) {
240: Iterator itr = envelope.getHeader().cloneOMElement()
241: .getChildren();
242: while (itr.hasNext()) {
243: newEnvelope.getHeader().addChild((OMNode) itr.next());
244: }
245: }
246:
247: if (envelope.getBody() != null) {
248: Iterator itr = envelope.getBody().cloneOMElement()
249: .getChildren();
250: while (itr.hasNext()) {
251: newEnvelope.getBody().addChild((OMNode) itr.next());
252: }
253: }
254:
255: return newEnvelope;
256: }
257:
258: /**
259: * Removes Submission and Final WS-Addressing headers and return the SOAPEnvelope from the given
260: * message context
261: *
262: * @param axisMsgCtx the Axis2 Message context
263: * @return the resulting SOAPEnvelope
264: */
265: public static SOAPEnvelope removeAddressingHeaders(
266: org.apache.axis2.context.MessageContext axisMsgCtx) {
267:
268: SOAPEnvelope env = axisMsgCtx.getEnvelope();
269: SOAPHeader soapHeader = env.getHeader();
270: ArrayList addressingHeaders;
271:
272: if (soapHeader != null) {
273: addressingHeaders = soapHeader
274: .getHeaderBlocksWithNSURI(AddressingConstants.Submission.WSA_NAMESPACE);
275:
276: if (addressingHeaders != null
277: && addressingHeaders.size() != 0) {
278: detachAddressingInformation(addressingHeaders);
279:
280: } else {
281: addressingHeaders = soapHeader
282: .getHeaderBlocksWithNSURI(AddressingConstants.Final.WSA_NAMESPACE);
283: if (addressingHeaders != null
284: && addressingHeaders.size() != 0) {
285: detachAddressingInformation(addressingHeaders);
286: }
287: }
288: }
289: return env;
290: }
291:
292: /**
293: * Remove WS-A headers
294: *
295: * @param headerInformation headers to be removed
296: */
297: private static void detachAddressingInformation(
298: ArrayList headerInformation) {
299: for (Object o : headerInformation) {
300: if (o instanceof SOAPHeaderBlock) {
301: SOAPHeaderBlock headerBlock = (SOAPHeaderBlock) o;
302: headerBlock.detach();
303: } else if (o instanceof OMElement) {
304: // work around for a known addressing bug which sends non SOAPHeaderBlock objects
305: OMElement om = (OMElement) o;
306: OMNamespace ns = om.getNamespace();
307: if (ns != null
308: && (AddressingConstants.Submission.WSA_NAMESPACE
309: .equals(ns.getNamespaceURI()) || AddressingConstants.Final.WSA_NAMESPACE
310: .equals(ns.getNamespaceURI()))) {
311: om.detach();
312: }
313: }
314: }
315: }
316:
317: }
|