1 /* 2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.messaging.saaj.soap.impl; 27 28 import java.util.*; 29 import java.util.logging.Level; 30 31 import javax.xml.namespace.QName; 32 import javax.xml.soap.*; 33 34 import com.sun.xml.internal.messaging.saaj.util.SAAJUtil; 35 import org.w3c.dom.Element; 36 37 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; 38 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocument; 39 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl; 40 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl; 41 42 public abstract class HeaderImpl extends ElementImpl implements SOAPHeader { 43 protected static final boolean MUST_UNDERSTAND_ONLY = false; 44 45 protected HeaderImpl(SOAPDocumentImpl ownerDoc, NameImpl name) { 46 super(ownerDoc, name); 47 } 48 49 public HeaderImpl(SOAPDocumentImpl ownerDoc, Element domElement) { 50 super(ownerDoc, domElement); 51 } 52 53 protected abstract SOAPHeaderElement createHeaderElement(Name name) 54 throws SOAPException; 55 protected abstract SOAPHeaderElement createHeaderElement(QName name) 56 throws SOAPException; 57 protected abstract NameImpl getNotUnderstoodName(); 58 protected abstract NameImpl getUpgradeName(); 59 protected abstract NameImpl getSupportedEnvelopeName(); 60 61 public SOAPHeaderElement addHeaderElement(Name name) throws SOAPException { 62 SOAPElement newHeaderElement = 63 ElementFactory.createNamedElement( 64 ((SOAPDocument) getOwnerDocument()).getDocument(), 65 name.getLocalName(), 66 name.getPrefix(), 67 name.getURI()); 68 if (newHeaderElement == null 69 || !(newHeaderElement instanceof SOAPHeaderElement)) { 70 newHeaderElement = createHeaderElement(name); 71 } 72 73 // header elements must be namespace qualified 74 // check that URI is not empty, ensuring that the element is NS qualified. 75 String uri = newHeaderElement.getElementQName().getNamespaceURI(); 76 if ((uri == null) || ("").equals(uri)) { 77 log.severe("SAAJ0131.impl.header.elems.ns.qualified"); 78 throw new SOAPExceptionImpl("HeaderElements must be namespace qualified"); 79 } 80 addNode(newHeaderElement); 81 return (SOAPHeaderElement) newHeaderElement; 82 } 83 84 public SOAPHeaderElement addHeaderElement(QName name) throws SOAPException { 85 SOAPElement newHeaderElement = 86 ElementFactory.createNamedElement( 87 ((SOAPDocument) getOwnerDocument()).getDocument(), 88 name.getLocalPart(), 89 name.getPrefix(), 90 name.getNamespaceURI()); 91 if (newHeaderElement == null 92 || !(newHeaderElement instanceof SOAPHeaderElement)) { 93 newHeaderElement = createHeaderElement(name); 94 } 95 96 // header elements must be namespace qualified 97 // check that URI is not empty, ensuring that the element is NS qualified. 98 String uri = newHeaderElement.getElementQName().getNamespaceURI(); 99 if ((uri == null) || ("").equals(uri)) { 100 log.severe("SAAJ0131.impl.header.elems.ns.qualified"); 101 throw new SOAPExceptionImpl("HeaderElements must be namespace qualified"); 102 } 103 addNode(newHeaderElement); 104 return (SOAPHeaderElement) newHeaderElement; 105 } 106 107 protected SOAPElement addElement(Name name) throws SOAPException { 108 return addHeaderElement(name); 109 } 110 111 protected SOAPElement addElement(QName name) throws SOAPException { 112 return addHeaderElement(name); 113 } 114 115 public Iterator examineHeaderElements(String actor) { 116 return getHeaderElementsForActor(actor, false, false); 117 } 118 119 public Iterator extractHeaderElements(String actor) { 120 return getHeaderElementsForActor(actor, true, false); 121 } 122 123 protected Iterator<SOAPHeaderElement> getHeaderElementsForActor( 124 String actor, 125 boolean detach, 126 boolean mustUnderstand) { 127 if (actor == null || actor.equals("")) { 128 log.severe("SAAJ0132.impl.invalid.value.for.actor.or.role"); 129 throw new IllegalArgumentException("Invalid value for actor or role"); 130 } 131 return getHeaderElements(actor, detach, mustUnderstand); 132 } 133 134 protected Iterator<SOAPHeaderElement> getHeaderElements( 135 String actor, 136 boolean detach, 137 boolean mustUnderstand) { 138 List<SOAPHeaderElement> elementList = new ArrayList<SOAPHeaderElement>(); 139 140 Iterator<org.w3c.dom.Node> eachChild = getChildElements(); 141 142 org.w3c.dom.Node currentChild = iterate(eachChild); 143 while (currentChild != null) { 144 if (!(currentChild instanceof SOAPHeaderElement)) { 145 currentChild = iterate(eachChild); 146 } else { 147 HeaderElementImpl currentElement = 148 (HeaderElementImpl) currentChild; 149 currentChild = iterate(eachChild); 150 151 boolean isMustUnderstandMatching = 152 (!mustUnderstand || currentElement.getMustUnderstand()); 153 boolean doAdd = false; 154 if (actor == null && isMustUnderstandMatching) { 155 doAdd = true; 156 } else { 157 String currentActor = currentElement.getActorOrRole(); 158 if (currentActor == null) { 159 currentActor = ""; 160 } 161 162 if (currentActor.equalsIgnoreCase(actor) 163 && isMustUnderstandMatching) { 164 doAdd = true; 165 } 166 } 167 168 if (doAdd) { 169 elementList.add(currentElement); 170 if (detach) { 171 currentElement.detachNode(); 172 } 173 } 174 } 175 } 176 177 return elementList.listIterator(); 178 } 179 180 private <T> T iterate(Iterator<T> each) { 181 return each.hasNext() ? each.next() : null; 182 } 183 184 public void setParentElement(SOAPElement element) throws SOAPException { 185 if (!(element instanceof SOAPEnvelope)) { 186 log.severe("SAAJ0133.impl.header.parent.mustbe.envelope"); 187 throw new SOAPException("Parent of SOAPHeader has to be a SOAPEnvelope"); 188 } 189 super.setParentElement(element); 190 } 191 192 // overriding ElementImpl's method to ensure that HeaderElements are 193 // namespace qualified. Holds for both SOAP versions. 194 // TODO - This check needs to be made for other addChildElement() methods 195 // as well. 196 public SOAPElement addChildElement(String localName) throws SOAPException { 197 198 SOAPElement element = super.addChildElement(localName); 199 // check that URI is not empty, ensuring that the element is NS qualified. 200 String uri = element.getElementName().getURI(); 201 if ((uri == null) || ("").equals(uri)) { 202 log.severe("SAAJ0134.impl.header.elems.ns.qualified"); 203 throw new SOAPExceptionImpl("HeaderElements must be namespace qualified"); 204 } 205 return element; 206 } 207 208 public Iterator examineAllHeaderElements() { 209 return getHeaderElements(null, false, MUST_UNDERSTAND_ONLY); 210 } 211 212 public Iterator examineMustUnderstandHeaderElements(String actor) { 213 return getHeaderElements(actor, false, true); 214 215 } 216 217 public Iterator extractAllHeaderElements() { 218 return getHeaderElements(null, true, false); 219 } 220 221 public SOAPHeaderElement addUpgradeHeaderElement(Iterator supportedSoapUris) 222 throws SOAPException { 223 if (supportedSoapUris == null) { 224 log.severe("SAAJ0411.ver1_2.no.null.supportedURIs"); 225 throw new SOAPException("Argument cannot be null; iterator of supportedURIs cannot be null"); 226 } 227 if (!supportedSoapUris.hasNext()) { 228 log.severe("SAAJ0412.ver1_2.no.empty.list.of.supportedURIs"); 229 throw new SOAPException("List of supported URIs cannot be empty"); 230 } 231 Name upgradeName = getUpgradeName(); 232 SOAPHeaderElement upgradeHeaderElement = 233 (SOAPHeaderElement) addChildElement(upgradeName); 234 Name supportedEnvelopeName = getSupportedEnvelopeName(); 235 int i = 0; 236 while (supportedSoapUris.hasNext()) { 237 SOAPElement subElement = 238 upgradeHeaderElement.addChildElement(supportedEnvelopeName); 239 String ns = "ns" + Integer.toString(i); 240 subElement.addAttribute( 241 NameImpl.createFromUnqualifiedName("qname"), 242 ns + ":Envelope"); 243 subElement.addNamespaceDeclaration( 244 ns, 245 (String) supportedSoapUris.next()); 246 i ++; 247 } 248 return upgradeHeaderElement; 249 } 250 251 public SOAPHeaderElement addUpgradeHeaderElement(String supportedSoapUri) 252 throws SOAPException { 253 return addUpgradeHeaderElement(new String[] {supportedSoapUri}); 254 } 255 256 public SOAPHeaderElement addUpgradeHeaderElement(String[] supportedSoapUris) 257 throws SOAPException { 258 259 if (supportedSoapUris == null) { 260 log.severe("SAAJ0411.ver1_2.no.null.supportedURIs"); 261 throw new SOAPException("Argument cannot be null; array of supportedURIs cannot be null"); 262 } 263 if (supportedSoapUris.length == 0) { 264 log.severe("SAAJ0412.ver1_2.no.empty.list.of.supportedURIs"); 265 throw new SOAPException("List of supported URIs cannot be empty"); 266 } 267 Name upgradeName = getUpgradeName(); 268 SOAPHeaderElement upgradeHeaderElement = 269 (SOAPHeaderElement) addChildElement(upgradeName); 270 Name supportedEnvelopeName = getSupportedEnvelopeName(); 271 for (int i = 0; i < supportedSoapUris.length; i ++) { 272 SOAPElement subElement = 273 upgradeHeaderElement.addChildElement(supportedEnvelopeName); 274 String ns = "ns" + Integer.toString(i); 275 subElement.addAttribute( 276 NameImpl.createFromUnqualifiedName("qname"), 277 ns + ":Envelope"); 278 subElement.addNamespaceDeclaration(ns, supportedSoapUris[i]); 279 } 280 return upgradeHeaderElement; 281 } 282 283 protected SOAPElement convertToSoapElement(Element element) { 284 final org.w3c.dom.Node soapNode = getSoapDocument().findIfPresent(element); 285 if (soapNode instanceof SOAPHeaderElement) { 286 return (SOAPElement) soapNode; 287 } else { 288 SOAPHeaderElement headerElement; 289 try { 290 headerElement = 291 createHeaderElement(NameImpl.copyElementName(element)); 292 } catch (SOAPException e) { 293 throw new ClassCastException("Could not convert Element to SOAPHeaderElement: " + e.getMessage()); 294 } 295 return replaceElementWithSOAPElement( 296 element, 297 (ElementImpl) headerElement); 298 } 299 } 300 301 public SOAPElement setElementQName(QName newName) throws SOAPException { 302 log.log(Level.SEVERE, 303 "SAAJ0146.impl.invalid.name.change.requested", 304 new Object[] {elementQName.getLocalPart(), 305 newName.getLocalPart()}); 306 throw new SOAPException("Cannot change name for " 307 + elementQName.getLocalPart() + " to " 308 + newName.getLocalPart()); 309 } 310 311 }