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 private boolean isRequestor(org.apache.cxf.message.Message message) {
140 return Boolean.TRUE.equals(message
141 .containsKey(org.apache.cxf.message.Message.REQUESTOR_ROLE));
142 }
143
144 }