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