|
Axis 2 example source code file (AddressingOutHandler.java)
The Axis 2 AddressingOutHandler.java source code/* * 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.axis2.handlers.addressing; import org.apache.axiom.om.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.om.util.AttributeHelper; import org.apache.axiom.om.util.ElementHelper; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFactory; import org.apache.axiom.soap.SOAPFault; import org.apache.axiom.soap.SOAPHeader; import org.apache.axiom.soap.SOAPHeaderBlock; import org.apache.axis2.AxisFault; import org.apache.axis2.addressing.AddressingConstants; import org.apache.axis2.addressing.AddressingFaultsHelper; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.addressing.EndpointReferenceHelper; import org.apache.axis2.addressing.RelatesTo; import org.apache.axis2.addressing.i18n.AddressingMessages; import org.apache.axis2.client.Options; import org.apache.axis2.context.MessageContext; import org.apache.axis2.description.HandlerDescription; import org.apache.axis2.description.Parameter; import org.apache.axis2.handlers.AbstractHandler; import org.apache.axis2.util.JavaUtils; import org.apache.axis2.util.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; public class AddressingOutHandler extends AbstractHandler implements AddressingConstants { private static final Log log = LogFactory.getLog(AddressingOutHandler.class); /** This variable should only be updated inside the {@link #init(HandlerDescription)} method. */ private boolean includeOptionalHeaders = false; /** Initialize the addressing out handler. */ public void init(HandlerDescription arg0) { super.init(arg0); //Determine whether to include optional addressing headers in the output message. //The default is not to include any headers that can be safely omitted. Parameter param = arg0.getParameter(INCLUDE_OPTIONAL_HEADERS); String value = Utils.getParameterValue(param); includeOptionalHeaders = JavaUtils.isTrueExplicitly(value); } public InvocationResponse invoke(MessageContext msgContext) throws AxisFault { // it should be able to disable addressing by some one. if (msgContext.isPropertyTrue(DISABLE_ADDRESSING_FOR_OUT_MESSAGES)) { if (log.isTraceEnabled()) { log.trace(msgContext.getLogIDString() + " Addressing is disabled. Not adding WS-Addressing headers."); } return InvocationResponse.CONTINUE; } // Determine the addressin namespace in effect. Object addressingVersionFromCurrentMsgCtxt = msgContext.getProperty(WS_ADDRESSING_VERSION); if (log.isTraceEnabled()) { log.trace("Addressing version string from messageContext=" + addressingVersionFromCurrentMsgCtxt); } boolean isSubmissionNamespace = Submission.WSA_NAMESPACE.equals(addressingVersionFromCurrentMsgCtxt); // Determine whether to include optional addressing headers in the output. boolean includeOptionalHeaders = this.includeOptionalHeaders || msgContext.isPropertyTrue(INCLUDE_OPTIONAL_HEADERS); // Determine if a MustUnderstand attribute will be added to all headers in the // addressing namespace. boolean addMustUnderstandAttribute = msgContext.isPropertyTrue(ADD_MUST_UNDERSTAND_TO_ADDRESSING_HEADERS); // what if there are addressing headers already in the message. Do you replace that or not? // Lets have a parameter to control that. The default behavior is you won't replace addressing // headers if there are any (this was the case so far). boolean replaceHeaders = msgContext.isPropertyTrue(REPLACE_ADDRESSING_HEADERS); WSAHeaderWriter writer = new WSAHeaderWriter(msgContext, isSubmissionNamespace, addMustUnderstandAttribute, replaceHeaders, includeOptionalHeaders); writer.writeHeaders(); return InvocationResponse.CONTINUE; } private class WSAHeaderWriter { private MessageContext messageContext; private SOAPEnvelope envelope; private SOAPHeader header; private SOAPFactory factory; private Options messageContextOptions; private OMNamespace addressingNamespaceObject; private String addressingNamespace; private boolean isFinalAddressingNamespace; private boolean addMustUnderstandAttribute; private boolean replaceHeaders; // determines whether we replace the existing headers or not, if they present private boolean includeOptionalHeaders; public WSAHeaderWriter(MessageContext mc, boolean isSubmissionNamespace, boolean addMU, boolean replace, boolean includeOptional) { if (log.isDebugEnabled()) { log.debug("WSAHeaderWriter: isFinal=" + isSubmissionNamespace + " addMU=" + addMU + " replace=" + replace + " includeOptional=" + includeOptional); } messageContext = mc; envelope = mc.getEnvelope(); factory = (SOAPFactory)envelope.getOMFactory(); header = envelope.getHeader(); // if there is no soap header in the envelope being processed, add one. if (header == null) { header = factory.createSOAPHeader(envelope); } messageContextOptions = messageContext.getOptions(); addressingNamespace = (isSubmissionNamespace ? Submission.WSA_NAMESPACE : Final.WSA_NAMESPACE); addressingNamespaceObject = factory.createOMNamespace(addressingNamespace, WSA_DEFAULT_PREFIX); isFinalAddressingNamespace = !isSubmissionNamespace; addMustUnderstandAttribute = addMU; replaceHeaders = replace; includeOptionalHeaders = includeOptional; } public void writeHeaders() throws AxisFault { // by this time, we definitely have some addressing information to be sent. This is because, // we have tested at the start of this whether messageInformationHeaders are null or not. // So rather than declaring addressing namespace in each and every addressing header, lets // define that in the Header itself. envelope.declareNamespace(addressingNamespaceObject); // processing WSA To processToEPR(); // processing WSA replyTo processReplyTo(); // processing WSA From processFromEPR(); // processing WSA FaultTo processFaultToEPR(); // processing WSA MessageID processMessageID(); // processing WSA Action processWSAAction(); // processing WSA RelatesTo processRelatesTo(); // process fault headers, if present processFaultsInfoIfPresent(); // process mustUnderstand attribute, if required. processMustUnderstandProperty(); } private void processMessageID() { String messageID = messageContextOptions.getMessageId(); if (messageID != null && !isAddressingHeaderAlreadyAvailable(WSA_MESSAGE_ID, false)) {//optional OMElement oe = processStringInfo(messageID, WSA_MESSAGE_ID); ArrayList attributes = (ArrayList)messageContext.getProperty( AddressingConstants.MESSAGEID_ATTRIBUTES); if (attributes != null && !attributes.isEmpty()) { Iterator attrIterator = attributes.iterator(); while (attrIterator.hasNext()) { AttributeHelper.importOMAttribute((OMAttribute)attrIterator.next(), oe); } } } } private void processWSAAction() throws AxisFault { String action = messageContextOptions.getAction(); if (log.isTraceEnabled()) { log.trace(messageContext.getLogIDString() + " processWSAAction: action from messageContext: " + action); } if (action == null || "".equals(action)) { if (messageContext.getAxisOperation() != null) { action = messageContext.getAxisOperation().getOutputAction(); if (log.isTraceEnabled()) { log.trace(messageContext.getLogIDString() + " processWSAAction: action from AxisOperation: " + action); } } } // Use the correct fault action for the selected namespace if (Final.WSA_FAULT_ACTION.equals(action) || Submission.WSA_FAULT_ACTION.equals(action)) { action = isFinalAddressingNamespace ? Final.WSA_FAULT_ACTION : Submission.WSA_FAULT_ACTION; messageContextOptions.setAction(action); } else if (!isFinalAddressingNamespace && Final.WSA_SOAP_FAULT_ACTION.equals(action)) { action = Submission.WSA_FAULT_ACTION; messageContextOptions.setAction(action); } // If we need to add a wsa:Action header if (!isAddressingHeaderAlreadyAvailable(WSA_ACTION, false)) { if (log.isTraceEnabled()) { log.trace(messageContext.getLogIDString() + " processWSAAction: No existing wsa:Action header found"); } // If we don't have an action to add, if (action == null || "".equals(action)) { if (log.isTraceEnabled()) { log.trace(messageContext.getLogIDString() + " processWSAAction: No action to add to header"); } // Fault unless validation has been explictily turned off if (!messageContext.isPropertyTrue( AddressingConstants.DISABLE_OUTBOUND_ADDRESSING_VALIDATION)) { throw new AxisFault(AddressingMessages.getMessage("outboundNoAction")); } } else { if (log.isTraceEnabled()) { log.trace(messageContext.getLogIDString() + " processWSAAction: Adding action to header: " + action); } // Otherwise just add the header OMElement oe = processStringInfo(action, WSA_ACTION); ArrayList attributes = (ArrayList)messageContext.getProperty( AddressingConstants.ACTION_ATTRIBUTES); if (attributes != null && !attributes.isEmpty()) { Iterator attrIterator = attributes.iterator(); while (attrIterator.hasNext()) { AttributeHelper .importOMAttribute((OMAttribute)attrIterator.next(), oe); } } } } } private void processFaultsInfoIfPresent() { OMElement detailElement = AddressingFaultsHelper .getDetailElementForAddressingFault(messageContext, addressingNamespaceObject); if (detailElement != null) { //The difference between SOAP 1.1 and SOAP 1.2 fault messages is explained in the WS-Addressing Specs. if (isFinalAddressingNamespace && messageContext.isSOAP11()) { // Add detail as a wsa:FaultDetail header if (!isAddressingHeaderAlreadyAvailable(Final.FAULT_HEADER_DETAIL, false)) { SOAPHeaderBlock faultDetail = header.addHeaderBlock( Final.FAULT_HEADER_DETAIL, addressingNamespaceObject); faultDetail.addChild(ElementHelper.importOMElement(detailElement, factory)); } } else if (!messageContext.isSOAP11()) { // Add detail to the Fault in the SOAP Body SOAPFault fault = envelope.getBody().getFault(); if (fault != null && fault.getDetail() != null) { fault.getDetail().addDetailEntry( ElementHelper.importOMElement(detailElement, factory)); } } } } private void processRelatesTo() { if (!isAddressingHeaderAlreadyAvailable(WSA_RELATES_TO, true)) { RelatesTo[] relatesTo = messageContextOptions.getRelationships(); if (relatesTo != null) { for (int i = 0, length = relatesTo.length; i < length; i++) { OMElement relatesToHeader = processStringInfo(relatesTo[i].getValue(), WSA_RELATES_TO); String relationshipType = relatesTo[i].getRelationshipType(); if (relatesToHeader != null) { if (relatesTo[i].getExtensibilityAttributes() != null) { Iterator attributes = relatesTo[i].getExtensibilityAttributes().iterator(); while (attributes.hasNext()) { OMAttribute oma = (OMAttribute)attributes.next(); AttributeHelper.importOMAttribute(oma, relatesToHeader); } } if (Final.WSA_DEFAULT_RELATIONSHIP_TYPE.equals(relationshipType) || Submission.WSA_DEFAULT_RELATIONSHIP_TYPE .equals(relationshipType)) { if (includeOptionalHeaders) { relationshipType = isFinalAddressingNamespace ? Final.WSA_DEFAULT_RELATIONSHIP_TYPE : Submission.WSA_DEFAULT_RELATIONSHIP_TYPE; relatesTo[i].setRelationshipType(relationshipType); } else { continue; //Omit the relationship type } } relatesToHeader.addAttribute(WSA_RELATES_TO_RELATIONSHIP_TYPE, relationshipType, null); } } } } } private void processFaultToEPR() throws AxisFault { EndpointReference epr = messageContextOptions.getFaultTo(); String headerName = AddressingConstants.WSA_FAULT_TO; //Omit the header if the epr is null. if (epr != null && !isAddressingHeaderAlreadyAvailable(headerName, false)) { addToSOAPHeader(epr, headerName); } } private void processFromEPR() throws AxisFault { EndpointReference epr = messageContextOptions.getFrom(); String headerName = AddressingConstants.WSA_FROM; //Omit the header if the epr is null. if (epr != null && !isAddressingHeaderAlreadyAvailable(headerName, false)) { addToSOAPHeader(epr, headerName); } } private void processReplyTo() throws AxisFault { EndpointReference epr = messageContextOptions.getReplyTo(); String headerName = AddressingConstants.WSA_REPLY_TO; //Don't check epr for null here as addToSOAPHeader() will provide an appropriate default. //This default is especially useful for client side outbound processing. if (!isAddressingHeaderAlreadyAvailable(headerName, false)) { addToSOAPHeader(epr, headerName); } } private void processToEPR() { EndpointReference epr = messageContextOptions.getTo(); if (epr != null && !isAddressingHeaderAlreadyAvailable(WSA_TO, false)) { Map referenceParameters = epr.getAllReferenceParameters(); String address = epr.getAddress(); if (!"".equals(address) && address != null) { if (!includeOptionalHeaders && isFinalAddressingNamespace && (Final.WSA_ANONYMOUS_URL.equals(address) || //Don't use epr.hasAnonymousAddress() here as it may Submission.WSA_ANONYMOUS_URL.equals(address))) { //recognize none WS-Addressing anonymous values. return; //Omit the header. } SOAPHeaderBlock toHeaderBlock = header.addHeaderBlock(WSA_TO, addressingNamespaceObject); toHeaderBlock.setText(address); if (epr.getAddressAttributes() != null) { Iterator addressAttributes = epr.getAddressAttributes().iterator(); while (addressAttributes.hasNext()) { OMAttribute attr = (OMAttribute)addressAttributes.next(); AttributeHelper.importOMAttribute(attr, toHeaderBlock); } } } processToEPRReferenceInformation(referenceParameters, header); } } private OMElement processStringInfo(String value, String headerName) { if (log.isTraceEnabled()) { log.trace("processStringInfo: value=" + value + " headerName=" + headerName); } if (!"".equals(value) && value != null) { SOAPHeaderBlock soapHeaderBlock = header.addHeaderBlock(headerName, addressingNamespaceObject); soapHeaderBlock.addChild(factory.createOMText(value)); return soapHeaderBlock; } return null; } private void addToSOAPHeader(EndpointReference epr, String headerName) throws AxisFault { String prefix = addressingNamespaceObject.getPrefix(); String anonymous = isFinalAddressingNamespace ? Final.WSA_ANONYMOUS_URL : Submission.WSA_ANONYMOUS_URL; if (log.isTraceEnabled()) { log.trace("addToSOAPHeader: epr=" + epr + " headerName=" + headerName); } if (epr == null) { if (!includeOptionalHeaders && isFinalAddressingNamespace && AddressingConstants.WSA_REPLY_TO.equals(headerName)) { return; //Omit the header. } else { epr = new EndpointReference(anonymous); } } else if (!isFinalAddressingNamespace && epr.hasNoneAddress()) { return; //Omit the header. } else if (Final.WSA_ANONYMOUS_URL.equals(epr.getAddress()) || //Don't use epr.hasAnonymousAddress() here as it may Submission.WSA_ANONYMOUS_URL.equals(epr.getAddress())) { //recognize none WS-Addressing anonymous values. if (!includeOptionalHeaders && isFinalAddressingNamespace && AddressingConstants.WSA_REPLY_TO.equals(headerName)) { return; //Omit the header. } else { epr.setAddress(anonymous); } } OMElement soapHeaderBlock = EndpointReferenceHelper.toOM(factory, epr, new QName(addressingNamespace, headerName, prefix), addressingNamespace); header.addChild(soapHeaderBlock); } /** * This will add reference parameters and/or reference properties in to the message * * @param referenceInformation a Map from QName -> OMElement * @param parent is the element to which the referenceparameters should be * attached */ private void processToEPRReferenceInformation(Map referenceInformation, OMElement parent) { if (referenceInformation != null && parent != null) { Iterator iterator = referenceInformation.values().iterator(); while (iterator.hasNext()) { OMElement omElement = (OMElement)iterator.next(); parent.addChild( ElementHelper.importOMElement(omElement, parent.getOMFactory())); if (isFinalAddressingNamespace) { omElement.addAttribute(Final.WSA_IS_REFERENCE_PARAMETER_ATTRIBUTE, Final.WSA_TYPE_ATTRIBUTE_VALUE, addressingNamespaceObject); } } } } /** * This will check for the existence of message information headers already in the message. * If there are already headers, then replacing them or not depends on the replaceHeaders * property. * * @param name - Name of the message information header * @param multipleHeaders - determines whether to search for multiple headers, or not. * @return false - if one can add new headers (always the case if multipleHeaders is true), * true - if new headers can't be added. */ private boolean isAddressingHeaderAlreadyAvailable(String name, boolean multipleHeaders) { QName qname = new QName(addressingNamespaceObject.getNamespaceURI(), name, addressingNamespaceObject.getPrefix()); boolean status = false; if (multipleHeaders) { if (replaceHeaders) { Iterator iterator = header.getChildrenWithName(qname); while (iterator.hasNext()) { OMElement addressingHeader = (OMElement)iterator.next(); addressingHeader.detach(); } } } else { OMElement addressingHeader = header.getFirstChildWithName(qname); if (addressingHeader != null && replaceHeaders) { if (log.isTraceEnabled()) { log.trace("isAddressingHeaderAlreadyAvailable: Removing existing header:" + addressingHeader.getLocalName()); } addressingHeader.detach(); } else { status = addressingHeader != null; } } if (log.isTraceEnabled()) { log.trace("isAddressingHeaderAlreadyAvailable: name=" + name + " status=" + status); } return status; } /** * Sets a mustUnderstand attribute on all headers that are found with the appropriate * addressing namespace. */ private void processMustUnderstandProperty() { if (addMustUnderstandAttribute) { List headers = header.getHeaderBlocksWithNSURI(addressingNamespace); for (int i = 0, size = headers.size(); i < size; i++) { SOAPHeaderBlock soapHeaderBlock = (SOAPHeaderBlock)headers.get(i); soapHeaderBlock.setMustUnderstand(true); if (log.isTraceEnabled()) { log.trace( "processMustUnderstandProperty: Setting mustUnderstand=true on: " + soapHeaderBlock.getLocalName()); } } } } } } Other Axis 2 examples (source code examples)Here is a short list of links related to this Axis 2 AddressingOutHandler.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.