View Javadoc
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.JavaMethodImpl;
44  import com.sun.xml.internal.ws.model.CheckedExceptionImpl;
45  import com.sun.istack.internal.Nullable;
46  import org.w3c.dom.Element;
47  
48  import javax.xml.namespace.QName;
49  import javax.xml.soap.Detail;
50  import javax.xml.soap.SOAPConstants;
51  import javax.xml.soap.SOAPException;
52  import javax.xml.soap.SOAPFactory;
53  import javax.xml.soap.SOAPFault;
54  import javax.xml.soap.SOAPMessage;
55  import javax.xml.ws.WebServiceException;
56  
57  /**
58   * @author Rama Pulavarthi
59   * @author Arun Gupta
60   */
61  public 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 }