View Javadoc
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  
75          /* package */  String getActionMismatchLocalName() {
76              return "ActionMismatch";
77          }
78          @Override
79          public boolean isReferenceParameter(String localName) {
80              return localName.equals("ReferenceParameters");
81          }
82  
83          @Override
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
89          /* package */ String getMapRequiredLocalName() {
90              return "MessageAddressingHeaderRequired";
91          }
92  
93          @Override
94          public String getMapRequiredText() {
95              return "A required header representing a Message Addressing Property is not present";
96          }
97  
98          /* package */ String getInvalidAddressLocalName() {
99              return "InvalidAddress";
100         }
101 
102         @Override
103         /* package */ String getInvalidMapLocalName() {
104             return "InvalidAddressingHeader";
105         }
106 
107         @Override
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
113         /* package */ String getInvalidCardinalityLocalName() {
114             return "InvalidCardinality";
115         }
116 
117         /*package*/ Header createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName) {
118             return new OutboundReferenceParameterHeader(mark,nsUri,localName);
119         }
120 
121         /*package*/ String getIsReferenceParameterLocalName() {
122             return "IsReferenceParameter";
123         }
124 
125         /* package */ String getWsdlAnonymousLocalName() {
126             return "Anonymous";
127         }
128 
129         public String getPrefix() {
130             return "wsa";
131         }
132 
133         public String getWsdlPrefix() {
134             return "wsaw";
135         }
136 
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")) {
156         /* package */  String getActionMismatchLocalName() {
157             return "InvalidMessageInformationHeader";
158         }
159         @Override
160         public boolean isReferenceParameter(String localName) {
161             return localName.equals("ReferenceParameters") || localName.equals("ReferenceProperties");
162         }
163 
164         @Override
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
170         /* package */ String getMapRequiredLocalName() {
171             return "MessageInformationHeaderRequired";
172         }
173 
174         @Override
175         public String getMapRequiredText() {
176             return "A required message information header, To, MessageID, or Action, is not present.";
177         }
178 
179         /* package */ String getInvalidAddressLocalName() {
180             return getInvalidMapLocalName();
181         }
182 
183         @Override
184         /* package */ String getInvalidMapLocalName() {
185             return "InvalidMessageInformationHeader";
186         }
187 
188         @Override
189         public String getInvalidMapText() {
190             return "A message information header is not valid and the message cannot be processed.";
191         }
192 
193         @Override
194         /* package */ String getInvalidCardinalityLocalName() {
195             return getInvalidMapLocalName();
196         }
197 
198         /*package*/ Header createReferenceParameterHeader(XMLStreamBuffer mark, String nsUri, String localName) {
199             return new OutboundStreamHeader(mark,nsUri,localName);
200         }
201 
202         /*package*/ String getIsReferenceParameterLocalName() {
203             return "";
204         }
205 
206         /* package */ String getWsdlAnonymousLocalName() {
207             return "";
208         }
209 
210         public String getPrefix() {
211             return "wsa";
212         }
213 
214         public String getWsdlPrefix() {
215             return "wsaw";
216         }
217 
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 
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      */
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      */
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
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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          */
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      */
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      */
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      */
612     /* package */ abstract String getInvalidCardinalityLocalName();
613 
614     /* package */ abstract String getWsdlAnonymousLocalName();
615 
616     public abstract String getPrefix();
617 
618     public abstract String getWsdlPrefix();
619 
620     public abstract Class<? extends WebServiceFeature> getFeatureClass();
621     /**
622      * Creates an outbound {@link Header} from a reference parameter.
623      */
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      */
631     /*package*/ abstract String getIsReferenceParameterLocalName();
632 
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      */
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      */
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      */
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      */
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      */
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 
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 }