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.api;
27  
28  import com.sun.xml.internal.bind.util.Which;
29  import com.sun.xml.internal.ws.api.message.saaj.SAAJFactory;
30  import com.sun.xml.internal.ws.encoding.soap.SOAP12Constants;
31  
32  import javax.xml.namespace.QName;
33  import javax.xml.soap.MessageFactory;
34  import javax.xml.soap.SOAPConstants;
35  import javax.xml.soap.SOAPException;
36  import javax.xml.soap.SOAPFactory;
37  import javax.xml.ws.soap.SOAPBinding;
38  
39  import com.oracle.webservices.internal.api.EnvelopeStyle;
40  import com.oracle.webservices.internal.api.EnvelopeStyleFeature;
41  
42  import java.util.Arrays;
43  import java.util.Collections;
44  import java.util.HashSet;
45  import java.util.Set;
46  
47  /**
48   * Version of SOAP (1.1 and 1.2).
49   *
50   * <p>
51   * This class defines various constants for SOAP 1.1 and SOAP 1.2,
52   * and also defines convenience methods to simplify the processing
53   * of multiple SOAP versions.
54   *
55   * <p>
56   * This constant alows you to do:
57   *
58   * <pre>
59   * SOAPVersion version = ...;
60   * version.someOp(...);
61   * </pre>
62   *
63   * As opposed to:
64   *
65   * <pre>
66   * if(binding is SOAP11) {
67   *   doSomeOp11(...);
68   * } else {
69   *   doSomeOp12(...);
70   * }
71   * </pre>
72   *
73   * @author Kohsuke Kawaguchi
74   */
75  public enum SOAPVersion {
76      SOAP_11(SOAPBinding.SOAP11HTTP_BINDING,
77              com.sun.xml.internal.ws.encoding.soap.SOAPConstants.URI_ENVELOPE,
78              "text/xml",
79              SOAPConstants.URI_SOAP_ACTOR_NEXT, "actor",
80              javax.xml.soap.SOAPConstants.SOAP_1_1_PROTOCOL,
81              new QName(com.sun.xml.internal.ws.encoding.soap.SOAPConstants.URI_ENVELOPE, "MustUnderstand"),
82              "Client",
83              "Server",
84              Collections.singleton(SOAPConstants.URI_SOAP_ACTOR_NEXT)),
85  
86      SOAP_12(SOAPBinding.SOAP12HTTP_BINDING,
87              SOAP12Constants.URI_ENVELOPE,
88              "application/soap+xml",
89              SOAPConstants.URI_SOAP_1_2_ROLE_ULTIMATE_RECEIVER, "role",
90              javax.xml.soap.SOAPConstants.SOAP_1_2_PROTOCOL,
91              new QName(com.sun.xml.internal.ws.encoding.soap.SOAP12Constants.URI_ENVELOPE, "MustUnderstand"),
92              "Sender",
93              "Receiver",
94              new HashSet<String>(Arrays.asList(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT,SOAPConstants.URI_SOAP_1_2_ROLE_ULTIMATE_RECEIVER)));
95  
96      /**
97       * Binding ID for SOAP/HTTP binding of this SOAP version.
98       *
99       * <p>
100      * Either {@link SOAPBinding#SOAP11HTTP_BINDING} or
101      *  {@link SOAPBinding#SOAP12HTTP_BINDING}
102      */
103     public final String httpBindingId;
104 
105     /**
106      * SOAP envelope namespace URI.
107      */
108     public final String nsUri;
109 
110     /**
111      * Content-type. Either "text/xml" or "application/soap+xml".
112      */
113     public final String contentType;
114 
115     /**
116      * SOAP MustUnderstand FaultCode for this SOAP version
117      */
118     public final QName faultCodeMustUnderstand;
119 
120     /**
121      * SAAJ {@link MessageFactory} for this SOAP version.
122      * @deprecated
123      */
124     public final MessageFactory saajMessageFactory;
125 
126     /**
127      * SAAJ {@link SOAPFactory} for this SOAP version.
128      * @deprecated
129      */
130     public final SOAPFactory saajSoapFactory;
131 
132     private final String saajFactoryString;
133 
134     /**
135      * If the actor/role attribute is absent, this SOAP version assumes this value.
136      */
137     public final String implicitRole;
138 
139     /**
140      * Singleton set that contains {@link #implicitRole}.
141      */
142     public final Set<String> implicitRoleSet;
143 
144     /**
145      * This represents the roles required to be assumed by SOAP binding implementation.
146      */
147     public final Set<String> requiredRoles;
148 
149     /**
150      * "role" (SOAP 1.2) or "actor" (SOAP 1.1)
151      */
152     public final String roleAttributeName;
153 
154     /**
155      * "{nsUri}Client" or "{nsUri}Sender"
156      */
157     public final QName faultCodeClient;
158 
159     /**
160      * "{nsUri}Server" or "{nsUri}Receiver"
161      */
162     public final QName faultCodeServer;
163 
164     private SOAPVersion(String httpBindingId, String nsUri, String contentType, String implicitRole, String roleAttributeName,
165                         String saajFactoryString, QName faultCodeMustUnderstand, String faultCodeClientLocalName,
166                         String faultCodeServerLocalName,Set<String> requiredRoles) {
167         this.httpBindingId = httpBindingId;
168         this.nsUri = nsUri;
169         this.contentType = contentType;
170         this.implicitRole = implicitRole;
171         this.implicitRoleSet = Collections.singleton(implicitRole);
172         this.roleAttributeName = roleAttributeName;
173         this.saajFactoryString = saajFactoryString;
174         try {
175             saajMessageFactory = MessageFactory.newInstance(saajFactoryString);
176             saajSoapFactory = SOAPFactory.newInstance(saajFactoryString);
177         } catch (SOAPException e) {
178             throw new Error(e);
179         } catch (NoSuchMethodError e) {
180             // SAAJ 1.3 is not in the classpath
181             LinkageError x = new LinkageError("You are loading old SAAJ from "+ Which.which(MessageFactory.class));
182             x.initCause(e);
183             throw x;
184         }
185         this.faultCodeMustUnderstand = faultCodeMustUnderstand;
186         this.requiredRoles = requiredRoles;
187         this.faultCodeClient = new QName(nsUri,faultCodeClientLocalName);
188         this.faultCodeServer = new QName(nsUri,faultCodeServerLocalName);
189     }
190 
191     public SOAPFactory getSOAPFactory() {
192         try {
193                 return SAAJFactory.getSOAPFactory(saajFactoryString);
194         } catch (SOAPException e) {
195             throw new Error(e);
196         } catch (NoSuchMethodError e) {
197             // SAAJ 1.3 is not in the classpath
198             LinkageError x = new LinkageError("You are loading old SAAJ from "+ Which.which(MessageFactory.class));
199             x.initCause(e);
200             throw x;
201         }
202     }
203 
204     public MessageFactory getMessageFactory() {
205         try {
206                 return SAAJFactory.getMessageFactory(saajFactoryString);
207         } catch (SOAPException e) {
208             throw new Error(e);
209         } catch (NoSuchMethodError e) {
210             // SAAJ 1.3 is not in the classpath
211             LinkageError x = new LinkageError("You are loading old SAAJ from "+ Which.which(MessageFactory.class));
212             x.initCause(e);
213             throw x;
214         }
215     }
216 
217     public String toString() {
218         return httpBindingId;
219     }
220 
221     /**
222      * Returns {@link SOAPVersion} whose {@link #httpBindingId} equals to
223      * the given string.
224      *
225      * This method does not perform input string validation.
226      *
227      * @param binding
228      *      for historical reason, we treat null as {@link #SOAP_11},
229      *      but you really shouldn't be passing null.
230      * @return always non-null.
231      */
232     public static SOAPVersion fromHttpBinding(String binding) {
233         if(binding==null)
234             return SOAP_11;
235 
236         if(binding.equals(SOAP_12.httpBindingId))
237             return SOAP_12;
238         else
239             return SOAP_11;
240     }
241 
242     /**
243      * Returns {@link SOAPVersion} whose {@link #nsUri} equals to
244      * the given string.
245      *
246      * This method does not perform input string validation.
247      *
248      * @param nsUri
249      *      must not be null.
250      * @return always non-null.
251      */
252     public static SOAPVersion fromNsUri(String nsUri) {
253         if(nsUri.equals(SOAP_12.nsUri))
254             return SOAP_12;
255         else
256             return SOAP_11;
257     }
258 
259     public static SOAPVersion from(EnvelopeStyleFeature f) {
260         EnvelopeStyle.Style[] style = f.getStyles();
261         if (style.length != 1) throw new IllegalArgumentException ("The EnvelopingFeature must has exactly one Enveloping.Style");
262         return from(style[0]);
263     }
264 
265     public static SOAPVersion from(EnvelopeStyle.Style style) {
266         switch (style) {
267         case SOAP11: return SOAP_11;
268         case SOAP12: return SOAP_12;
269         case XML: //ERROR??
270         default: return SOAP_11;
271         }
272     }
273 
274     public EnvelopeStyleFeature toFeature() {
275         return SOAP_11.equals(this) ?
276             new EnvelopeStyleFeature(new EnvelopeStyle.Style[]{EnvelopeStyle.Style.SOAP11}) :
277             new EnvelopeStyleFeature(new EnvelopeStyle.Style[]{EnvelopeStyle.Style.SOAP12});
278     }
279 }