/** * Copyright (c) 2009-2012 EBM WebSourcing, 2012-2024 Linagora * * This program/library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or (at your * option) any later version. * * This program/library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program/library; If not, see http://www.gnu.org/licenses/ * for the GNU Lesser General Public License version 2.1. */ package org.ow2.petals.binding.soap.util; import java.util.Iterator; import java.util.Map; import javax.jbi.messaging.MessagingException; import org.apache.axiom.om.OMContainer; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.axiom.soap.SOAPBody; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFactory; import org.apache.axiom.soap.SOAPFault; import org.apache.axiom.soap.SOAPHeader; /** * @author Christophe Hamerling - EBM WebSourcing */ public final class AxiomSOAPEnvelopeFlattener { /** * Get back a soap envelope without the multiref elements. * * @param envelope the SOAP envelope with multiref elements * @throws MessagingException if it is not possible to determine the SOAP version * @return the SOAP envelope without multiref elements */ public static final SOAPEnvelope flatten(SOAPEnvelope envelope) throws MessagingException { // get all the multiref elements from the input soap envelope final Map multiref = AxiomUtils.getHrefElements(envelope); if (multiref.isEmpty()) { return envelope; } final SOAPFactory factory = AxiomUtils.getSOAPFactory(envelope); // Create envelope with the same prefix final SOAPEnvelope targetEnv = factory.createSOAPEnvelope(envelope.getNamespace()); // Copy the attributes and namespaces from the source // envelope to the target envelope. AxiomUtils.copyTagData(envelope, targetEnv); @SuppressWarnings("unchecked") final Iterator i = envelope.getChildren(); while (i.hasNext()) { final OMNode node = i.next(); if (node instanceof SOAPHeader) { // Copy the SOAPHeader tree final SOAPHeader targetHeader = factory.createSOAPHeader(targetEnv); @SuppressWarnings("unchecked") final Iterator j = ((SOAPHeader) node).getChildren(); while (j.hasNext()) { final OMNode child = j.next(); flatten(factory, targetHeader, child, multiref); } } else if (node instanceof SOAPBody) { // Copy the SOAPBody tree final SOAPBody targetBody = factory.createSOAPBody(targetEnv); @SuppressWarnings("unchecked") final Iterator j = ((SOAPBody) node).getChildren(); while (j.hasNext()) { final OMNode child = j.next(); flatten(factory, targetBody, child, multiref); } } else { // Comments, text, etc. targetEnv.addChild(AxiomUtils.copy(node)); } } return targetEnv; } private static final void flatten(SOAPFactory factory, OMContainer targetParent, OMNode sourceNode, Map multirefs) { if (sourceNode instanceof SOAPFault || !(sourceNode instanceof OMElement)) { targetParent.addChild(AxiomUtils.copy(sourceNode)); } else { // 1. avoid to copy the multiref elements OMElement element = (OMElement) sourceNode; if (!AxiomUtils.isMultirefElement(element)) { if (AxiomUtils.isHrefRedirect(element)) { flattenOMElement(factory, targetParent, element, multirefs); } else { // go deeper... OMElement newElement = factory.createOMElement(element .getQName(), targetParent); AxiomUtils.copyTagData(element, newElement); Iterator j = element.getChildren(); while (j.hasNext()) { OMNode child = (OMNode) j.next(); flatten(factory, newElement, child, multirefs); } } } else { } } } public static final void flattenOMElement(SOAPFactory factory, OMContainer targetParent, OMElement sourceElement, Map multiref) { // Clone and attach the OMElement. // REVIEW This clone will expand the underlying tree. We may want // consider traversing // a few levels deeper to see if there are any additional // OMSourcedElements. // get the href String id = AxiomUtils.getHrefId(sourceElement); OMElement href = multiref.get(id); OMElement newElement = factory .createOMElement(sourceElement.getQName()); AxiomUtils.copyTagData(sourceElement, newElement); // let's include the multiref part... AxiomUtils.copyTagData(href, newElement); // copy all the multiref children @SuppressWarnings("unchecked") final Iterator i = href.getChildren(); while (i.hasNext()) { final OMNode node = i.next(); // lets flatten inner elements flatten(factory, newElement, node, multiref); } targetParent.addChild(newElement); } }