1/* 2 * Copyright (c) 1997, 2013, 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 26package com.sun.xml.internal.ws.addressing; 27 28import com.sun.xml.internal.ws.addressing.model.InvalidAddressingHeaderException; 29import com.sun.xml.internal.ws.addressing.model.MissingAddressingHeaderException; 30import com.sun.xml.internal.ws.api.SOAPVersion; 31import com.sun.xml.internal.ws.api.WSBinding; 32import com.sun.xml.internal.ws.api.addressing.AddressingVersion; 33import com.sun.xml.internal.ws.api.message.AddressingUtils; 34import com.sun.xml.internal.ws.api.message.Packet; 35import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation; 36import com.sun.xml.internal.ws.api.model.wsdl.WSDLFault; 37import com.sun.xml.internal.ws.api.model.wsdl.WSDLOperation; 38import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput; 39import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; 40import com.sun.xml.internal.ws.api.model.SEIModel; 41import com.sun.xml.internal.ws.api.model.JavaMethod; 42import com.sun.xml.internal.ws.api.model.WSDLOperationMapping; 43import com.sun.xml.internal.ws.model.JavaMethodImpl; 44import com.sun.xml.internal.ws.model.CheckedExceptionImpl; 45import com.sun.istack.internal.Nullable; 46import org.w3c.dom.Element; 47 48import javax.xml.namespace.QName; 49import javax.xml.soap.Detail; 50import javax.xml.soap.SOAPConstants; 51import javax.xml.soap.SOAPException; 52import javax.xml.soap.SOAPFactory; 53import javax.xml.soap.SOAPFault; 54import javax.xml.soap.SOAPMessage; 55import javax.xml.ws.WebServiceException; 56 57/** 58 * @author Rama Pulavarthi 59 * @author Arun Gupta 60 */ 61public abstract class WsaTubeHelper { 62 63 public WsaTubeHelper(WSBinding binding, SEIModel seiModel, WSDLPort wsdlPort) { 64 this.binding = binding; 65 this.wsdlPort = wsdlPort; 66 this.seiModel = seiModel; 67 this.soapVer = binding.getSOAPVersion(); 68 this.addVer = binding.getAddressingVersion(); 69 70 } 71 72 public String getFaultAction(Packet requestPacket, Packet responsePacket) { 73 String action = null; 74 if(seiModel != null) { 75 action = getFaultActionFromSEIModel(requestPacket,responsePacket); 76 } 77 if (action != null) { 78 return action; 79 } else { 80 action = addVer.getDefaultFaultAction(); 81 } 82 if (wsdlPort != null) { 83 WSDLOperationMapping wsdlOp = requestPacket.getWSDLOperationMapping(); 84 if (wsdlOp != null) { 85 WSDLBoundOperation wbo = wsdlOp.getWSDLBoundOperation(); 86 return getFaultAction(wbo, responsePacket); 87 } 88 } 89 return action; 90 } 91 92 String getFaultActionFromSEIModel(Packet requestPacket, Packet responsePacket) { 93 String action = null; 94 if (seiModel == null || wsdlPort == null) { 95 return action; 96 } 97 98 try { 99 SOAPMessage sm = responsePacket.getMessage().copy().readAsSOAPMessage(); 100 if (sm == null) { 101 return action; 102 } 103 104 if (sm.getSOAPBody() == null) { 105 return action; 106 } 107 108 if (sm.getSOAPBody().getFault() == null) { 109 return action; 110 } 111 112 Detail detail = sm.getSOAPBody().getFault().getDetail(); 113 if (detail == null) { 114 return action; 115 } 116 117 String ns = detail.getFirstChild().getNamespaceURI(); 118 String name = detail.getFirstChild().getLocalName(); 119 120 WSDLOperationMapping wsdlOp = requestPacket.getWSDLOperationMapping(); 121 JavaMethodImpl jm = (wsdlOp != null) ? (JavaMethodImpl)wsdlOp.getJavaMethod() : null; 122 if (jm != null) { 123 for (CheckedExceptionImpl ce : jm.getCheckedExceptions()) { 124 if (ce.getDetailType().tagName.getLocalPart().equals(name) && 125 ce.getDetailType().tagName.getNamespaceURI().equals(ns)) { 126 return ce.getFaultAction(); 127 } 128 } 129 } 130 return action; 131 } catch (SOAPException e) { 132 throw new WebServiceException(e); 133 } 134 } 135 136 String getFaultAction(@Nullable WSDLBoundOperation wbo, Packet responsePacket) { 137 String action = AddressingUtils.getAction(responsePacket.getMessage().getHeaders(), addVer, soapVer); 138 if (action != null) { 139 return action; 140 } 141 142 action = addVer.getDefaultFaultAction(); 143 if (wbo == null) { 144 return action; 145 } 146 147 try { 148 SOAPMessage sm = responsePacket.getMessage().copy().readAsSOAPMessage(); 149 if (sm == null) { 150 return action; 151 } 152 153 if (sm.getSOAPBody() == null) { 154 return action; 155 } 156 157 if (sm.getSOAPBody().getFault() == null) { 158 return action; 159 } 160 161 Detail detail = sm.getSOAPBody().getFault().getDetail(); 162 if (detail == null) { 163 return action; 164 } 165 166 String ns = detail.getFirstChild().getNamespaceURI(); 167 String name = detail.getFirstChild().getLocalName(); 168 169 WSDLOperation o = wbo.getOperation(); 170 171 WSDLFault fault = o.getFault(new QName(ns, name)); 172 if (fault == null) { 173 return action; 174 } 175 176 action = fault.getAction(); 177 178 return action; 179 } catch (SOAPException e) { 180 throw new WebServiceException(e); 181 } 182 } 183 184 public String getInputAction(Packet packet) { 185 String action = null; 186 187 if (wsdlPort != null) { 188 WSDLOperationMapping wsdlOp = packet.getWSDLOperationMapping(); 189 if (wsdlOp != null) { 190 WSDLBoundOperation wbo = wsdlOp.getWSDLBoundOperation(); 191 WSDLOperation op = wbo.getOperation(); 192 action = op.getInput().getAction(); 193 } 194 } 195 196 return action; 197 } 198 199 /** 200 * This method gives the Input addressing Action for a message. 201 * It gives the Action set in the wsdl operation for the corresponding payload. 202 * If it is not explicitly set, it gives the soapAction 203 * @param packet 204 * @return input Action 205 */ 206 public String getEffectiveInputAction(Packet packet) { 207 //non-default SOAPAction beomes wsa:action 208 if(packet.soapAction != null && !packet.soapAction.equals("")) { 209 return packet.soapAction; 210 } 211 String action; 212 213 if (wsdlPort != null) { 214 WSDLOperationMapping wsdlOp = packet.getWSDLOperationMapping(); 215 if (wsdlOp != null) { 216 WSDLBoundOperation wbo = wsdlOp.getWSDLBoundOperation(); 217 WSDLOperation op = wbo.getOperation(); 218 action = op.getInput().getAction(); 219 } else { 220 action = packet.soapAction; 221 } 222 } else { 223 action = packet.soapAction; 224 } 225 return action; 226 } 227 228 public boolean isInputActionDefault(Packet packet) { 229 if (wsdlPort == null) { 230 return false; 231 } 232 WSDLOperationMapping wsdlOp = packet.getWSDLOperationMapping(); 233 if(wsdlOp == null) { 234 return false; 235 } 236 WSDLBoundOperation wbo = wsdlOp.getWSDLBoundOperation(); 237 WSDLOperation op = wbo.getOperation(); 238 return op.getInput().isDefaultAction(); 239 240 } 241 242 public String getSOAPAction(Packet packet) { 243 String action = ""; 244 245 if (packet == null || packet.getMessage() == null) { 246 return action; 247 } 248 249 if (wsdlPort == null) { 250 return action; 251 } 252 253 WSDLOperationMapping wsdlOp = packet.getWSDLOperationMapping(); 254 if (wsdlOp == null) { 255 return action; 256 } 257 258 WSDLBoundOperation op = wsdlOp.getWSDLBoundOperation(); 259 action = op.getSOAPAction(); 260 return action; 261 } 262 263 public String getOutputAction(Packet packet) { 264 //String action = AddressingVersion.UNSET_OUTPUT_ACTION; 265 String action = null; 266 WSDLOperationMapping wsdlOp = packet.getWSDLOperationMapping(); 267 if (wsdlOp != null) { 268 JavaMethod javaMethod = wsdlOp.getJavaMethod(); 269 if (javaMethod != null) { 270 JavaMethodImpl jm = (JavaMethodImpl) javaMethod; 271 if (jm != null && jm.getOutputAction() != null && !jm.getOutputAction().equals("")) { 272 return jm.getOutputAction(); 273 } 274 } 275 WSDLBoundOperation wbo = wsdlOp.getWSDLBoundOperation(); 276 if (wbo != null) return getOutputAction(wbo); 277 } 278 return action; 279 } 280 281 String getOutputAction(@Nullable WSDLBoundOperation wbo) { 282 String action = AddressingVersion.UNSET_OUTPUT_ACTION; 283 if (wbo != null) { 284 WSDLOutput op = wbo.getOperation().getOutput(); 285 if (op != null) { 286 action = op.getAction(); 287 } 288 } 289 return action; 290 } 291 292 public SOAPFault createInvalidAddressingHeaderFault(InvalidAddressingHeaderException e, AddressingVersion av) { 293 QName name = e.getProblemHeader(); 294 QName subsubcode = e.getSubsubcode(); 295 QName subcode = av.invalidMapTag; 296 String faultstring = String.format(av.getInvalidMapText(), name, subsubcode); 297 298 try { 299 SOAPFactory factory; 300 SOAPFault fault; 301 if (soapVer == SOAPVersion.SOAP_12) { 302 factory = SOAPVersion.SOAP_12.getSOAPFactory(); 303 fault = factory.createFault(); 304 fault.setFaultCode(SOAPConstants.SOAP_SENDER_FAULT); 305 fault.appendFaultSubcode(subcode); 306 fault.appendFaultSubcode(subsubcode); 307 getInvalidMapDetail(name, fault.addDetail()); 308 } else { 309 factory = SOAPVersion.SOAP_11.getSOAPFactory(); 310 fault = factory.createFault(); 311 fault.setFaultCode(subsubcode); 312 } 313 314 fault.setFaultString(faultstring); 315 316 return fault; 317 } catch (SOAPException se) { 318 throw new WebServiceException(se); 319 } 320 } 321 322 public SOAPFault newMapRequiredFault(MissingAddressingHeaderException e) { 323 QName subcode = addVer.mapRequiredTag; 324 QName subsubcode = addVer.mapRequiredTag; 325 String faultstring = addVer.getMapRequiredText(); 326 327 try { 328 SOAPFactory factory; 329 SOAPFault fault; 330 if (soapVer == SOAPVersion.SOAP_12) { 331 factory = SOAPVersion.SOAP_12.getSOAPFactory(); 332 fault = factory.createFault(); 333 fault.setFaultCode(SOAPConstants.SOAP_SENDER_FAULT); 334 fault.appendFaultSubcode(subcode); 335 fault.appendFaultSubcode(subsubcode); 336 getMapRequiredDetail(e.getMissingHeaderQName(), fault.addDetail()); 337 } else { 338 factory = SOAPVersion.SOAP_11.getSOAPFactory(); 339 fault = factory.createFault(); 340 fault.setFaultCode(subsubcode); 341 } 342 343 fault.setFaultString(faultstring); 344 345 return fault; 346 } catch (SOAPException se) { 347 throw new WebServiceException(se); 348 } 349 } 350 351 public abstract void getProblemActionDetail(String action, Element element); 352 public abstract void getInvalidMapDetail(QName name, Element element); 353 public abstract void getMapRequiredDetail(QName name, Element element); 354 355 protected SEIModel seiModel; 356 protected WSDLPort wsdlPort; 357 protected WSBinding binding; 358 protected final SOAPVersion soapVer; 359 protected final AddressingVersion addVer; 360} 361