1 /* 2 * Copyright (c) 1997, 2014, 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 org.w3c.dom.Element; 35 import org.w3c.dom.Node; 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 protected abstract SOAPHeaderElement createHeaderElement(Name name) 50 throws SOAPException; 51 protected abstract SOAPHeaderElement createHeaderElement(QName name) 52 throws SOAPException; 53 protected abstract NameImpl getNotUnderstoodName(); 54 protected abstract NameImpl getUpgradeName(); 55 protected abstract NameImpl getSupportedEnvelopeName(); 56 57 public SOAPHeaderElement addHeaderElement(Name name) throws SOAPException { 58 SOAPElement newHeaderElement = 59 ElementFactory.createNamedElement( 60 ((SOAPDocument) getOwnerDocument()).getDocument(), 61 name.getLocalName(), 62 name.getPrefix(), 63 name.getURI()); 64 if (newHeaderElement == null 65 || !(newHeaderElement instanceof SOAPHeaderElement)) { 66 newHeaderElement = createHeaderElement(name); 67 } 68 69 // header elements must be namespace qualified 70 // check that URI is not empty, ensuring that the element is NS qualified. 71 String uri = newHeaderElement.getElementQName().getNamespaceURI(); 72 if ((uri == null) || ("").equals(uri)) { 73 log.severe("SAAJ0131.impl.header.elems.ns.qualified"); 74 throw new SOAPExceptionImpl("HeaderElements must be namespace qualified"); 75 } 76 addNode(newHeaderElement); 77 return (SOAPHeaderElement) newHeaderElement; 78 } 79 80 public SOAPHeaderElement addHeaderElement(QName name) throws SOAPException { 81 SOAPElement newHeaderElement = 82 ElementFactory.createNamedElement( 83 ((SOAPDocument) getOwnerDocument()).getDocument(), 84 name.getLocalPart(), 85 name.getPrefix(), 86 name.getNamespaceURI()); 87 if (newHeaderElement == null 88 || !(newHeaderElement instanceof SOAPHeaderElement)) { 89 newHeaderElement = createHeaderElement(name); 90 } 91 92 // header elements must be namespace qualified 93 // check that URI is not empty, ensuring that the element is NS qualified. 94 String uri = newHeaderElement.getElementQName().getNamespaceURI(); 95 if ((uri == null) || ("").equals(uri)) { 96 log.severe("SAAJ0131.impl.header.elems.ns.qualified"); 97 throw new SOAPExceptionImpl("HeaderElements must be namespace qualified"); 98 } 99 addNode(newHeaderElement); 100 return (SOAPHeaderElement) newHeaderElement; 101 } 102 103 protected SOAPElement addElement(Name name) throws SOAPException { 104 return addHeaderElement(name); 105 } 106 107 protected SOAPElement addElement(QName name) throws SOAPException { 108 return addHeaderElement(name); 109 } 110 111 public Iterator examineHeaderElements(String actor) { 112 return getHeaderElementsForActor(actor, false, false); 113 } 114 115 public Iterator extractHeaderElements(String actor) { 116 return getHeaderElementsForActor(actor, true, false); 117 } 118 119 protected Iterator getHeaderElementsForActor( 120 String actor, 121 boolean detach, 122 boolean mustUnderstand) { 123 if (actor == null || actor.equals("")) { 124 log.severe("SAAJ0132.impl.invalid.value.for.actor.or.role"); 125 throw new IllegalArgumentException("Invalid value for actor or role"); 126 } 127 return getHeaderElements(actor, detach, mustUnderstand); 128 } 129 130 protected Iterator getHeaderElements( 131 String actor, 132 boolean detach, 133 boolean mustUnderstand) { 134 List elementList = new ArrayList(); 135 136 Iterator eachChild = getChildElements(); 137 138 Object currentChild = iterate(eachChild); 139 while (currentChild != null) { 140 if (!(currentChild instanceof SOAPHeaderElement)) { 141 currentChild = iterate(eachChild); 142 } else { 143 HeaderElementImpl currentElement = 144 (HeaderElementImpl) currentChild; 145 currentChild = iterate(eachChild); 146 147 boolean isMustUnderstandMatching = 148 (!mustUnderstand || currentElement.getMustUnderstand()); 149 boolean doAdd = false; 150 if (actor == null && isMustUnderstandMatching) { 151 doAdd = true; 152 } else { 153 String currentActor = currentElement.getActorOrRole(); 154 if (currentActor == null) { 155 currentActor = ""; 156 } 157 158 if (currentActor.equalsIgnoreCase(actor) 159 && isMustUnderstandMatching) { 160 doAdd = true; 161 } 162 } 163 164 if (doAdd) { 165 elementList.add(currentElement); 166 if (detach) { 167 currentElement.detachNode(); 168 } 169 } 170 } 171 } 172 173 return elementList.listIterator(); 174 } 175 176 private Object iterate(Iterator each) { 177 return each.hasNext() ? each.next() : null; 178 } 179 180 public void setParentElement(SOAPElement element) throws SOAPException { 181 if (!(element instanceof SOAPEnvelope)) { 182 log.severe("SAAJ0133.impl.header.parent.mustbe.envelope"); 183 throw new SOAPException("Parent of SOAPHeader has to be a SOAPEnvelope"); 184 } 185 super.setParentElement(element); 186 } 187 188 // overriding ElementImpl's method to ensure that HeaderElements are 189 // namespace qualified. Holds for both SOAP versions. 190 // TODO - This check needs to be made for other addChildElement() methods 191 // as well. 192 public SOAPElement addChildElement(String localName) throws SOAPException { 193 194 SOAPElement element = super.addChildElement(localName); 195 // check that URI is not empty, ensuring that the element is NS qualified. 196 String uri = element.getElementName().getURI(); 197 if ((uri == null) || ("").equals(uri)) { 198 log.severe("SAAJ0134.impl.header.elems.ns.qualified"); 199 throw new SOAPExceptionImpl("HeaderElements must be namespace qualified"); 200 } 201 return element; 202 } 203 204 public Iterator examineAllHeaderElements() { 205 return getHeaderElements(null, false, MUST_UNDERSTAND_ONLY); 206 } 207 208 public Iterator examineMustUnderstandHeaderElements(String actor) { 209 return getHeaderElements(actor, false, true); 210 211 } 212 213 public Iterator extractAllHeaderElements() { 214 return getHeaderElements(null, true, false); 215 } 216 217 public SOAPHeaderElement addUpgradeHeaderElement(Iterator supportedSoapUris) 218 throws SOAPException { 219 if (supportedSoapUris == null) { 220 log.severe("SAAJ0411.ver1_2.no.null.supportedURIs"); 221 throw new SOAPException("Argument cannot be null; iterator of supportedURIs cannot be null"); 222 } 223 if (!supportedSoapUris.hasNext()) { 224 log.severe("SAAJ0412.ver1_2.no.empty.list.of.supportedURIs"); 225 throw new SOAPException("List of supported URIs cannot be empty"); 226 } 227 Name upgradeName = getUpgradeName(); 228 SOAPHeaderElement upgradeHeaderElement = 229 (SOAPHeaderElement) addChildElement(upgradeName); 230 Name supportedEnvelopeName = getSupportedEnvelopeName(); 231 int i = 0; 232 while (supportedSoapUris.hasNext()) { 233 SOAPElement subElement = 234 upgradeHeaderElement.addChildElement(supportedEnvelopeName); 235 String ns = "ns" + Integer.toString(i); 236 subElement.addAttribute( 237 NameImpl.createFromUnqualifiedName("qname"), 238 ns + ":Envelope"); 239 subElement.addNamespaceDeclaration( 240 ns, 241 (String) supportedSoapUris.next()); 242 i ++; 243 } 244 return upgradeHeaderElement; 245 } 246 247 public SOAPHeaderElement addUpgradeHeaderElement(String supportedSoapUri) 248 throws SOAPException { 249 return addUpgradeHeaderElement(new String[] {supportedSoapUri}); 250 } 251 252 public SOAPHeaderElement addUpgradeHeaderElement(String[] supportedSoapUris) 253 throws SOAPException { 254 255 if (supportedSoapUris == null) { 256 log.severe("SAAJ0411.ver1_2.no.null.supportedURIs"); 257 throw new SOAPException("Argument cannot be null; array of supportedURIs cannot be null"); 258 } 259 if (supportedSoapUris.length == 0) { 260 log.severe("SAAJ0412.ver1_2.no.empty.list.of.supportedURIs"); 261 throw new SOAPException("List of supported URIs cannot be empty"); 262 } 263 Name upgradeName = getUpgradeName(); 264 SOAPHeaderElement upgradeHeaderElement = 265 (SOAPHeaderElement) addChildElement(upgradeName); 266 Name supportedEnvelopeName = getSupportedEnvelopeName(); 267 for (int i = 0; i < supportedSoapUris.length; i ++) { 268 SOAPElement subElement = 269 upgradeHeaderElement.addChildElement(supportedEnvelopeName); 270 String ns = "ns" + Integer.toString(i); 271 subElement.addAttribute( 272 NameImpl.createFromUnqualifiedName("qname"), 273 ns + ":Envelope"); 274 subElement.addNamespaceDeclaration(ns, supportedSoapUris[i]); 275 } 276 return upgradeHeaderElement; 277 } 278 279 protected SOAPElement convertToSoapElement(Element element) { 280 if (element instanceof SOAPHeaderElement) { 281 return (SOAPElement) element; 282 } else { 283 SOAPHeaderElement headerElement; 284 try { 285 headerElement = 286 createHeaderElement(NameImpl.copyElementName(element)); 287 } catch (SOAPException e) { 288 throw new ClassCastException("Could not convert Element to SOAPHeaderElement: " + e.getMessage()); 289 } 290 return replaceElementWithSOAPElement( 291 element, 292 (ElementImpl) headerElement); 293 } 294 } 295 296 public SOAPElement setElementQName(QName newName) throws SOAPException { 297 log.log(Level.SEVERE, 298 "SAAJ0146.impl.invalid.name.change.requested", 299 new Object[] {elementQName.getLocalPart(), 300 newName.getLocalPart()}); 301 throw new SOAPException("Cannot change name for " 302 + elementQName.getLocalPart() + " to " 303 + newName.getLocalPart()); 304 } 305 306 }