001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.cxfbc.interceptors;
018    
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    
023    import javax.xml.transform.Source;
024    import javax.xml.transform.dom.DOMSource;
025    import org.w3c.dom.Element;
026    import org.w3c.dom.NodeList;
027    import org.apache.cxf.binding.soap.SoapMessage;
028    import org.apache.cxf.binding.soap.model.SoapBindingInfo;
029    import org.apache.cxf.binding.soap.model.SoapHeaderInfo;
030    import org.apache.cxf.endpoint.Endpoint;
031    import org.apache.cxf.headers.Header;
032    import org.apache.cxf.interceptor.Fault;
033    import org.apache.cxf.message.Message;
034    import org.apache.cxf.phase.AbstractPhaseInterceptor;
035    import org.apache.cxf.phase.Phase;
036    import org.apache.cxf.service.model.BindingMessageInfo;
037    import org.apache.cxf.service.model.BindingOperationInfo;
038    import org.apache.servicemix.jbi.jaxp.SourceTransformer;
039    import org.apache.servicemix.soap.interceptors.jbi.JbiConstants;
040    import org.apache.servicemix.soap.util.DomUtil;
041    import org.apache.servicemix.soap.util.QNameUtil;
042    
043    
044    public class ExtractHeaderPartIntercepor extends AbstractPhaseInterceptor<Message> {
045    
046        public ExtractHeaderPartIntercepor() {
047            super(Phase.PRE_STREAM);
048        }
049    
050        public void handleMessage(Message message) {
051            
052            extractHeaderFromMessagePart(message);
053        }
054    
055        private void extractHeaderFromMessagePart(Message message) {
056            Source source = message.getContent(Source.class);
057            if (source == null) {
058                return;
059            }
060    
061            Element element;
062            try {
063                element = new SourceTransformer().toDOMElement(source);
064            } catch (Exception e) {
065                throw new Fault(e);
066            }
067    
068            if (!JbiConstants.WSDL11_WRAPPER_NAMESPACE.equals(element
069                    .getNamespaceURI())
070                    || !JbiConstants.WSDL11_WRAPPER_MESSAGE_LOCALNAME
071                            .equals(element.getLocalName())) {
072                message.setContent(Source.class, new DOMSource(element));
073                return;
074            }
075    
076            BindingOperationInfo bop = message.getExchange().get(
077                    BindingOperationInfo.class);
078            if (bop == null) {
079                throw new Fault(
080                        new Exception("Operation not bound on this message"));
081            }
082            BindingMessageInfo msg = isRequestor(message) ? bop.getInput() : bop
083                    .getOutput();
084    
085            SoapBindingInfo binding = (SoapBindingInfo) message.getExchange().get(
086                    Endpoint.class).getEndpointInfo().getBinding();
087            String style = binding.getStyle(bop.getOperationInfo());
088            if (style == null) {
089                style = binding.getStyle();
090            }
091    
092            Element partWrapper = DomUtil.getFirstChildElement(element);
093            while (partWrapper != null) {
094                extractHeaderParts((SoapMessage) message, element, partWrapper, msg);
095                partWrapper = DomUtil.getNextSiblingElement(partWrapper);
096            }
097            message.setContent(Source.class, new DOMSource(element));
098        }
099    
100        private void extractHeaderParts(SoapMessage message,
101                Element element, Element partWrapper, BindingMessageInfo msg) {
102            List<NodeList> partsContent = new ArrayList<NodeList>();
103            if (partWrapper != null) {
104                if (!JbiConstants.WSDL11_WRAPPER_NAMESPACE.equals(element
105                        .getNamespaceURI())
106                        || !JbiConstants.WSDL11_WRAPPER_PART_LOCALNAME
107                                .equals(partWrapper.getLocalName())) {
108                    throw new Fault(new Exception(
109                            "Unexpected part wrapper element '"
110                                    + QNameUtil.toString(element) + "' expected '{"
111                                    + JbiConstants.WSDL11_WRAPPER_NAMESPACE
112                                    + "}part'"));
113                }
114                NodeList nodes = partWrapper.getChildNodes();
115                partsContent.add(nodes);
116            }
117    
118            List<Header> headerList = message.getHeaders();
119            List<SoapHeaderInfo> headers = msg.getExtensors(SoapHeaderInfo.class);
120            for (SoapHeaderInfo header : headers) {
121                if (partsContent.size() == 0) {
122                    break;
123                }
124    
125                NodeList nl = partsContent.get(0);
126                if (header.getPart().getConcreteName().getNamespaceURI().equals(
127                        nl.item(0).getNamespaceURI())
128                        && header.getPart().getConcreteName().getLocalPart()
129                                .equals(nl.item(0).getLocalName())) {
130                    headerList.add(new Header(header.getPart().getConcreteName(),
131                            nl.item(0)));
132                    partsContent.remove(0);
133                }
134    
135            }
136    
137        }
138    
139    }