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.soap.bindings.soap.interceptors;
018
019 import java.net.URI;
020 import java.util.HashSet;
021 import java.util.Set;
022
023 import javax.xml.namespace.QName;
024
025 import org.apache.servicemix.soap.api.Interceptor;
026 import org.apache.servicemix.soap.api.InterceptorChain;
027 import org.apache.servicemix.soap.api.Message;
028 import org.apache.servicemix.soap.api.model.Operation;
029 import org.apache.servicemix.soap.bindings.soap.SoapConstants;
030 import org.apache.servicemix.soap.bindings.soap.SoapFault;
031 import org.apache.servicemix.soap.bindings.soap.SoapInterceptor;
032 import org.apache.servicemix.soap.bindings.soap.SoapVersion;
033 import org.apache.servicemix.soap.bindings.soap.model.wsdl1.Wsdl1SoapOperation;
034 import org.apache.servicemix.soap.bindings.soap.model.wsdl1.Wsdl1SoapPart;
035 import org.apache.servicemix.soap.core.AbstractInterceptor;
036 import org.w3c.dom.DocumentFragment;
037 import org.w3c.dom.Element;
038
039 public class MustUnderstandInterceptor extends AbstractInterceptor {
040
041 public MustUnderstandInterceptor() {
042 }
043
044 public void handleMessage(Message message) {
045 Set<URI> serviceRoles = new HashSet<URI>();
046 Set<QName> headerQNames = new HashSet<QName>();
047 Set<QName> understoodQNames = new HashSet<QName>();
048
049 buildMustUnderstandHeaders(headerQNames, message, serviceRoles);
050 initServiceSideInfo(understoodQNames, message, serviceRoles);
051 headerQNames.removeAll(understoodQNames);
052 if (!headerQNames.isEmpty()) {
053 StringBuffer sb = new StringBuffer(300);
054 int pos = 0;
055 for (QName qname : headerQNames) {
056 pos = pos + qname.toString().length() + 2;
057 if (sb.length() > 0) {
058 sb.append(", ");
059 }
060 sb.append(qname.toString());
061 }
062 throw new SoapFault(SoapConstants.SOAP_12_CODE_MUSTUNDERSTAND, sb.toString());
063 }
064 }
065
066 private void initServiceSideInfo(Set<QName> understoodQNames,
067 Message message,
068 Set<URI> serviceRoles) {
069 // Retrieve soap headers bound to message parts
070 Operation operation = message.get(Operation.class);
071 if (operation instanceof Wsdl1SoapOperation) {
072 Wsdl1SoapOperation soapOper = (Wsdl1SoapOperation) operation;
073 for (Wsdl1SoapPart part : soapOper.getInput().getParts()) {
074 if (part.isHeader()) {
075 understoodQNames.add(part.getElement());
076 }
077 }
078 }
079 InterceptorChain chain = message.get(InterceptorChain.class);
080 for (Interceptor interceptorInstance : chain.getInterceptors()) {
081 if (interceptorInstance instanceof SoapInterceptor) {
082 SoapInterceptor si = (SoapInterceptor) interceptorInstance;
083 serviceRoles.addAll(si.getRoles());
084 understoodQNames.addAll(si.getUnderstoodHeaders());
085 }
086 }
087 }
088
089 private void buildMustUnderstandHeaders(Set<QName> mustUnderstandHeaders,
090 Message message,
091 Set<URI> serviceRoles) {
092 SoapVersion soapVersion = message.get(SoapVersion.class);
093 for(DocumentFragment df : message.getSoapHeaders().values()) {
094 for (int i = 0; i < df.getChildNodes().getLength(); i++) {
095 if (df.getChildNodes().item(i) instanceof Element) {
096 Element header = (Element) df.getChildNodes().item(i);
097 String mustUnderstand = header.getAttributeNS(soapVersion.getNamespace(),
098 soapVersion.getAttrNameMustUnderstand());
099 if (Boolean.valueOf(mustUnderstand) || "1".equals(mustUnderstand.trim())) {
100 String role = header.getAttributeNS(soapVersion.getNamespace(),
101 soapVersion.getAttrNameRole());
102 QName headerName = new QName(header.getNamespaceURI(), header.getLocalName());
103 role = role.trim();
104 if (role != null && role.length() > 0) {
105 role = role.trim();
106 if (role.equals(soapVersion.getNextRole()) || role.equals(soapVersion.getUltimateReceiverRole())) {
107 mustUnderstandHeaders.add(headerName);
108 } else {
109 for (URI roleFromBinding : serviceRoles) {
110 if (role.equals(roleFromBinding)) {
111 mustUnderstandHeaders.add(headerName);
112 }
113 }
114 }
115 } else {
116 // if role omitted, the soap node is ultimate receiver,
117 // needs to understand
118 mustUnderstandHeaders.add(headerName);
119 }
120 }
121 }
122 }
123 }
124 }
125
126 }