1 /*
2  * Copyright (c) 1997, 2012, 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.addressing;
27 
28 import com.sun.istack.internal.NotNull;
29 import com.sun.istack.internal.Nullable;
30 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
31 import com.sun.xml.internal.ws.addressing.W3CAddressingConstants;
32 import com.sun.xml.internal.ws.addressing.WsaTubeHelper;
33 import com.sun.xml.internal.ws.addressing.v200408.MemberSubmissionAddressingConstants;
34 import com.sun.xml.internal.ws.api.WSBinding;
35 import com.sun.xml.internal.ws.api.message.Header;
36 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
37 import com.sun.xml.internal.ws.api.model.SEIModel;
38 import com.sun.xml.internal.ws.developer.MemberSubmissionAddressingFeature;
39 import com.sun.xml.internal.ws.developer.MemberSubmissionEndpointReference;
40 import com.sun.xml.internal.ws.message.stream.OutboundStreamHeader;
41 
42 import javax.xml.namespace.QName;
43 import javax.xml.stream.XMLStreamException;
44 import javax.xml.ws.EndpointReference;
45 import javax.xml.ws.WebServiceException;
46 import javax.xml.ws.WebServiceFeature;
47 import javax.xml.ws.soap.AddressingFeature;
48 import javax.xml.ws.wsaddressing.W3CEndpointReference;
49 import java.io.ByteArrayInputStream;
50 import java.io.UnsupportedEncodingException;
51 
52 /**
53  * 'Traits' object that absorbs differences of WS-Addressing versions.
54  *
55  * @author Arun Gupta
56  */
57 public enum AddressingVersion {
58 
59     W3C("http://www.w3.org/2005/08/addressing",
60         "wsa",
61         W3CAddressingConstants.ANONYMOUS_EPR,
62         "http://www.w3.org/2006/05/addressing/wsdl",
63         "http://www.w3.org/2006/05/addressing/wsdl",
64         "http://www.w3.org/2005/08/addressing/anonymous",
65         "http://www.w3.org/2005/08/addressing/none",
66         new EPR(W3CEndpointReference.class,
67                     "Address",
68                     "ServiceName",
69                     "EndpointName",
70                     "InterfaceName",
71                     new QName("http://www.w3.org/2005/08/addressing","Metadata","wsa"),
72                     "ReferenceParameters",
73                     null )) {
74 
getActionMismatchLocalName()75         /* package */  String getActionMismatchLocalName() {
76             return "ActionMismatch";
77         }
78         @Override
isReferenceParameter(String localName)79         public boolean isReferenceParameter(String localName) {
80             return localName.equals("ReferenceParameters");
81         }
82 
83         @Override
getWsaHelper(WSDLPort wsdlPort, SEIModel seiModel, WSBinding binding)84         public WsaTubeHelper getWsaHelper(WSDLPort wsdlPort, SEIModel seiModel, WSBinding binding) {
85             return new com.sun.xml.internal.ws.addressing.WsaTubeHelperImpl(wsdlPort, seiModel, binding);
86         }
87 
88         @Override
getMapRequiredLocalName()89         /* package */ String getMapRequiredLocalName() {
90             return "MessageAddressingHeaderRequired";
91         }
92 
93         @Override
getMapRequiredText()94         public String getMapRequiredText() {
95             return "A required header representing a Message Addressing Property is not present";
96         }
97 
getInvalidAddressLocalName()98         /* package */ String getInvalidAddressLocalName() {
99             return "InvalidAddress";
100         }
101 
102         @Override
getInvalidMapLocalName()103         /* package */ String getInvalidMapLocalName() {
104             return "InvalidAddressingHeader";
105         }
106 
107         @Override
getInvalidMapText()108         public String getInvalidMapText() {
109             return "A header representing a Message Addressing Property is not valid and the message cannot be processed";
110         }
111 
112         @Override
getInvalidCardinalityLocalName()113         /* package */ String getInvalidCardinalityLocalName() {
114             return "InvalidCardinality";
115         }
116 
createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName)117         /*package*/ Header createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName) {
118             return new OutboundReferenceParameterHeader(mark,nsUri,localName);
119         }
120 
getIsReferenceParameterLocalName()121         /*package*/ String getIsReferenceParameterLocalName() {
122             return "IsReferenceParameter";
123         }
124 
getWsdlAnonymousLocalName()125         /* package */ String getWsdlAnonymousLocalName() {
126             return "Anonymous";
127         }
128 
getPrefix()129         public String getPrefix() {
130             return "wsa";
131         }
132 
getWsdlPrefix()133         public String getWsdlPrefix() {
134             return "wsaw";
135         }
136 
getFeatureClass()137         public Class<? extends WebServiceFeature> getFeatureClass() {
138             return AddressingFeature.class;
139         }
140     },
141     MEMBER("http://schemas.xmlsoap.org/ws/2004/08/addressing",
142            "wsa",
143            MemberSubmissionAddressingConstants.ANONYMOUS_EPR,
144            "http://schemas.xmlsoap.org/ws/2004/08/addressing",
145            "http://schemas.xmlsoap.org/ws/2004/08/addressing/policy",
146            "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous",
147             "",
148            new EPR(MemberSubmissionEndpointReference.class,
149                     "Address",
150                     "ServiceName",
151                     "PortName",
152                     "PortType",
153                     MemberSubmissionAddressingConstants.MEX_METADATA,
154                     "ReferenceParameters",
155                     "ReferenceProperties")) {
getActionMismatchLocalName()156         /* package */  String getActionMismatchLocalName() {
157             return "InvalidMessageInformationHeader";
158         }
159         @Override
isReferenceParameter(String localName)160         public boolean isReferenceParameter(String localName) {
161             return localName.equals("ReferenceParameters") || localName.equals("ReferenceProperties");
162         }
163 
164         @Override
getWsaHelper(WSDLPort wsdlPort, SEIModel seiModel, WSBinding binding)165         public WsaTubeHelper getWsaHelper(WSDLPort wsdlPort, SEIModel seiModel, WSBinding binding) {
166             return new com.sun.xml.internal.ws.addressing.v200408.WsaTubeHelperImpl(wsdlPort, seiModel, binding);
167         }
168 
169         @Override
getMapRequiredLocalName()170         /* package */ String getMapRequiredLocalName() {
171             return "MessageInformationHeaderRequired";
172         }
173 
174         @Override
getMapRequiredText()175         public String getMapRequiredText() {
176             return "A required message information header, To, MessageID, or Action, is not present.";
177         }
178 
getInvalidAddressLocalName()179         /* package */ String getInvalidAddressLocalName() {
180             return getInvalidMapLocalName();
181         }
182 
183         @Override
getInvalidMapLocalName()184         /* package */ String getInvalidMapLocalName() {
185             return "InvalidMessageInformationHeader";
186         }
187 
188         @Override
getInvalidMapText()189         public String getInvalidMapText() {
190             return "A message information header is not valid and the message cannot be processed.";
191         }
192 
193         @Override
getInvalidCardinalityLocalName()194         /* package */ String getInvalidCardinalityLocalName() {
195             return getInvalidMapLocalName();
196         }
197 
createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName)198         /*package*/ Header createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName) {
199             return new OutboundStreamHeader(mark,nsUri,localName);
200         }
201 
getIsReferenceParameterLocalName()202         /*package*/ String getIsReferenceParameterLocalName() {
203             return "";
204         }
205 
getWsdlAnonymousLocalName()206         /* package */ String getWsdlAnonymousLocalName() {
207             return "";
208         }
209 
getPrefix()210         public String getPrefix() {
211             return "wsa";
212         }
213 
getWsdlPrefix()214         public String getWsdlPrefix() {
215             return "wsaw";
216         }
217 
getFeatureClass()218         public Class<? extends WebServiceFeature> getFeatureClass() {
219             return MemberSubmissionAddressingFeature.class;
220         }
221     };
222 
223     /**
224      * Namespace URI
225      */
226     public final String nsUri;
227 
228     /**
229      * Namespace URI for the WSDL Binding
230      */
231     public final String wsdlNsUri;
232 
233     /**
234      * Representing either {@link W3CEndpointReference} or
235      * {@link MemberSubmissionEndpointReference}.
236      */
237     public final EPR eprType;
238 
239     /**
240      * Namespace URI for the WSDL Binding
241      */
242     public final String policyNsUri;
243 
244     /**
245      * Gets the anonymous URI value associated with this WS-Addressing version.
246      */
247     public final @NotNull String anonymousUri;
248 
249     /**
250      * Gets the none URI value associated with this WS-Addressing version.
251      */
252     public final @NotNull String noneUri;
253 
254     /**
255      * Represents the anonymous EPR.
256      */
257     public final WSEndpointReference anonymousEpr;
258 
259     /**
260      * Represents the To QName in the SOAP message for a specific WS-Addressing Version.
261      */
262     public final QName toTag;
263 
264     /**
265      * Represents the From QName in the SOAP message for a specific WS-Addressing Version.
266      */
267     public final QName fromTag;
268 
269     /**
270      * Represents the ReplyTo QName in the SOAP message for a specific WS-Addressing Version.
271      */
272     public final QName replyToTag;
273 
274     /**
275      * Represents the FaultTo QName for a specific WS-Addressing Version.
276      */
277     public final QName faultToTag;
278 
279     /**
280      * Represents the Action QName in the SOAP message for a specific WS-Addressing Version.
281      */
282     public final QName actionTag;
283 
284     /**
285      * Represents the MessageID QName in the SOAP message for a specific WS-Addressing Version.
286      */
287     public final QName messageIDTag;
288 
289     /**
290      * Represents the RelatesTo QName in the SOAP message for a specific WS-Addressing Version.
291      */
292     public final QName relatesToTag;
293 
294     /**
295      * Represents the QName of the fault code when a required header representing a
296      * WS-Addressing Message Addressing Property is not present.
297      */
298     public final QName mapRequiredTag;
299 
300     /**
301      * Represents the QName of the fault code when Action is not supported at this endpoint.
302      */
303     public final QName actionMismatchTag;
304 
305     /**
306      * Represents the QName of the fault code when Action is not supported at this endpoint.
307      */
308     public final QName actionNotSupportedTag;
309 
310     /**
311      * Represents the text of the fault when Action is not supported at this endpoint.
312      */
313     public final String actionNotSupportedText;
314 
315     /**
316      * Represents the QName of the fault code when a header representing a
317      * WS-Addressing Message Addressing Property is invalid and cannot be processed.
318      */
319     public final QName invalidMapTag;
320 
321     /**
322      * Represents the QName of the fault code when a header representing a
323      * WS-Addressing Message Addressing Property occurs greater than expected number.
324      */
325     public final QName invalidCardinalityTag;
326 
327     /**
328      * Represents the QName of the fault code when a header representing an
329      * address is not valid.
330      */
331     public final QName invalidAddressTag;
332 
333     /**
334      * Represents the QName of the element that conveys additional information
335      * on the pre-defined WS-Addressing faults.
336      */
337     public final QName problemHeaderQNameTag;
338 
339     /**
340      * Represents the QName of the element that conveys additional information
341      * if Action is not matching with that expected.
342      */
343     public final QName problemActionTag;
344 
345     /**
346      * Represents the QName of the header element that is used to capture the fault detail
347      * if there is a fault processing WS-Addressing Message Addressing Property. This is
348      * only used for SOAP 1.1.
349      */
350     public final QName faultDetailTag;
351 
352     /**
353      * Fault sub-sub-code that represents
354      * "Specifies that the invalid header was expected to be an EPR but did not contain an [address]."
355      */
356     public final QName fault_missingAddressInEpr;
357 
358     /**
359      * Represents the Action QName in the WSDL for a specific WS-Addressing Version.
360      */
361     public final QName wsdlActionTag;
362 
363     /**
364      * Represents the WSDL extension QName for a specific WS-Addressing Version.
365      */
366     public final QName wsdlExtensionTag;
367 
368     /**
369      * Represents the WSDL anonymous QName for a specific WS-Addressing Version.
370      */
371     public final QName wsdlAnonymousTag;
372 
373     /**
374      * Represents the QName of the reference parameter in a SOAP message. This is
375      * only valid for W3C WS-Addressing.
376      */
377     public final QName isReferenceParameterTag;
378 
379     private static final String EXTENDED_FAULT_NAMESPACE = "http://jax-ws.dev.java.net/addressing/fault";
380     public static final String UNSET_OUTPUT_ACTION = "http://jax-ws.dev.java.net/addressing/output-action-not-set";
381     public static final String UNSET_INPUT_ACTION = "http://jax-ws.dev.java.net/addressing/input-action-not-set";
382 
383     /**
384      * Fault sub-sub-code that represents duplicate &lt;Address> element in EPR.
385      * This is a fault code not defined in the spec.
386      */
387     public static final QName fault_duplicateAddressInEpr = new QName(
388         EXTENDED_FAULT_NAMESPACE, "DuplicateAddressInEpr", "wsa"
389     );
390 
AddressingVersion(String nsUri, String prefix, String anonymousEprString, String wsdlNsUri, String policyNsUri, String anonymousUri, String noneUri, EPR eprType )391     private AddressingVersion(String nsUri, String prefix, String anonymousEprString, String wsdlNsUri, String policyNsUri,
392                               String anonymousUri, String noneUri,
393                               EPR eprType ) {
394         this.nsUri = nsUri;
395         this.wsdlNsUri = wsdlNsUri;
396         this.policyNsUri = policyNsUri;
397         this.anonymousUri = anonymousUri;
398         this.noneUri = noneUri;
399         toTag = new QName(nsUri,"To", prefix);
400         fromTag = new QName(nsUri,"From", prefix);
401         replyToTag = new QName(nsUri,"ReplyTo", prefix);
402         faultToTag = new QName(nsUri,"FaultTo", prefix);
403         actionTag = new QName(nsUri,"Action", prefix);
404         messageIDTag = new QName(nsUri,"MessageID", prefix);
405         relatesToTag = new QName(nsUri,"RelatesTo", prefix);
406 
407         mapRequiredTag = new QName(nsUri,getMapRequiredLocalName(), prefix);
408         actionMismatchTag = new QName(nsUri,getActionMismatchLocalName(), prefix);
409         actionNotSupportedTag = new QName(nsUri,"ActionNotSupported", prefix);
410         actionNotSupportedText = "The \"%s\" cannot be processed at the receiver";
411         invalidMapTag = new QName(nsUri,getInvalidMapLocalName(), prefix);
412         invalidAddressTag = new QName(nsUri,getInvalidAddressLocalName(), prefix);
413         invalidCardinalityTag = new QName(nsUri,getInvalidCardinalityLocalName(), prefix);
414         faultDetailTag = new QName(nsUri,"FaultDetail", prefix);
415 
416         problemHeaderQNameTag = new QName(nsUri,"ProblemHeaderQName", prefix);
417         problemActionTag = new QName(nsUri, "ProblemAction", prefix);
418 
419         fault_missingAddressInEpr = new QName(nsUri,"MissingAddressInEPR", prefix);
420         isReferenceParameterTag = new QName(nsUri,getIsReferenceParameterLocalName(), prefix);
421 
422         wsdlActionTag = new QName(wsdlNsUri,"Action", prefix);
423         wsdlExtensionTag = new QName(wsdlNsUri, "UsingAddressing", prefix);
424         wsdlAnonymousTag = new QName(wsdlNsUri, getWsdlAnonymousLocalName(), prefix);
425 
426         // create stock anonymous EPR
427         try {
428             this.anonymousEpr = new WSEndpointReference(new ByteArrayInputStream(anonymousEprString.getBytes("UTF-8")),this);
429         } catch (XMLStreamException e) {
430             throw new Error(e); // bug in our code as EPR should parse.
431         } catch (UnsupportedEncodingException e) {
432             throw new Error(e);
433         }
434         this.eprType = eprType;
435     }
436 
437     /**
438      * Gets the local name of the fault when a header representing a WS-Addressing Action is not same as SOAPAction
439      *
440      * @return local name
441      */
getActionMismatchLocalName()442     /* package */ abstract String getActionMismatchLocalName();
443 
444     /**
445      * Returns {@link AddressingVersion} whose {@link #nsUri} equals to
446      * the given string.
447      *
448      * This method does not perform input string validation.
449      *
450      * @param nsUri
451      *      must not be null.
452      * @return always non-null.
453      */
fromNsUri(String nsUri)454     public static AddressingVersion fromNsUri(String nsUri) {
455         if (nsUri.equals(W3C.nsUri))
456             return W3C;
457 
458         if (nsUri.equals(MEMBER.nsUri))
459             return MEMBER;
460 
461         return null;
462     }
463 
464     /**
465      * Gets the {@link AddressingVersion} from a {@link WSBinding}
466      *
467      * @param binding WSDL binding
468      * @return
469      *     addresing version enabled, or null if none is enabled.
470      */
471     public static @Nullable
fromBinding(WSBinding binding)472     AddressingVersion fromBinding(WSBinding binding) {
473         // TODO: who is responsible for reporting an error if both versions
474         // are on?
475         if (binding.isFeatureEnabled(AddressingFeature.class))
476             return W3C;
477 
478         if (binding.isFeatureEnabled(MemberSubmissionAddressingFeature.class))
479             return MEMBER;
480 
481         return null;
482     }
483 
484     /**
485      * Gets the {@link AddressingVersion} from a {@link WSDLPort}
486      *
487      * @param port WSDL port
488      * @return addresing version
489      */
fromPort(WSDLPort port)490     public static AddressingVersion fromPort(WSDLPort port) {
491         if (port == null)
492             return null;
493 
494         WebServiceFeature wsf = port.getFeature(AddressingFeature.class);
495         if (wsf == null) {
496             wsf = port.getFeature(MemberSubmissionAddressingFeature.class);
497         }
498         if (wsf == null)
499             return null;
500 
501         return fromFeature(wsf);
502     }
503 
504     /**
505      * Returns {@link #nsUri} associated with this {@link AddressingVersion}
506      *
507      * @return namespace URI
508      * @deprecated
509      *      Use {@link #nsUri}.
510      */
getNsUri()511     public String getNsUri() {
512         return nsUri;
513     }
514 
515     /**
516      * Returns true if the given local name is considered as
517      * a reference parameter in EPR.
518      *
519      * For W3C, this means "ReferenceParameters",
520      * and for the member submission version, this means
521      * either "ReferenceParameters" or "ReferenceProperties".
522      */
isReferenceParameter(String localName)523     public abstract boolean isReferenceParameter(String localName);
524 
525     /**
526      * Returns WsaTubeHelper for the WS-Addressing version identified by <code>binding</code>
527      * {@link WSBinding} and for the {@link WSDLPort} port.
528      *
529      * @return WS-A version specific helper
530      *
531      * @deprecated
532      *     TODO  why are we exposing implementation specificc class through api?
533      *     TODO  Remove it if no one elase uses it.
534      */
getWsaHelper(WSDLPort wsdlPort, SEIModel seiModel, WSBinding binding)535     public abstract WsaTubeHelper getWsaHelper(WSDLPort wsdlPort, SEIModel seiModel, WSBinding binding);
536 
537     /**
538      * Gets the none URI value associated with this WS-Addressing version.
539      *
540      * @return none URI value
541      * @deprecated
542      *      Use {@link #noneUri}.
543      */
getNoneUri()544     public final String getNoneUri() {
545         return noneUri;
546     }
547 
548     /**
549      * Gets the anonymous URI value associated with this WS-Addressing version.
550      *
551      * @deprecated
552      *      Use {@link #anonymousUri}
553      */
getAnonymousUri()554     public final String getAnonymousUri() {
555         return anonymousUri;
556     }
557 
558     /**
559      * Gets the default fault Action value associated with this WS-Addressing version.
560      *
561      * @return default fault Action value
562      */
getDefaultFaultAction()563     public String getDefaultFaultAction() {
564         return nsUri + "/fault";
565     }
566 
567     /**
568      * Gets the local name of the fault when a header representing a WS-Addressing Message
569      * Addresing Property is absent.
570      *
571      * @return local name
572      */
getMapRequiredLocalName()573     /* package */ abstract String getMapRequiredLocalName();
574 
575     /**
576      * Gets the description text when a required WS-Addressing header representing a
577      * Message Addressing Property is absent.
578      *
579      * @return description text
580      */
getMapRequiredText()581     public abstract String getMapRequiredText();
582 
583     /**
584          * Gets the local name of the fault when a header representing anaddress is invalid.
585          * @return local name
586          */
getInvalidAddressLocalName()587     /* package */ abstract String getInvalidAddressLocalName();
588 
589 
590     /**
591      * Gets the local name of the fault when a header representing a WS-Addressing Message
592      * Addresing Property is invalid and cannot be processed.
593      *
594      * @return local name
595      */
getInvalidMapLocalName()596     /* package */ abstract String getInvalidMapLocalName();
597 
598     /**
599      * Gets the description text when a header representing a WS-Addressing
600      * Message Addressing Property is invalid and cannot be processed.
601      *
602      * @return description text
603      */
getInvalidMapText()604     public abstract String getInvalidMapText();
605 
606     /**
607      * Gets the local name of the fault when a header representing a WS-Addressing Message
608      * Addresing Property occurs greater than expected number.
609      *
610      * @return local name
611      */
getInvalidCardinalityLocalName()612     /* package */ abstract String getInvalidCardinalityLocalName();
613 
getWsdlAnonymousLocalName()614     /* package */ abstract String getWsdlAnonymousLocalName();
615 
getPrefix()616     public abstract String getPrefix();
617 
getWsdlPrefix()618     public abstract String getWsdlPrefix();
619 
getFeatureClass()620     public abstract Class<? extends WebServiceFeature> getFeatureClass();
621     /**
622      * Creates an outbound {@link Header} from a reference parameter.
623      */
createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName)624     /*package*/ abstract Header createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName);
625 
626     /**
627      * Gets the local name for wsa:IsReferenceParameter. This method will return a valid
628      * value only valid for W3C WS-Addressing. For Member Submission WS-Addressing, this method
629      * returns null.
630      */
getIsReferenceParameterLocalName()631     /*package*/ abstract String getIsReferenceParameterLocalName();
632 
fromFeature(WebServiceFeature af)633     public static AddressingVersion fromFeature(WebServiceFeature af) {
634         if (af.getID().equals(AddressingFeature.ID))
635             return W3C;
636         else if (af.getID().equals(MemberSubmissionAddressingFeature.ID))
637             return MEMBER;
638         else
639             return null;
640     }
641 
642     /**
643      * Gets the {@link WebServiceFeature} corresponding to the namespace URI of
644      * WS-Addressing policy assertion in the WSDL. <code>enabled</code> and
645      * <code>required</code> are used to initialize the value of the feature.
646      *
647      * @param nsUri namespace URI of the WS-Addressing policy assertion in the WSDL
648      * @param enabled true if feature is to be enabled, false otherwise
649      * @param required true if feature is required, false otherwise. Corresponds
650      *          to wsdl:required on the extension/assertion.
651      * @return WebServiceFeature corresponding to the assertion namespace URI
652      * @throws WebServiceException if an unsupported namespace URI is passed
653      */
getFeature(String nsUri, boolean enabled, boolean required)654     public static @NotNull WebServiceFeature getFeature(String nsUri, boolean enabled, boolean required) {
655         if (nsUri.equals(W3C.policyNsUri))
656             return new AddressingFeature(enabled, required);
657         else if (nsUri.equals(MEMBER.policyNsUri))
658             return new MemberSubmissionAddressingFeature(enabled, required);
659         else
660             throw new WebServiceException("Unsupported namespace URI: " + nsUri);
661     }
662 
663     /**
664      * Gets the corresponding {@link AddressingVersion} instance from the
665      * EPR class.
666      */
fromSpecClass(Class<? extends EndpointReference> eprClass)667     public static @NotNull AddressingVersion fromSpecClass(Class<? extends EndpointReference> eprClass) {
668         if(eprClass==W3CEndpointReference.class)
669             return W3C;
670         if(eprClass==MemberSubmissionEndpointReference.class)
671             return MEMBER;
672         throw new WebServiceException("Unsupported EPR type: "+eprClass);
673     }
674 
675     /**
676      * Returns true if the WebServiceFeature is either a {@link AddressingFeature} or
677      * {@link MemberSubmissionAddressingFeature} and is required.
678      *
679      * @param wsf The WebServiceFeature encaps
680      * @throws WebServiceException if <code>wsf</code> does not contain either {@link AddressingFeature} or
681      * {@link MemberSubmissionAddressingFeature}
682      * @return true if <code>wsf</code> requires WS-Addressing
683      */
isRequired(WebServiceFeature wsf)684     public static boolean isRequired(WebServiceFeature wsf) {
685         if (wsf.getID().equals(AddressingFeature.ID)) {
686             return ((AddressingFeature)wsf).isRequired();
687         } else if (wsf.getID().equals(MemberSubmissionAddressingFeature.ID)) {
688             return ((MemberSubmissionAddressingFeature)wsf).isRequired();
689         } else
690             throw new WebServiceException("WebServiceFeature not an Addressing feature: "+ wsf.getID());
691     }
692 
693     /**
694      * Returns true if <code>binding</code> contains either a {@link AddressingFeature} or
695      * {@link MemberSubmissionAddressingFeature} and is required.
696      *
697      * @param binding The binding
698      * @return true if <code>binding</code> requires WS-Addressing
699      */
isRequired(WSBinding binding)700     public static boolean isRequired(WSBinding binding) {
701         AddressingFeature af = binding.getFeature(AddressingFeature.class);
702         if (af != null)
703             return af.isRequired();
704         MemberSubmissionAddressingFeature msaf = binding.getFeature(MemberSubmissionAddressingFeature.class);
705         if(msaf != null)
706             return msaf.isRequired();
707 
708         return false;
709     }
710 
711     /**
712      * Returns true if <code>binding</code> contains either a {@link AddressingFeature} or
713      * {@link MemberSubmissionAddressingFeature} and is enabled.
714      *
715      * @param binding The binding
716      * @return true if WS-Addressing is enabled for <code>binding</code>.
717      */
isEnabled(WSBinding binding)718     public static boolean isEnabled(WSBinding binding) {
719         return binding.isFeatureEnabled(MemberSubmissionAddressingFeature.class) ||
720                 binding.isFeatureEnabled(AddressingFeature.class);
721     }
722 
723     public final static class EPR {
724         public final Class<? extends EndpointReference> eprClass;
725         public final String address;
726         public final String serviceName;
727         public final String portName;
728         public final String portTypeName;
729         public final String referenceParameters;
730         /**
731          * Element under which metadata is specified.
732          * In W3C, it is wsa:Metadata
733          * In Member, it is directly under mex:MetadataSection
734          */
735         public final QName wsdlMetadata;
736         public final String referenceProperties;
737 
EPR(Class<? extends EndpointReference> eprClass, String address, String serviceName, String portName, String portTypeName, QName wsdlMetadata, String referenceParameters, String referenceProperties)738         public EPR(Class<? extends EndpointReference> eprClass, String address, String serviceName, String portName,
739                     String portTypeName, QName wsdlMetadata,
740                     String referenceParameters, String referenceProperties) {
741             this.eprClass = eprClass;
742             this.address = address;
743             this.serviceName = serviceName;
744             this.portName = portName;
745             this.portTypeName = portTypeName;
746             this.referenceParameters = referenceParameters;
747             this.referenceProperties = referenceProperties;
748             this.wsdlMetadata = wsdlMetadata;
749 
750         }
751     }
752 
753 }
754