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.server;
  27 
  28 import com.sun.istack.internal.NotNull;
  29 import com.sun.istack.internal.Nullable;
  30 import com.sun.xml.internal.ws.api.BindingID;
  31 import com.sun.xml.internal.ws.api.Component;
  32 import com.sun.xml.internal.ws.api.ComponentRegistry;
  33 import com.sun.xml.internal.ws.api.SOAPVersion;
  34 import com.sun.xml.internal.ws.api.WSBinding;
  35 import com.sun.xml.internal.ws.api.config.management.EndpointCreationAttributes;
  36 import com.sun.xml.internal.ws.api.config.management.ManagedEndpointFactory;
  37 import com.sun.xml.internal.ws.api.databinding.MetadataReader;
  38 import com.sun.xml.internal.ws.api.message.Message;
  39 import com.sun.xml.internal.ws.api.message.Packet;
  40 import com.sun.xml.internal.ws.api.model.SEIModel;
  41 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
  42 import com.sun.xml.internal.ws.api.pipe.Codec;
  43 import com.sun.xml.internal.ws.api.pipe.Engine;
  44 import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptor;
  45 import com.sun.xml.internal.ws.api.pipe.ServerTubeAssemblerContext;
  46 import com.sun.xml.internal.ws.api.pipe.ThrowableContainerPropertySet;
  47 import com.sun.xml.internal.ws.api.pipe.Tube;
  48 import com.sun.xml.internal.ws.policy.PolicyMap;
  49 import com.sun.xml.internal.ws.server.EndpointAwareTube;
  50 import com.sun.xml.internal.ws.server.EndpointFactory;
  51 import com.sun.xml.internal.ws.util.ServiceFinder;
  52 import com.sun.xml.internal.ws.util.xml.XmlUtil;
  53 import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
  54 import com.sun.org.glassfish.gmbal.ManagedObjectManager;
  55 import org.xml.sax.EntityResolver;
  56 import org.w3c.dom.Element;
  57 
  58 import javax.xml.namespace.QName;
  59 import javax.xml.ws.Binding;
  60 import javax.xml.ws.EndpointReference;
  61 import javax.xml.ws.WebServiceContext;
  62 import javax.xml.ws.WebServiceException;
  63 
  64 import java.net.URL;
  65 import java.util.Collection;
  66 import java.util.Collections;
  67 import java.util.Iterator;
  68 import java.util.List;
  69 import java.util.Set;
  70 import java.util.concurrent.Executor;
  71 
  72 /**
  73  * Root object that hosts the {@link Packet} processing code
  74  * at the server.
  75  *
  76  * <p>
  77  * One instance of {@link WSEndpoint} is created for each deployed service
  78  * endpoint. A hosted service usually handles multiple concurrent
  79  * requests. To do this efficiently, an endpoint handles incoming
  80  * {@link Packet} through {@link PipeHead}s, where many copies can be created
  81  * for each endpoint.
  82  *
  83  * <p>
  84  * Each {@link PipeHead} is thread-unsafe, and request needs to be
  85  * serialized. A {@link PipeHead} represents a sizable resource
  86  * (in particular a whole pipeline), so the caller is expected to
  87  * reuse them and avoid excessive allocations as much as possible.
  88  * Making {@link PipeHead}s thread-unsafe allow the JAX-WS RI internal to
  89  * tie thread-local resources to {@link PipeHead}, and reduce the total
  90  * resource management overhead.
  91  *
  92  * <p>
  93  * To abbreviate this resource management (and for a few other reasons),
  94  * JAX-WS RI provides {@link Adapter} class. If you are hosting a JAX-WS
  95  * service, you'll most likely want to send requests to {@link WSEndpoint}
  96  * through {@link Adapter}.
  97  *
  98  * <p>
  99  * {@link WSEndpoint} is ready to handle {@link Packet}s as soon as
 100  * it's created. No separate post-initialization step is necessary.
 101  * However, to comply with the JAX-WS spec requirement, the caller
 102  * is expected to call the {@link #dispose()} method to allow an
 103  * orderly shut-down of a hosted service.
 104  *
 105  *
 106  *
 107  * <h3>Objects Exposed From Endpoint</h3>
 108  * <p>
 109  * {@link WSEndpoint} exposes a series of information that represents
 110  * how an endpoint is configured to host a service. See the getXXX methods
 111  * for more details.
 112  *
 113  *
 114  *
 115  * <h3>Implementation Notes</h3>
 116  * <p>
 117  * {@link WSEndpoint} owns a {@link WSWebServiceContext} implementation.
 118  * But a bulk of the work is delegated to {@link WebServiceContextDelegate},
 119  * which is passed in as a parameter to {@link PipeHead#process(Packet, WebServiceContextDelegate, TransportBackChannel)}.
 120  *
 121  * @author Kohsuke Kawaguchi
 122  */
 123 public abstract class WSEndpoint<T> implements ComponentRegistry {
 124 
 125     /**
 126      * Gets the Endpoint's codec that is used to encode/decode {@link Message}s. This is a
 127      * copy of the master codec and it shouldn't be shared across two requests running
 128      * concurrently(unless it is stateless).
 129      *
 130      * @return codec to encode/decode
 131      */
 132     public abstract @NotNull Codec createCodec();
 133 
 134     /**
 135      * Gets the application endpoint's serviceName. It could be got from DD or annotations
 136      *
 137      * @return same as wsdl:service QName if WSDL exists or generated
 138      */
 139     public abstract @NotNull QName getServiceName();
 140 
 141     /**
 142      * Gets the application endpoint's portName. It could be got from DD or annotations
 143      *
 144      * @return same as wsdl:port QName if WSDL exists or generated
 145      */
 146     public abstract @NotNull QName getPortName();
 147 
 148     /**
 149      * Gets the application endpoint {@link Class} that eventually serves the request.
 150      *
 151      * <p>
 152      * This is the same value given to the {@link #create} method.
 153      */
 154     public abstract @NotNull Class<T> getImplementationClass();
 155 
 156     /**
 157      * Represents the binding for which this {@link WSEndpoint}
 158      * is created for.
 159      *
 160      * @return
 161      *      always same object.
 162      */
 163     public abstract @NotNull WSBinding getBinding();
 164 
 165     /**
 166      * Gets the {@link Container} object.
 167      *
 168      * <p>
 169      * The components inside {@link WSEndpoint} uses this reference
 170      * to communicate with the hosting environment.
 171      *
 172      * @return
 173      *      always same object. If no "real" {@link Container} instance
 174      *      is given, {@link Container#NONE} will be returned.
 175      */
 176     public abstract @NotNull Container getContainer();
 177 
 178     /**
 179      * Gets the port that this endpoint is serving.
 180      *
 181      * <p>
 182      * A service is not required to have a WSDL, and when it doesn't,
 183      * this method returns null. Otherwise it returns an object that
 184      * describes the port that this {@link WSEndpoint} is serving.
 185      *
 186      * @return
 187      *      Possibly null, but always the same value.
 188      */
 189     public abstract @Nullable WSDLPort getPort();
 190 
 191     /**
 192      * Set this {@link Executor} to run asynchronous requests using this executor.
 193      * This executor is set on {@link Engine} and must be set before
 194      * calling {@link #schedule(Packet,CompletionCallback) } and
 195      * {@link #schedule(Packet,CompletionCallback,FiberContextSwitchInterceptor)} methods.
 196      *
 197      * @param exec Executor to run async requests
 198      */
 199     public abstract void setExecutor(@NotNull Executor exec);
 200 
 201     /**
 202      * This method takes a {@link Packet} that represents
 203      * a request, run it through a {@link Tube}line, eventually
 204      * pass it to the user implementation code, which produces
 205      * a reply, then run that through the tubeline again,
 206      * and eventually return it as a return value through {@link CompletionCallback}.
 207      *
 208      * <p>
 209      * This takes care of pooling of {@link Tube}lines and reuses
 210      * tubeline for requests. Same instance of tubeline is not used concurrently
 211      * for two requests.
 212      *
 213      * <p>
 214      * If the transport is capable of asynchronous execution, use this
 215      * instead of using {@link PipeHead#process}.
 216      *
 217      * <p>
 218      * Before calling this method, set the executor using {@link #setExecutor}. The
 219      * executor may used multiple times to run this request in a asynchronous fashion.
 220      * The calling thread will be returned immediately, and the callback will be
 221      * called in a different a thread.
 222      *
 223      * <p>
 224      * {@link Packet#transportBackChannel} should have the correct value, so that
 225      * one-way message processing happens correctly. {@link Packet#webServiceContextDelegate}
 226      * should have the correct value, so that some {@link WebServiceContext} methods correctly.
 227      *
 228      * @see Packet#transportBackChannel
 229      * @see Packet#webServiceContextDelegate
 230      *
 231      * @param request web service request
 232      * @param callback callback to get response packet
 233      */
 234     public final void schedule(@NotNull Packet request, @NotNull CompletionCallback callback ) {
 235         schedule(request,callback,null);
 236     }
 237 
 238     /**
 239      * Schedule invocation of web service asynchronously.
 240      *
 241      * @see #schedule(Packet, CompletionCallback)
 242      *
 243      * @param request web service request
 244      * @param callback callback to get response packet(exception if there is one)
 245      * @param interceptor caller's interceptor to impose a context of execution
 246      */
 247     public abstract void schedule(@NotNull Packet request, @NotNull CompletionCallback callback, @Nullable FiberContextSwitchInterceptor interceptor );
 248 
 249     public void process(@NotNull Packet request, @NotNull CompletionCallback callback, @Nullable FiberContextSwitchInterceptor interceptor ) {
 250        schedule(request,callback,interceptor);
 251     }
 252 
 253     /**
 254      * Returns {@link Engine} for this endpoint
 255      * @return Engine
 256      */
 257     public Engine getEngine() {
 258         throw new UnsupportedOperationException();
 259     }
 260 
 261     /**
 262      * Callback to notify that jax-ws runtime has finished execution of a request
 263      * submitted via schedule().
 264      */
 265     public interface CompletionCallback {
 266         /**
 267          * Indicates that the jax-ws runtime has finished execution of a request
 268          * submitted via schedule().
 269          *
 270          * <p>
 271          * Since the JAX-WS RI runs asynchronously,
 272          * this method maybe invoked by a different thread
 273          * than any of the threads that started it or run a part of tubeline.
 274          *
 275          * @param response {@link Packet}
 276          */
 277         void onCompletion(@NotNull Packet response);
 278     }
 279 
 280     /**
 281      * Creates a new {@link PipeHead} to process
 282      * incoming requests.
 283      *
 284      * <p>
 285      * This is not a cheap operation. The caller is expected
 286      * to reuse the returned {@link PipeHead}. See
 287      * {@link WSEndpoint class javadoc} for details.
 288      *
 289      * @return
 290      *      A newly created {@link PipeHead} that's ready to serve.
 291      */
 292     public abstract @NotNull PipeHead createPipeHead();
 293 
 294     /**
 295      * Represents a resource local to a thread.
 296      *
 297      * See {@link WSEndpoint} class javadoc for more discussion about
 298      * this.
 299      */
 300     public interface PipeHead {
 301         /**
 302          * Processes a request and produces a reply.
 303          *
 304          * <p>
 305          * This method takes a {@link Packet} that represents
 306          * a request, run it through a {@link Tube}line, eventually
 307          * pass it to the user implementation code, which produces
 308          * a reply, then run that through the pipeline again,
 309          * and eventually return it as a return value.
 310          *
 311          * @param request
 312          *      Unconsumed {@link Packet} that represents
 313          *      a request.
 314          * @param wscd
 315          *      {@link WebServiceContextDelegate} to be set to {@link Packet}.
 316          *      (we didn't have to take this and instead just ask the caller to
 317          *      set to {@link Packet#webServiceContextDelegate}, but that felt
 318          *      too error prone.)
 319          * @param tbc
 320          *      {@link TransportBackChannel} to be set to {@link Packet}.
 321          *      See the {@code wscd} parameter javadoc for why this is a parameter.
 322          *      Can be null.
 323          * @return
 324          *      Unconsumed {@link Packet} that represents
 325          *      a reply to the request.
 326          *
 327          * @throws WebServiceException
 328          *      This method <b>does not</b> throw a {@link WebServiceException}.
 329          *      The {@link WSEndpoint} must always produce a fault {@link Message}
 330          *      for it.
 331          *
 332          * @throws RuntimeException
 333          *      A {@link RuntimeException} thrown from this method, including
 334          *      {@link WebServiceException}, must be treated as a bug in the
 335          *      code (including JAX-WS and all the pipe implementations), not
 336          *      an operator error by the user.
 337          *
 338          *      <p>
 339          *      Therefore, it should be recorded by the caller in a way that
 340          *      allows developers to fix a bug.
 341          */
 342         @NotNull Packet process(
 343             @NotNull Packet request, @Nullable WebServiceContextDelegate wscd, @Nullable TransportBackChannel tbc);
 344     }
 345 
 346     /**
 347      * Indicates that the {@link WSEndpoint} is about to be turned off,
 348      * and will no longer serve any packet anymore.
 349      *
 350      * <p>
 351      * This method needs to be invoked for the JAX-WS RI to correctly
 352      * implement some of the spec semantics (TODO: pointer.)
 353      * It's the responsibility of the code that hosts a {@link WSEndpoint}
 354      * to invoke this method.
 355      *
 356      * <p>
 357      * Once this method is called, the behavior is undefed for
 358      * all in-progress {@link PipeHead#process} methods (by other threads)
 359      * and future {@link PipeHead#process} method invocations.
 360      */
 361     public abstract void dispose();
 362 
 363     /**
 364      * Gets the description of the service.
 365      *
 366      * <p>
 367      * A description is a set of WSDL/schema and other documents that together
 368      * describes a service.
 369      * A service is not required to have a description, and when it doesn't,
 370      * this method returns null.
 371      *
 372      * @return
 373      *      Possibly null, always the same value under ordinary circumstances but
 374      *      may change if the endpoint is managed.
 375      */
 376     public abstract @Nullable ServiceDefinition getServiceDefinition();
 377 
 378     /**
 379      * Gets the list of {@link BoundEndpoint} that are associated
 380      * with this endpoint.
 381      *
 382      * @return
 383      *      always return the same set.
 384      */
 385     public List<BoundEndpoint> getBoundEndpoints() {
 386         Module m = getContainer().getSPI(Module.class);
 387         return m != null ? m.getBoundEndpoints() : null;
 388     }
 389 
 390     /**
 391      * Gets the list of {@link EndpointComponent} that are associated
 392      * with this endpoint.
 393      *
 394      * <p>
 395      * Components (such as codec, tube, handler, etc) who wish to provide
 396      * some service to other components in the endpoint can iterate the
 397      * registry and call its {@link EndpointComponent#getSPI(Class)} to
 398      * establish a private contract between components.
 399      * <p>
 400      * Components who wish to subscribe to such a service can add itself
 401      * to this set.
 402      *
 403      * @return
 404      *      always return the same set.
 405      * @deprecated
 406      */
 407     public abstract @NotNull Set<EndpointComponent> getComponentRegistry();
 408 
 409         public @NotNull Set<Component> getComponents() {
 410         return Collections.emptySet();
 411     }
 412 
 413         public @Nullable <S> S getSPI(@NotNull Class<S> spiType) {
 414                 Set<Component> componentRegistry = getComponents();
 415                 if (componentRegistry != null) {
 416                         for (Component c : componentRegistry) {
 417                                 S s = c.getSPI(spiType);
 418                                 if (s != null)
 419                                         return s;
 420                         }
 421                 }
 422                 return getContainer().getSPI(spiType);
 423         }
 424 
 425     /**
 426      * Gets the {@link com.sun.xml.internal.ws.api.model.SEIModel} that represents the relationship
 427      * between WSDL and Java SEI.
 428      *
 429      * <p>
 430      * This method returns a non-null value if and only if this
 431      * endpoint is ultimately serving an application through an SEI.
 432      *
 433      * @return
 434      *      maybe null. See above for more discussion.
 435      *      Always the same value.
 436      */
 437     public abstract @Nullable SEIModel getSEIModel();
 438 
 439     /**
 440      * Gives the PolicMap that captures the Policy for the endpoint
 441      *
 442      * @return PolicyMap
 443      *
 444      * @deprecated
 445      * Do not use this method as the PolicyMap API is not final yet and might change in next few months.
 446      */
 447     public abstract PolicyMap getPolicyMap();
 448 
 449     /**
 450      * Get the ManagedObjectManager for this endpoint.
 451      */
 452     public abstract @NotNull ManagedObjectManager getManagedObjectManager();
 453 
 454     /**
 455      * Close the ManagedObjectManager for this endpoint.
 456      * This is used by the Web Service Configuration Management system so that it
 457      * closes the MOM before it creates a new WSEndpoint.  Then it calls dispose
 458      * on the existing endpoint and then installs the new endpoint.
 459      * The call to dispose also calls closeManagedObjectManager, but is a noop
 460      * if that method has already been called.
 461      */
 462     public abstract void closeManagedObjectManager();
 463 
 464     /**
 465      * This is only needed to expose info for monitoring.
 466      */
 467     public abstract @NotNull ServerTubeAssemblerContext getAssemblerContext();
 468 
 469     /**
 470      * Creates an endpoint from deployment or programmatic configuration
 471      *
 472      * <p>
 473      * This method works like the following:
 474      * <ol>
 475      * <li>{@link ServiceDefinition} is modeleed from the given SEI type.
 476      * <li>{@link Invoker} that always serves <tt>implementationObject</tt> will be used.
 477      * </ol>
 478      * @param implType
 479      *      Endpoint class(not SEI). Enpoint class must have @WebService or @WebServiceProvider
 480      *      annotation.
 481      * @param processHandlerAnnotation
 482      *      Flag to control processing of @HandlerChain on Impl class
 483      *      if true, processes @HandlerChain on Impl
 484      *      if false, DD might have set HandlerChain no need to parse.
 485      * @param invoker
 486      *      Pass an object to invoke the actual endpoint object. If it is null, a default
 487      *      invoker is created using {@link InstanceResolver#createDefault}. Appservers
 488      *      could create its own invoker to do additional functions like transactions,
 489      *      invoking the endpoint through proxy etc.
 490      * @param serviceName
 491      *      Optional service name(may be from DD) to override the one given by the
 492      *      implementation class. If it is null, it will be derived from annotations.
 493      * @param portName
 494      *      Optional port name(may be from DD) to override the one given by the
 495      *      implementation class. If it is null, it will be derived from annotations.
 496      * @param container
 497      *      Allows technologies that are built on top of JAX-WS(such as WSIT) needs to
 498      *      negotiate private contracts between them and the container
 499      * @param binding
 500      *      JAX-WS implementation of {@link Binding}. This object can be created by
 501      *      {@link BindingID#createBinding()}. Usually the binding can be got from
 502      *      DD, {@link javax.xml.ws.BindingType}.
 503      *
 504      *
 505      * TODO: DD has a configuration for MTOM threshold.
 506      * Maybe we need something more generic so that other technologies
 507      * like Tango can get information from DD.
 508      *
 509      * TODO: does it really make sense for this to take EntityResolver?
 510      * Given that all metadata has to be given as a list anyway.
 511      *
 512      * @param primaryWsdl
 513      *      The {@link ServiceDefinition#getPrimary() primary} WSDL.
 514      *      If null, it'll be generated based on the SEI (if this is an SEI)
 515      *      or no WSDL is associated (if it's a provider.)
 516      *      TODO: shouldn't the implementation find this from the metadata list?
 517      * @param metadata
 518      *      Other documents that become {@link SDDocument}s. Can be null.
 519      * @param resolver
 520      *      Optional resolver used to de-reference resources referenced from
 521      *      WSDL. Must be null if the {@code url} is null.
 522      * @param isTransportSynchronous
 523      *      If the caller knows that the returned {@link WSEndpoint} is going to be
 524      *      used by a synchronous-only transport, then it may pass in <tt>true</tt>
 525      *      to allow the callee to perform an optimization based on that knowledge
 526      *      (since often synchronous version is cheaper than an asynchronous version.)
 527      *      This value is visible from {@link ServerTubeAssemblerContext#isSynchronous()}.
 528      *
 529      * @return newly constructed {@link WSEndpoint}.
 530      * @throws WebServiceException
 531      *      if the endpoint set up fails.
 532      */
 533     public static <T> WSEndpoint<T> create(
 534             @NotNull Class<T> implType,
 535             boolean processHandlerAnnotation,
 536             @Nullable Invoker invoker,
 537             @Nullable QName serviceName,
 538             @Nullable QName portName,
 539             @Nullable Container container,
 540             @Nullable WSBinding binding,
 541             @Nullable SDDocumentSource primaryWsdl,
 542             @Nullable Collection<? extends SDDocumentSource> metadata,
 543             @Nullable EntityResolver resolver,
 544             boolean isTransportSynchronous) {
 545         return create(implType, processHandlerAnnotation, invoker, serviceName, portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, true);
 546     }
 547 
 548     public static <T> WSEndpoint<T> create(
 549         @NotNull Class<T> implType,
 550         boolean processHandlerAnnotation,
 551         @Nullable Invoker invoker,
 552         @Nullable QName serviceName,
 553         @Nullable QName portName,
 554         @Nullable Container container,
 555         @Nullable WSBinding binding,
 556         @Nullable SDDocumentSource primaryWsdl,
 557         @Nullable Collection<? extends SDDocumentSource> metadata,
 558         @Nullable EntityResolver resolver,
 559         boolean isTransportSynchronous,
 560         boolean isStandard)
 561     {
 562         final WSEndpoint<T> endpoint =
 563             EndpointFactory.createEndpoint(
 564                 implType,processHandlerAnnotation, invoker,serviceName,portName,container,binding,primaryWsdl,metadata,resolver,isTransportSynchronous,isStandard);
 565 
 566         final Iterator<ManagedEndpointFactory> managementFactories = ServiceFinder.find(ManagedEndpointFactory.class).iterator();
 567         if (managementFactories.hasNext()) {
 568             final ManagedEndpointFactory managementFactory = managementFactories.next();
 569             final EndpointCreationAttributes attributes = new EndpointCreationAttributes(
 570                     processHandlerAnnotation, invoker, resolver, isTransportSynchronous);
 571 
 572             WSEndpoint<T> managedEndpoint = managementFactory.createEndpoint(endpoint, attributes);
 573 
 574             if (endpoint.getAssemblerContext().getTerminalTube() instanceof EndpointAwareTube) {
 575                 ((EndpointAwareTube)endpoint.getAssemblerContext().getTerminalTube()).setEndpoint(managedEndpoint);
 576             }
 577 
 578             return managedEndpoint;
 579         }
 580 
 581 
 582         return endpoint;
 583     }
 584 
 585     /**
 586      * Deprecated version that assumes <tt>isTransportSynchronous==false</tt>
 587      */
 588     @Deprecated
 589     public static <T> WSEndpoint<T> create(
 590         @NotNull Class<T> implType,
 591         boolean processHandlerAnnotation,
 592         @Nullable Invoker invoker,
 593         @Nullable QName serviceName,
 594         @Nullable QName portName,
 595         @Nullable Container container,
 596         @Nullable WSBinding binding,
 597         @Nullable SDDocumentSource primaryWsdl,
 598         @Nullable Collection<? extends SDDocumentSource> metadata,
 599         @Nullable EntityResolver resolver) {
 600         return create(implType,processHandlerAnnotation,invoker,serviceName,portName,container,binding,primaryWsdl,metadata,resolver,false);
 601     }
 602 
 603 
 604     /**
 605      * The same as
 606      * {@link #create(Class, boolean, Invoker, QName, QName, Container, WSBinding, SDDocumentSource, Collection, EntityResolver)}
 607      * except that this version takes an url of the <tt>jax-ws-catalog.xml</tt>.
 608      *
 609      * @param catalogUrl
 610      *      if not null, an {@link EntityResolver} is created from it and used.
 611      *      otherwise no resolution will be performed.
 612      */
 613     public static <T> WSEndpoint<T> create(
 614         @NotNull Class<T> implType,
 615         boolean processHandlerAnnotation,
 616         @Nullable Invoker invoker,
 617         @Nullable QName serviceName,
 618         @Nullable QName portName,
 619         @Nullable Container container,
 620         @Nullable WSBinding binding,
 621         @Nullable SDDocumentSource primaryWsdl,
 622         @Nullable Collection<? extends SDDocumentSource> metadata,
 623         @Nullable URL catalogUrl) {
 624         return create(
 625             implType,processHandlerAnnotation,invoker,serviceName,portName,container,binding,primaryWsdl,metadata,
 626             XmlUtil.createEntityResolver(catalogUrl),false);
 627     }
 628 
 629     /**
 630      * Gives the wsdl:service default name computed from the endpoint implementaiton class
 631      */
 632     public static @NotNull QName getDefaultServiceName(Class endpointClass){
 633         return getDefaultServiceName(endpointClass, true, null);
 634     }
 635     public static @NotNull QName getDefaultServiceName(Class endpointClass, MetadataReader metadataReader){
 636         return getDefaultServiceName(endpointClass, true, metadataReader);
 637     }
 638 
 639     public static @NotNull QName getDefaultServiceName(Class endpointClass, boolean isStandard){
 640         return getDefaultServiceName(endpointClass, isStandard, null);
 641     }
 642     public static @NotNull QName getDefaultServiceName(Class endpointClass, boolean isStandard, MetadataReader metadataReader){
 643         return EndpointFactory.getDefaultServiceName(endpointClass, isStandard, metadataReader);
 644     }
 645 
 646     /**
 647      * Gives the wsdl:service/wsdl:port default name computed from the endpoint implementaiton class
 648      */
 649     public static @NotNull QName getDefaultPortName(@NotNull QName serviceName, Class endpointClass) {
 650         return getDefaultPortName(serviceName, endpointClass, null);
 651     }
 652     public static @NotNull QName getDefaultPortName(@NotNull QName serviceName, Class endpointClass, MetadataReader metadataReader) {
 653         return getDefaultPortName(serviceName, endpointClass, true, metadataReader);
 654     }
 655 
 656     public static @NotNull QName getDefaultPortName(@NotNull QName serviceName, Class endpointClass, boolean isStandard) {
 657         return getDefaultPortName(serviceName, endpointClass, isStandard, null);
 658     }
 659     public static @NotNull QName getDefaultPortName(@NotNull QName serviceName, Class endpointClass, boolean isStandard, MetadataReader metadataReader){
 660         return EndpointFactory.getDefaultPortName(serviceName, endpointClass, isStandard, metadataReader);
 661     }
 662 
 663     /**
 664      * Return EndpointReference instance, based on passed parameters and spec version represented by clazz
 665      * @param <T>
 666      * @param clazz represents spec version
 667      * @param address   endpoint address
 668      * @param wsdlAddress   wsdl address
 669      * @param referenceParameters   any reference parameters to be added to the instance
 670      * @return EndpointReference instance based on passed parameters and values obtained from current instance
 671      */
 672     public abstract <T extends EndpointReference> T getEndpointReference(Class<T> clazz, String address, String wsdlAddress, Element... referenceParameters);
 673 
 674     /**
 675      *
 676      * @param <T>
 677      * @param clazz
 678      * @param address
 679      * @param wsdlAddress
 680      * @param metadata
 681      * @param referenceParameters
 682      * @return EndpointReference instance based on passed parameters and values obtained from current instance
 683      */
 684     public abstract <T extends EndpointReference> T getEndpointReference(Class<T> clazz,
 685             String address, String wsdlAddress, List<Element> metadata,
 686             List<Element> referenceParameters);
 687 
 688     /**
 689      * Used for managed endpoints infrastructure to compare equality of proxies vs proxied endpoints.
 690      * @param endpoint
 691      * @return true if the proxied endpoint instance held by this instance equals to 'endpoint', otherwise return false.
 692      */
 693     public boolean equalsProxiedInstance(WSEndpoint endpoint) {
 694         if (endpoint == null) return false;
 695         return this.equals(endpoint);
 696     }
 697 
 698     /**
 699      * Nullable when there is no associated WSDL Model
 700      * @return
 701      */
 702     public abstract @Nullable OperationDispatcher getOperationDispatcher();
 703 
 704 
 705     /**
 706      * This is used by WsaServerTube and WSEndpointImpl to create a Packet with SOAPFault message from a Java exception.
 707      */
 708     public abstract Packet createServiceResponseForException(final ThrowableContainerPropertySet tc,
 709                                                              final Packet      responsePacket,
 710                                                              final SOAPVersion soapVersion,
 711                                                              final WSDLPort    wsdlPort,
 712                                                              final SEIModel    seiModel,
 713                                                              final WSBinding   binding);
 714 }