| /* |
| * 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.core.axis2; |
| |
| import org.apache.axiom.om.OMAbstractFactory; |
| import org.apache.axiom.om.OMAttribute; |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.om.OMNode; |
| import org.apache.axiom.soap.*; |
| import org.apache.axis2.AxisFault; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.synapse.SynapseException; |
| import org.apache.synapse.util.MessageHelper; |
| |
| import javax.xml.namespace.QName; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| public class SOAPUtils { |
| |
| private static final Log log = LogFactory.getLog(SOAPUtils.class); |
| |
| /** |
| * Converts the SOAP version of the message context. Creates a new envelope of the given SOAP |
| * version, copy headers and bodies from the old envelope and sets the new envelope to the same |
| * message context. |
| * |
| * @param axisOutMsgCtx messageContext where version conversion is done |
| * @param soapVersionURI either org.apache.axis2.namespace.Constants.URI_SOAP12_ENV or |
| * org.apache.axis2.namespace.Constants.URI_SOAP11_ENV |
| * @throws AxisFault in case of an error in conversion |
| */ |
| public static void convertSoapVersion(org.apache.axis2.context.MessageContext axisOutMsgCtx, |
| String soapVersionURI) throws AxisFault { |
| |
| if (org.apache.axis2.namespace.Constants.URI_SOAP12_ENV.equals(soapVersionURI)) { |
| convertSOAP11toSOAP12(axisOutMsgCtx); |
| } else if (org.apache.axis2.namespace.Constants.URI_SOAP11_ENV.equals(soapVersionURI)) { |
| convertSOAP12toSOAP11(axisOutMsgCtx); |
| } else { |
| throw new SynapseException("Invalid soapVersionURI:" + soapVersionURI); |
| } |
| } |
| |
| private static String SOAP_ATR_ACTOR = "actor"; |
| private static String SOAP_ATR_ROLE = "role"; |
| private static String SOAP_ATR_MUST_UNDERSTAND = "mustUnderstand"; |
| |
| /** |
| * Converts the version of the the message context to 1.2. |
| * <br /> |
| * <b>Message Changes:</b> |
| * <ol> |
| * <li>Convert envelope, header elements</li> |
| * <li>For each header block convert attribute actor to role</li> |
| * <li>For each header block convert mustUnderstand value type</li> |
| * <li>For each header block remove 1.1 namespaced other attributes</li> |
| * </ol> |
| * |
| * <b>Fault Changes:</b> |
| * <ol> |
| * <li>Convert fault element</li> |
| * <li>faultcode to Fault/Code</li> |
| * <li>faultstring to First Fault/Reason/Text with lang=en</li> |
| * </ol> |
| * |
| * @param axisOutMsgCtx message context to be converted |
| * @throws AxisFault incase conversion process fails |
| */ |
| public static void convertSOAP11toSOAP12( |
| org.apache.axis2.context.MessageContext axisOutMsgCtx) throws AxisFault { |
| |
| if(log.isDebugEnabled()) { |
| log.debug("convert SOAP11 to SOAP12"); |
| } |
| |
| SOAPEnvelope clonedOldEnv = MessageHelper.cloneSOAPEnvelope(axisOutMsgCtx.getEnvelope()); |
| |
| SOAPFactory soap12Factory = OMAbstractFactory.getSOAP12Factory(); |
| SOAPEnvelope newEnvelope = soap12Factory.getDefaultEnvelope(); |
| |
| if (clonedOldEnv.getHeader() != null) { |
| Iterator itr = clonedOldEnv.getHeader().getChildren(); |
| while (itr.hasNext()) { |
| OMNode omNode = (OMNode) itr.next(); |
| |
| if (omNode instanceof SOAPHeaderBlock) { |
| SOAPHeaderBlock soapHeader = (SOAPHeaderBlock) omNode; |
| SOAPHeaderBlock newSOAPHeader = soap12Factory.createSOAPHeaderBlock( |
| soapHeader.getLocalName(), soapHeader.getNamespace()); |
| Iterator allAttributes = soapHeader.getAllAttributes(); |
| |
| while(allAttributes.hasNext()) { |
| OMAttribute attr = (OMAttribute) allAttributes.next(); |
| if(attr.getNamespace() != null |
| && SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals( |
| attr.getNamespace().getNamespaceURI())) { |
| String attrName = attr.getLocalName(); |
| |
| if(SOAP_ATR_ACTOR.equals(attrName)) { |
| OMAttribute newAtr = omNode.getOMFactory().createOMAttribute( |
| SOAP_ATR_ROLE, newEnvelope.getNamespace(), |
| attr.getAttributeValue()); |
| newSOAPHeader.addAttribute(newAtr); |
| |
| } else if(SOAP_ATR_MUST_UNDERSTAND.equals(attrName)) { |
| boolean isMustUnderstand = soapHeader.getMustUnderstand(); |
| newSOAPHeader.setMustUnderstand(isMustUnderstand); |
| |
| } else { |
| log.warn("removed unsupported attribute from SOAP 1.1 " + |
| "namespace when converting to SOAP 1.2:" + attrName); |
| } |
| |
| } else { |
| newSOAPHeader.addAttribute(attr); |
| } |
| } // while(allAttributes.hasNext()) |
| |
| Iterator itrChildren = soapHeader.getChildren(); |
| while (itrChildren.hasNext()) { |
| OMNode node = (OMNode) itrChildren.next(); |
| itrChildren.remove(); |
| newSOAPHeader.addChild(node); |
| } |
| |
| newEnvelope.getHeader().addChild(newSOAPHeader); |
| |
| } else { |
| itr.remove(); |
| newEnvelope.getHeader().addChild(omNode); |
| } |
| |
| } // while (itr.hasNext()) |
| |
| } // if (clonedOldEnv.getHeader() != null) |
| |
| if (clonedOldEnv.getBody() != null) { |
| |
| Iterator itrBodyChildren = clonedOldEnv.getBody().getChildren(); |
| while (itrBodyChildren.hasNext()) { |
| OMNode omNode = (OMNode) itrBodyChildren.next(); |
| |
| if (omNode != null && omNode instanceof SOAPFault) { |
| |
| SOAPFault soapFault = (SOAPFault) omNode; |
| SOAPFault newSOAPFault = soap12Factory.createSOAPFault(); |
| newEnvelope.getBody().addChild(newSOAPFault); |
| // get the existing envelope |
| SOAPFaultCode code = soapFault.getCode(); |
| if(code != null) { |
| SOAPFaultCode newSOAPFaultCode = soap12Factory.createSOAPFaultCode(); |
| newSOAPFault.setCode(newSOAPFaultCode); |
| |
| QName s11Code = code.getTextAsQName(); |
| if (s11Code != null) { |
| // get the corresponding SOAP12 fault code |
| // for the provided SOAP11 fault code |
| SOAPFaultValue newSOAPFaultValue |
| = soap12Factory.createSOAPFaultValue(newSOAPFaultCode); |
| newSOAPFaultValue.setText(getMappingSOAP12Code(s11Code)); |
| } |
| |
| } |
| |
| SOAPFaultReason reason = soapFault.getReason(); |
| if(reason != null) { |
| SOAPFaultReason newSOAPFaultReason |
| = soap12Factory.createSOAPFaultReason(newSOAPFault); |
| String reasonText = reason.getText(); |
| if(reasonText != null) { |
| SOAPFaultText newSOAPFaultText |
| = soap12Factory.createSOAPFaultText(newSOAPFaultReason); |
| newSOAPFaultText.setLang("en"); // hard coded |
| newSOAPFaultText.setText(reasonText); |
| } |
| newSOAPFault.setReason(newSOAPFaultReason); |
| } |
| |
| SOAPFaultDetail detail = soapFault.getDetail(); |
| if(detail != null) { |
| SOAPFaultDetail newSOAPFaultDetail |
| = soap12Factory.createSOAPFaultDetail(newSOAPFault); |
| Iterator<OMElement> iter = detail.getAllDetailEntries(); |
| while (iter.hasNext()) { |
| OMElement detailEntry = iter.next(); |
| iter.remove(); |
| newSOAPFaultDetail.addDetailEntry(detailEntry); |
| } |
| newSOAPFault.setDetail(newSOAPFaultDetail); |
| } |
| |
| } else { |
| itrBodyChildren.remove(); |
| newEnvelope.getBody().addChild(omNode); |
| |
| } // if (omNode instanceof SOAPFault) |
| |
| } // while (itrBodyChildren.hasNext()) |
| |
| } //if (clonedOldEnv.getBody() != null) |
| |
| axisOutMsgCtx.setEnvelope(newEnvelope); |
| } |
| |
| /** |
| * Converts the version of the the message context to 1.1. |
| * <br /> |
| * <b>Message Changes:</b> |
| * <ol> |
| * <li>Convert envelope, header elements</li> |
| * <li>For each header block convert attribute role to actor</li> |
| * <li>For each header block convert mustUnderstand value type</li> |
| * <li>For each header block remove 1.2 namespaced other attributes</li> |
| * </ol> |
| * |
| * <b>Fault Changes:</b> |
| * <ol> |
| * <li>Convert fault element</li> |
| * <li>Fault/Code to faultcode</li> |
| * <li>First Fault/Reason/Text to faultstring</li> |
| * </ol> |
| * @param axisOutMsgCtx message context to be converted |
| * @throws AxisFault in case of an error in conversion |
| */ |
| public static void convertSOAP12toSOAP11( |
| org.apache.axis2.context.MessageContext axisOutMsgCtx) throws AxisFault { |
| |
| if (log.isDebugEnabled()) { |
| log.debug("convert SOAP12 to SOAP11"); |
| } |
| |
| SOAPEnvelope clonedOldEnv = MessageHelper.cloneSOAPEnvelope(axisOutMsgCtx.getEnvelope()); |
| |
| SOAPFactory soap11Factory = OMAbstractFactory.getSOAP11Factory(); |
| SOAPEnvelope newEnvelope = soap11Factory.getDefaultEnvelope(); |
| if (clonedOldEnv.getHeader() != null) { |
| Iterator itr = clonedOldEnv.getHeader().getChildren(); |
| while (itr.hasNext()) { |
| OMNode omNode = (OMNode) itr.next(); |
| |
| if (omNode instanceof SOAPHeaderBlock) { |
| SOAPHeaderBlock soapHeaderBlock = (SOAPHeaderBlock) omNode; |
| SOAPHeaderBlock newSOAPHeader = soap11Factory.createSOAPHeaderBlock( |
| soapHeaderBlock.getLocalName(), soapHeaderBlock.getNamespace()); |
| |
| Iterator allAttributes = soapHeaderBlock.getAllAttributes(); |
| |
| while(allAttributes.hasNext()) { |
| OMAttribute attr = (OMAttribute) allAttributes.next(); |
| if (attr.getNamespace() != null |
| && SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals( |
| attr.getNamespace().getNamespaceURI())) { |
| String attrName = attr.getLocalName(); |
| |
| if (SOAP_ATR_ROLE.equals(attrName)) { |
| OMAttribute newAtr = omNode.getOMFactory().createOMAttribute( |
| SOAP_ATR_ACTOR, newEnvelope.getNamespace(), |
| attr.getAttributeValue()); |
| newSOAPHeader.addAttribute(newAtr); |
| |
| } else if(SOAP_ATR_MUST_UNDERSTAND.equals(attrName)) { |
| boolean isMustUnderstand = soapHeaderBlock.getMustUnderstand(); |
| newSOAPHeader.setMustUnderstand(isMustUnderstand); |
| |
| } else { |
| log.warn("removed unsupported attribute from SOAP 1.2 " + |
| "namespace when converting to SOAP 1.1:" + attrName); |
| } |
| |
| } else { |
| newSOAPHeader.addAttribute(attr); |
| } |
| } |
| |
| Iterator itrChildren = soapHeaderBlock.getChildren(); |
| while (itrChildren.hasNext()) { |
| OMNode node = (OMNode) itrChildren.next(); |
| itrChildren.remove(); |
| newSOAPHeader.addChild(node); |
| } |
| |
| newEnvelope.getHeader().addChild(newSOAPHeader); |
| |
| } else { |
| itr.remove(); |
| newEnvelope.getHeader().addChild(omNode); |
| } |
| } |
| } |
| |
| if (clonedOldEnv.getBody() != null) { |
| if (clonedOldEnv.hasFault()) { |
| SOAPFault soapFault = clonedOldEnv.getBody().getFault(); |
| SOAPFault newSOAPFault = soap11Factory.createSOAPFault(); |
| newEnvelope.getBody().addChild(newSOAPFault); |
| |
| SOAPFaultCode code = soapFault.getCode(); |
| if(code != null) { |
| SOAPFaultCode newSOAPFaultCode |
| = soap11Factory.createSOAPFaultCode(newSOAPFault); |
| |
| SOAPFaultValue value = code.getValue(); |
| if(value != null) { |
| // get the corresponding SOAP12 fault code |
| // for the provided SOAP11 fault code |
| soap11Factory.createSOAPFaultValue(newSOAPFaultCode); |
| if(value.getTextAsQName() != null) { |
| newSOAPFaultCode.setText( |
| getMappingSOAP11Code(value.getTextAsQName())); |
| } |
| } |
| } |
| |
| SOAPFaultReason reason = soapFault.getReason(); |
| if(reason != null) { |
| SOAPFaultReason newSOAPFaultReason |
| = soap11Factory.createSOAPFaultReason(newSOAPFault); |
| |
| List allSoapTexts = reason.getAllSoapTexts(); |
| Iterator iterAllSoapTexts = allSoapTexts.iterator(); |
| if (iterAllSoapTexts.hasNext()) { |
| SOAPFaultText soapFaultText = (SOAPFaultText) iterAllSoapTexts.next(); |
| iterAllSoapTexts.remove(); |
| newSOAPFaultReason.setText(soapFaultText.getText()); |
| } |
| } |
| |
| SOAPFaultDetail detail = soapFault.getDetail(); |
| if(detail != null) { |
| SOAPFaultDetail newSOAPFaultDetail |
| = soap11Factory.createSOAPFaultDetail(newSOAPFault); |
| Iterator<OMElement> iter = detail.getAllDetailEntries(); |
| while (iter.hasNext()) { |
| OMElement detailEntry = iter.next(); |
| iter.remove(); |
| newSOAPFaultDetail.addDetailEntry(detailEntry); |
| } |
| newSOAPFault.setDetail(newSOAPFaultDetail); |
| } |
| |
| } else { |
| Iterator itr = clonedOldEnv.getBody().getChildren(); |
| while (itr.hasNext()) { |
| OMNode omNode = (OMNode) itr.next(); |
| if (omNode != null) { |
| itr.remove(); |
| newEnvelope.getBody().addChild(omNode); |
| } |
| } |
| } |
| |
| } |
| |
| axisOutMsgCtx.setEnvelope(newEnvelope); |
| } |
| |
| /********************************************************************** |
| * Fault code conversions * |
| **********************************************************************/ |
| |
| private static final QName S11_FAULTCODE_VERSIONMISMATCH = new QName( |
| SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI, "VersionMismatch", |
| SOAP11Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| private static final QName S12_FAULTCODE_VERSIONMISMATCH = new QName( |
| SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI, "VersionMismatch", |
| SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| |
| private static final QName S11_FAULTCODE_MUSTUNDERSTAND = new QName( |
| SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI, "MustUnderstand", |
| SOAP11Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| private static final QName S12_FAULTCODE_MUSTUNDERSTAND = new QName( |
| SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI, "MustUnderstand", |
| SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| |
| private static final QName S11_FAULTCODE_CLIENT = new QName( |
| SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI, "Client", |
| SOAP11Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| private static final QName S12_FAULTCODE_SENDER = new QName( |
| SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI, "Sender", |
| SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| |
| private static final QName S11_FAULTCODE_SERVER = new QName( |
| SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI, "Server", |
| SOAP11Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| private static final QName S12_FAULTCODE_RECEIVER = new QName( |
| SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI, "Receiver", |
| SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| |
| private static final QName S12_FAULTCODE_DATAENCODINGUNKNOWN = new QName( |
| SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI, "DataEncodingUnknown", |
| SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX); |
| |
| private static QName getMappingSOAP12Code(QName soap11Code) { |
| if (S11_FAULTCODE_VERSIONMISMATCH.equals(soap11Code)) { |
| return S12_FAULTCODE_VERSIONMISMATCH; |
| } else if (S11_FAULTCODE_MUSTUNDERSTAND.equals(soap11Code)) { |
| return S12_FAULTCODE_MUSTUNDERSTAND; |
| } else if (S11_FAULTCODE_CLIENT.equals(soap11Code)) { |
| return S12_FAULTCODE_SENDER; |
| } else if (S11_FAULTCODE_SERVER.equals(soap11Code)) { |
| return S12_FAULTCODE_RECEIVER; |
| } else { |
| log.warn("An unidentified SOAP11 FaultCode encountered, returning a blank QName"); |
| return new QName("", ""); |
| } |
| } |
| |
| private static QName getMappingSOAP11Code(QName soap12Code) { |
| if (S12_FAULTCODE_VERSIONMISMATCH.equals(soap12Code)) { |
| return S11_FAULTCODE_VERSIONMISMATCH; |
| } else if (S12_FAULTCODE_MUSTUNDERSTAND.equals(soap12Code)) { |
| return S11_FAULTCODE_MUSTUNDERSTAND; |
| } else if (S12_FAULTCODE_SENDER.equals(soap12Code)) { |
| return S11_FAULTCODE_SERVER; |
| } else if (S12_FAULTCODE_RECEIVER.equals(soap12Code)) { |
| return S11_FAULTCODE_SERVER; |
| } else if (S12_FAULTCODE_DATAENCODINGUNKNOWN.equals(soap12Code)) { |
| log.debug("There is no matching SOAP11 code value for SOAP12 fault code " + |
| "DataEncodingUnknown, returning a blank QName"); |
| return new QName(""); |
| } else { |
| log.warn("An unidentified SOAP11 FaultCode encountered, returning a blank QName"); |
| return new QName(""); |
| } |
| } |
| } |