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