001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.binding.soap.interceptor;
019:
020: import java.net.URI;
021: import java.util.HashSet;
022: import java.util.ResourceBundle;
023: import java.util.Set;
024: import java.util.logging.Logger;
025:
026: import javax.xml.namespace.QName;
027:
028: import org.apache.cxf.binding.soap.HeaderUtil;
029: import org.apache.cxf.binding.soap.SoapFault;
030: import org.apache.cxf.binding.soap.SoapHeader;
031: import org.apache.cxf.binding.soap.SoapMessage;
032: import org.apache.cxf.binding.soap.SoapVersion;
033: import org.apache.cxf.common.i18n.Message;
034: import org.apache.cxf.common.logging.LogUtils;
035: import org.apache.cxf.headers.Header;
036: import org.apache.cxf.interceptor.Interceptor;
037: import org.apache.cxf.phase.Phase;
038:
039: public class MustUnderstandInterceptor extends AbstractSoapInterceptor {
040: private static final Logger LOG = LogUtils
041: .getL7dLogger(MustUnderstandInterceptor.class);
042:
043: private static final ResourceBundle BUNDLE = LOG
044: .getResourceBundle();
045:
046: public MustUnderstandInterceptor() {
047: super (Phase.PRE_PROTOCOL);
048: }
049:
050: public MustUnderstandInterceptor(String phase) {
051: super (phase);
052: }
053:
054: public void handleMessage(SoapMessage soapMessage) {
055: SoapVersion soapVersion = soapMessage.getVersion();
056: Set<Header> mustUnderstandHeaders = new HashSet<Header>();
057: Set<URI> serviceRoles = new HashSet<URI>();
058: Set<QName> notUnderstandQNames = new HashSet<QName>();
059: Set<QName> mustUnderstandQNames = new HashSet<QName>();
060:
061: buildMustUnderstandHeaders(mustUnderstandHeaders, soapMessage,
062: serviceRoles);
063: initServiceSideInfo(mustUnderstandQNames, soapMessage,
064: serviceRoles);
065:
066: if (!checkUnderstand(mustUnderstandHeaders,
067: mustUnderstandQNames, notUnderstandQNames)) {
068: StringBuffer sb = new StringBuffer(300);
069: int pos = 0;
070: for (QName qname : notUnderstandQNames) {
071: pos = pos + qname.toString().length() + 2;
072: sb.append(qname.toString() + ", ");
073: }
074: sb.delete(pos - 2, pos);
075: throw new SoapFault(new Message("MUST_UNDERSTAND", BUNDLE,
076: sb.toString()), soapVersion.getMustUnderstand());
077: }
078: }
079:
080: private void initServiceSideInfo(Set<QName> mustUnderstandQNames,
081: SoapMessage soapMessage, Set<URI> serviceRoles) {
082:
083: Set<QName> paramHeaders = HeaderUtil
084: .getHeaderQNameInOperationParam(soapMessage);
085:
086: if (paramHeaders != null) {
087: mustUnderstandQNames.addAll(paramHeaders);
088: }
089: for (Interceptor interceptorInstance : soapMessage
090: .getInterceptorChain()) {
091: if (interceptorInstance instanceof SoapInterceptor) {
092: SoapInterceptor si = (SoapInterceptor) interceptorInstance;
093: Set<URI> roles = si.getRoles();
094: if (roles != null) {
095: serviceRoles.addAll(roles);
096: }
097: Set<QName> understoodHeaders = si
098: .getUnderstoodHeaders();
099: if (understoodHeaders != null) {
100: mustUnderstandQNames.addAll(understoodHeaders);
101: }
102: }
103: }
104: }
105:
106: private void buildMustUnderstandHeaders(
107: Set<Header> mustUnderstandHeaders, SoapMessage soapMessage,
108: Set<URI> serviceRoles) {
109: for (Header header : soapMessage.getHeaders()) {
110: if (header instanceof SoapHeader
111: && ((SoapHeader) header).isMustUnderstand()) {
112: String role = ((SoapHeader) header).getActor();
113: if (role != null) {
114: role = role.trim();
115: if (role.equals(soapMessage.getVersion()
116: .getNextRole())
117: || role.equals(soapMessage.getVersion()
118: .getUltimateReceiverRole())) {
119: mustUnderstandHeaders.add(header);
120: } else {
121: for (URI roleFromBinding : serviceRoles) {
122: if (role.equals(roleFromBinding.toString())) {
123: mustUnderstandHeaders.add(header);
124: }
125: }
126: }
127: } else {
128: // if role omitted, the soap node is ultimate receiver,
129: // needs to understand
130: mustUnderstandHeaders.add(header);
131: }
132: }
133: }
134: }
135:
136: private boolean checkUnderstand(Set<Header> mustUnderstandHeaders,
137: Set<QName> mustUnderstandQNames,
138: Set<QName> notUnderstandQNames) {
139:
140: for (Header header : mustUnderstandHeaders) {
141: QName qname = header.getName();
142: if (!mustUnderstandQNames.contains(qname)) {
143: notUnderstandQNames.add(qname);
144: }
145: }
146: if (notUnderstandQNames.size() > 0) {
147: return false;
148: }
149: return true;
150: }
151: }
|