Thu, 31 Aug 2017 15:18:52 +0800
merge
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. Oracle designates this |
aoqi@0 | 8 | * particular file as subject to the "Classpath" exception as provided |
aoqi@0 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
aoqi@0 | 10 | * |
aoqi@0 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 15 | * accompanied this code). |
aoqi@0 | 16 | * |
aoqi@0 | 17 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 20 | * |
aoqi@0 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 22 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 23 | * questions. |
aoqi@0 | 24 | */ |
aoqi@0 | 25 | |
aoqi@0 | 26 | package com.sun.xml.internal.ws.api.pipe; |
aoqi@0 | 27 | |
aoqi@0 | 28 | import com.sun.istack.internal.NotNull; |
aoqi@0 | 29 | import com.sun.istack.internal.Nullable; |
aoqi@0 | 30 | import com.sun.xml.internal.ws.addressing.W3CWsaClientTube; |
aoqi@0 | 31 | import com.sun.xml.internal.ws.addressing.v200408.MemberSubmissionWsaClientTube; |
aoqi@0 | 32 | import com.sun.xml.internal.ws.api.EndpointAddress; |
aoqi@0 | 33 | import com.sun.xml.internal.ws.api.WSBinding; |
aoqi@0 | 34 | import com.sun.xml.internal.ws.api.WSService; |
aoqi@0 | 35 | import com.sun.xml.internal.ws.api.addressing.AddressingVersion; |
aoqi@0 | 36 | import com.sun.xml.internal.ws.api.client.ClientPipelineHook; |
aoqi@0 | 37 | import com.sun.xml.internal.ws.api.client.WSPortInfo; |
aoqi@0 | 38 | import com.sun.xml.internal.ws.api.model.SEIModel; |
aoqi@0 | 39 | import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; |
aoqi@0 | 40 | import com.sun.xml.internal.ws.api.pipe.helper.PipeAdapter; |
aoqi@0 | 41 | import com.sun.xml.internal.ws.api.server.Container; |
aoqi@0 | 42 | import com.sun.xml.internal.ws.binding.BindingImpl; |
aoqi@0 | 43 | import com.sun.xml.internal.ws.client.ClientSchemaValidationTube; |
aoqi@0 | 44 | import com.sun.xml.internal.ws.developer.SchemaValidationFeature; |
aoqi@0 | 45 | import com.sun.xml.internal.ws.developer.WSBindingProvider; |
aoqi@0 | 46 | import com.sun.xml.internal.ws.handler.ClientLogicalHandlerTube; |
aoqi@0 | 47 | import com.sun.xml.internal.ws.handler.ClientMessageHandlerTube; |
aoqi@0 | 48 | import com.sun.xml.internal.ws.handler.ClientSOAPHandlerTube; |
aoqi@0 | 49 | import com.sun.xml.internal.ws.handler.HandlerTube; |
aoqi@0 | 50 | import com.sun.xml.internal.ws.protocol.soap.ClientMUTube; |
aoqi@0 | 51 | import com.sun.xml.internal.ws.transport.DeferredTransportPipe; |
aoqi@0 | 52 | import com.sun.xml.internal.ws.util.pipe.DumpTube; |
aoqi@0 | 53 | |
aoqi@0 | 54 | import javax.xml.ws.soap.SOAPBinding; |
aoqi@0 | 55 | import java.io.PrintStream; |
aoqi@0 | 56 | |
aoqi@0 | 57 | /** |
aoqi@0 | 58 | * Factory for well-known {@link Tube} implementations |
aoqi@0 | 59 | * that the {@link TubelineAssembler} needs to use |
aoqi@0 | 60 | * to satisfy JAX-WS requirements. |
aoqi@0 | 61 | * |
aoqi@0 | 62 | * @author Jitendra Kotamraju |
aoqi@0 | 63 | */ |
aoqi@0 | 64 | public class ClientTubeAssemblerContext { |
aoqi@0 | 65 | |
aoqi@0 | 66 | private final @NotNull EndpointAddress address; |
aoqi@0 | 67 | private final @Nullable WSDLPort wsdlModel; |
aoqi@0 | 68 | private final @Nullable SEIModel seiModel; |
aoqi@0 | 69 | private final @Nullable Class sei; |
aoqi@0 | 70 | private final @NotNull WSService rootOwner; |
aoqi@0 | 71 | private final @NotNull WSBinding binding; |
aoqi@0 | 72 | private final @NotNull Container container; |
aoqi@0 | 73 | private @NotNull Codec codec; |
aoqi@0 | 74 | |
aoqi@0 | 75 | //Nullable only to maintain comaptibility with old constructors of this class. |
aoqi@0 | 76 | private final @Nullable WSBindingProvider bindingProvider; |
aoqi@0 | 77 | |
aoqi@0 | 78 | /** |
aoqi@0 | 79 | * This constructor should be used only by JAX-WS Runtime and is not meant for external consumption. |
aoqi@0 | 80 | * @deprecated |
aoqi@0 | 81 | * Use {@link #ClientTubeAssemblerContext(EndpointAddress, WSDLPort, WSService, WSBindingProvider, WSBinding, Container, Codec, SEIModel, Class)} |
aoqi@0 | 82 | */ |
aoqi@0 | 83 | public ClientTubeAssemblerContext(@NotNull EndpointAddress address, @Nullable WSDLPort wsdlModel, @NotNull WSService rootOwner, @NotNull WSBinding binding) { |
aoqi@0 | 84 | this(address, wsdlModel, rootOwner, binding, Container.NONE); |
aoqi@0 | 85 | } |
aoqi@0 | 86 | |
aoqi@0 | 87 | /** |
aoqi@0 | 88 | * This constructor should be used only by JAX-WS Runtime and is not meant for external consumption. |
aoqi@0 | 89 | * @deprecated |
aoqi@0 | 90 | * Use {@link #ClientTubeAssemblerContext(EndpointAddress, WSDLPort, WSService, WSBindingProvider, WSBinding, Container, Codec, SEIModel, Class)} |
aoqi@0 | 91 | */ |
aoqi@0 | 92 | public ClientTubeAssemblerContext(@NotNull EndpointAddress address, @Nullable WSDLPort wsdlModel, |
aoqi@0 | 93 | @NotNull WSService rootOwner, @NotNull WSBinding binding, |
aoqi@0 | 94 | @NotNull Container container) { |
aoqi@0 | 95 | // WSBinding is actually BindingImpl |
aoqi@0 | 96 | this(address, wsdlModel, rootOwner, binding, container, ((BindingImpl)binding).createCodec() ); |
aoqi@0 | 97 | } |
aoqi@0 | 98 | |
aoqi@0 | 99 | /** |
aoqi@0 | 100 | * This constructor should be used only by JAX-WS Runtime and is not meant for external consumption. |
aoqi@0 | 101 | * @deprecated |
aoqi@0 | 102 | * Use {@link #ClientTubeAssemblerContext(EndpointAddress, WSDLPort, WSService, WSBindingProvider, WSBinding, Container, Codec, SEIModel, Class)} |
aoqi@0 | 103 | */ |
aoqi@0 | 104 | public ClientTubeAssemblerContext(@NotNull EndpointAddress address, @Nullable WSDLPort wsdlModel, |
aoqi@0 | 105 | @NotNull WSService rootOwner, @NotNull WSBinding binding, |
aoqi@0 | 106 | @NotNull Container container, Codec codec) { |
aoqi@0 | 107 | this(address, wsdlModel, rootOwner, binding, container, codec, null, null); |
aoqi@0 | 108 | } |
aoqi@0 | 109 | |
aoqi@0 | 110 | /** |
aoqi@0 | 111 | * This constructor should be used only by JAX-WS Runtime and is not meant for external consumption. |
aoqi@0 | 112 | * @deprecated |
aoqi@0 | 113 | * Use {@link #ClientTubeAssemblerContext(EndpointAddress, WSDLPort, WSService, WSBindingProvider, WSBinding, Container, Codec, SEIModel, Class)} |
aoqi@0 | 114 | */ |
aoqi@0 | 115 | public ClientTubeAssemblerContext(@NotNull EndpointAddress address, @Nullable WSDLPort wsdlModel, |
aoqi@0 | 116 | @NotNull WSService rootOwner, @NotNull WSBinding binding, |
aoqi@0 | 117 | @NotNull Container container, Codec codec, SEIModel seiModel, Class sei) { |
aoqi@0 | 118 | this(address, wsdlModel, rootOwner, null/* no info on which port it is, so pass null*/, binding, container, codec, seiModel, sei); |
aoqi@0 | 119 | } |
aoqi@0 | 120 | |
aoqi@0 | 121 | /** |
aoqi@0 | 122 | * This constructor should be used only by JAX-WS Runtime and is not meant for external consumption. |
aoqi@0 | 123 | * |
aoqi@0 | 124 | * @since JAX-WS 2.2 |
aoqi@0 | 125 | */ |
aoqi@0 | 126 | public ClientTubeAssemblerContext(@NotNull EndpointAddress address, @Nullable WSDLPort wsdlModel, |
aoqi@0 | 127 | @NotNull WSBindingProvider bindingProvider, @NotNull WSBinding binding, |
aoqi@0 | 128 | @NotNull Container container, Codec codec, SEIModel seiModel, Class sei) { |
aoqi@0 | 129 | this(address, wsdlModel, (bindingProvider==null? null: bindingProvider.getPortInfo().getOwner()), bindingProvider, binding, container, codec, seiModel, sei); |
aoqi@0 | 130 | |
aoqi@0 | 131 | } |
aoqi@0 | 132 | |
aoqi@0 | 133 | //common constructor |
aoqi@0 | 134 | //WSService is null, when ClientTubeAssemblerContext is created for sending non-anonymous responses. |
aoqi@0 | 135 | private ClientTubeAssemblerContext(@NotNull EndpointAddress address, @Nullable WSDLPort wsdlModel, |
aoqi@0 | 136 | @Nullable WSService rootOwner, @Nullable WSBindingProvider bindingProvider, @NotNull WSBinding binding, |
aoqi@0 | 137 | @NotNull Container container, Codec codec, SEIModel seiModel, Class sei) { |
aoqi@0 | 138 | this.address = address; |
aoqi@0 | 139 | this.wsdlModel = wsdlModel; |
aoqi@0 | 140 | this.rootOwner = rootOwner; |
aoqi@0 | 141 | this.bindingProvider = bindingProvider; |
aoqi@0 | 142 | this.binding = binding; |
aoqi@0 | 143 | this.container = container; |
aoqi@0 | 144 | this.codec = codec; |
aoqi@0 | 145 | this.seiModel = seiModel; |
aoqi@0 | 146 | this.sei = sei; |
aoqi@0 | 147 | } |
aoqi@0 | 148 | |
aoqi@0 | 149 | /** |
aoqi@0 | 150 | * The endpoint address. Always non-null. This parameter is taken separately |
aoqi@0 | 151 | * from {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLPort} (even though there's {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLPort#getAddress()}) |
aoqi@0 | 152 | * because sometimes WSDL is not available. |
aoqi@0 | 153 | */ |
aoqi@0 | 154 | public @NotNull EndpointAddress getAddress() { |
aoqi@0 | 155 | return address; |
aoqi@0 | 156 | } |
aoqi@0 | 157 | |
aoqi@0 | 158 | /** |
aoqi@0 | 159 | * The created pipeline will be used to serve this port. |
aoqi@0 | 160 | * Null if the service isn't associated with any port definition in WSDL, |
aoqi@0 | 161 | * and otherwise non-null. |
aoqi@0 | 162 | */ |
aoqi@0 | 163 | public @Nullable WSDLPort getWsdlModel() { |
aoqi@0 | 164 | return wsdlModel; |
aoqi@0 | 165 | } |
aoqi@0 | 166 | |
aoqi@0 | 167 | /** |
aoqi@0 | 168 | * The pipeline is created for this {@link com.sun.xml.internal.ws.api.WSService}. |
aoqi@0 | 169 | * Always non-null. (To be precise, the newly created pipeline |
aoqi@0 | 170 | * is owned by a proxy or a dispatch created from thsi {@link com.sun.xml.internal.ws.api.WSService}.) |
aoqi@0 | 171 | */ |
aoqi@0 | 172 | public @NotNull WSService getService() { |
aoqi@0 | 173 | return rootOwner; |
aoqi@0 | 174 | } |
aoqi@0 | 175 | |
aoqi@0 | 176 | /** |
aoqi@0 | 177 | * The pipeline is created for this {@link com.sun.xml.internal.ws.api.client.WSPortInfo}. |
aoqi@0 | 178 | * Nullable incase of backwards compatible usages of this class. |
aoqi@0 | 179 | */ |
aoqi@0 | 180 | public @Nullable WSPortInfo getPortInfo() { |
aoqi@0 | 181 | return bindingProvider == null? null: bindingProvider.getPortInfo(); |
aoqi@0 | 182 | } |
aoqi@0 | 183 | |
aoqi@0 | 184 | |
aoqi@0 | 185 | /** |
aoqi@0 | 186 | * The pipeline is created for this {@link WSBindingProvider}. |
aoqi@0 | 187 | * Nullable incase of backwards compatible usages of this class. |
aoqi@0 | 188 | */ |
aoqi@0 | 189 | public @Nullable WSBindingProvider getBindingProvider() { |
aoqi@0 | 190 | return bindingProvider; |
aoqi@0 | 191 | } |
aoqi@0 | 192 | |
aoqi@0 | 193 | /** |
aoqi@0 | 194 | * The binding of the new pipeline to be created. |
aoqi@0 | 195 | */ |
aoqi@0 | 196 | public @NotNull WSBinding getBinding() { |
aoqi@0 | 197 | return binding; |
aoqi@0 | 198 | } |
aoqi@0 | 199 | |
aoqi@0 | 200 | /** |
aoqi@0 | 201 | * The created pipeline will use seiModel to get java concepts for the endpoint |
aoqi@0 | 202 | * |
aoqi@0 | 203 | * @return Null if the service doesn't have SEI model e.g. Dispatch, |
aoqi@0 | 204 | * and otherwise non-null. |
aoqi@0 | 205 | */ |
aoqi@0 | 206 | public @Nullable SEIModel getSEIModel() { |
aoqi@0 | 207 | return seiModel; |
aoqi@0 | 208 | } |
aoqi@0 | 209 | |
aoqi@0 | 210 | /** |
aoqi@0 | 211 | * The SEI class for the endpoint |
aoqi@0 | 212 | * |
aoqi@0 | 213 | * @return Null if the service doesn't have SEI model e.g. Dispatch, |
aoqi@0 | 214 | * and otherwise non-null. |
aoqi@0 | 215 | */ |
aoqi@0 | 216 | public @Nullable Class getSEI() { |
aoqi@0 | 217 | return sei; |
aoqi@0 | 218 | } |
aoqi@0 | 219 | |
aoqi@0 | 220 | /** |
aoqi@0 | 221 | * Returns the Container in which the client is running |
aoqi@0 | 222 | * |
aoqi@0 | 223 | * @return Container in which client is running |
aoqi@0 | 224 | */ |
aoqi@0 | 225 | public Container getContainer() { |
aoqi@0 | 226 | return container; |
aoqi@0 | 227 | } |
aoqi@0 | 228 | |
aoqi@0 | 229 | /** |
aoqi@0 | 230 | * creates a {@link Tube} that dumps messages that pass through. |
aoqi@0 | 231 | */ |
aoqi@0 | 232 | public Tube createDumpTube(String name, PrintStream out, Tube next) { |
aoqi@0 | 233 | return new DumpTube(name, out, next); |
aoqi@0 | 234 | } |
aoqi@0 | 235 | |
aoqi@0 | 236 | /** |
aoqi@0 | 237 | * Creates a {@link Tube} that adds container specific security |
aoqi@0 | 238 | */ |
aoqi@0 | 239 | public @NotNull Tube createSecurityTube(@NotNull Tube next) { |
aoqi@0 | 240 | ClientPipelineHook hook = container.getSPI(ClientPipelineHook.class); |
aoqi@0 | 241 | if (hook != null) { |
aoqi@0 | 242 | ClientPipeAssemblerContext ctxt = new ClientPipeAssemblerContext(address, wsdlModel, |
aoqi@0 | 243 | rootOwner, binding, container); |
aoqi@0 | 244 | return PipeAdapter.adapt(hook.createSecurityPipe(ctxt, PipeAdapter.adapt(next))); |
aoqi@0 | 245 | } |
aoqi@0 | 246 | return next; |
aoqi@0 | 247 | } |
aoqi@0 | 248 | |
aoqi@0 | 249 | /** |
aoqi@0 | 250 | * Creates a {@link Tube} that invokes protocol and logical handlers. |
aoqi@0 | 251 | */ |
aoqi@0 | 252 | public Tube createWsaTube(Tube next) { |
aoqi@0 | 253 | if (binding instanceof SOAPBinding && AddressingVersion.isEnabled(binding) && wsdlModel!=null) |
aoqi@0 | 254 | if(AddressingVersion.fromBinding(binding) == AddressingVersion.MEMBER) { |
aoqi@0 | 255 | return new MemberSubmissionWsaClientTube(wsdlModel, binding, next); |
aoqi@0 | 256 | } else { |
aoqi@0 | 257 | return new W3CWsaClientTube(wsdlModel, binding, next); |
aoqi@0 | 258 | } |
aoqi@0 | 259 | else |
aoqi@0 | 260 | return next; |
aoqi@0 | 261 | } |
aoqi@0 | 262 | |
aoqi@0 | 263 | /** |
aoqi@0 | 264 | * Creates a {@link Tube} that invokes protocol and logical handlers. |
aoqi@0 | 265 | */ |
aoqi@0 | 266 | public Tube createHandlerTube(Tube next) { |
aoqi@0 | 267 | HandlerTube cousinHandlerTube = null; |
aoqi@0 | 268 | //XML/HTTP Binding can have only LogicalHandlerPipe |
aoqi@0 | 269 | if (binding instanceof SOAPBinding) { |
aoqi@0 | 270 | //Add MessageHandlerTube |
aoqi@0 | 271 | HandlerTube messageHandlerTube = new ClientMessageHandlerTube(seiModel, binding, wsdlModel, next); |
aoqi@0 | 272 | next = cousinHandlerTube = messageHandlerTube; |
aoqi@0 | 273 | |
aoqi@0 | 274 | //Add SOAPHandlerTuber |
aoqi@0 | 275 | HandlerTube soapHandlerTube = new ClientSOAPHandlerTube(binding, next, cousinHandlerTube); |
aoqi@0 | 276 | next = cousinHandlerTube = soapHandlerTube; |
aoqi@0 | 277 | } |
aoqi@0 | 278 | return new ClientLogicalHandlerTube(binding, seiModel, next, cousinHandlerTube); |
aoqi@0 | 279 | } |
aoqi@0 | 280 | |
aoqi@0 | 281 | /** |
aoqi@0 | 282 | * Creates a {@link Tube} that performs SOAP mustUnderstand processing. |
aoqi@0 | 283 | * This pipe should be before HandlerPipes. |
aoqi@0 | 284 | */ |
aoqi@0 | 285 | public Tube createClientMUTube(Tube next) { |
aoqi@0 | 286 | if(binding instanceof SOAPBinding) |
aoqi@0 | 287 | return new ClientMUTube(binding,next); |
aoqi@0 | 288 | else |
aoqi@0 | 289 | return next; |
aoqi@0 | 290 | } |
aoqi@0 | 291 | |
aoqi@0 | 292 | /** |
aoqi@0 | 293 | * creates a {@link Tube} that validates messages against schema |
aoqi@0 | 294 | */ |
aoqi@0 | 295 | public Tube createValidationTube(Tube next) { |
aoqi@0 | 296 | if (binding instanceof SOAPBinding && binding.isFeatureEnabled(SchemaValidationFeature.class) && wsdlModel!=null) |
aoqi@0 | 297 | return new ClientSchemaValidationTube(binding, wsdlModel, next); |
aoqi@0 | 298 | else |
aoqi@0 | 299 | return next; |
aoqi@0 | 300 | } |
aoqi@0 | 301 | |
aoqi@0 | 302 | /** |
aoqi@0 | 303 | * Creates a transport pipe (for client), which becomes the terminal pipe. |
aoqi@0 | 304 | */ |
aoqi@0 | 305 | public Tube createTransportTube() { |
aoqi@0 | 306 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
aoqi@0 | 307 | |
aoqi@0 | 308 | // The application may configure the endpoint address through request context |
aoqi@0 | 309 | // using {@link BindingProvider#ENDPOINT_ADDRESS_PROPERTY}. Let us |
aoqi@0 | 310 | // defer the creation of actual transport until the service invocation, |
aoqi@0 | 311 | // DeferredTransportPipe is used for this purpose. |
aoqi@0 | 312 | return new DeferredTransportPipe(cl,this); |
aoqi@0 | 313 | } |
aoqi@0 | 314 | |
aoqi@0 | 315 | /** |
aoqi@0 | 316 | * Gets the {@link Codec} that is set by {@link #setCodec} or the default codec |
aoqi@0 | 317 | * based on the binding. |
aoqi@0 | 318 | * |
aoqi@0 | 319 | * @return codec to be used for web service requests |
aoqi@0 | 320 | */ |
aoqi@0 | 321 | public @NotNull Codec getCodec() { |
aoqi@0 | 322 | return codec; |
aoqi@0 | 323 | } |
aoqi@0 | 324 | |
aoqi@0 | 325 | /** |
aoqi@0 | 326 | * Interception point to change {@link Codec} during {@link Tube}line assembly. The |
aoqi@0 | 327 | * new codec will be used by jax-ws client runtime for encoding/decoding web service |
aoqi@0 | 328 | * request/response messages. The new codec should be used by the transport tubes. |
aoqi@0 | 329 | * |
aoqi@0 | 330 | * <p> |
aoqi@0 | 331 | * the codec should correctly implement {@link Codec#copy} since it is used while |
aoqi@0 | 332 | * serving requests concurrently. |
aoqi@0 | 333 | * |
aoqi@0 | 334 | * @param codec codec to be used for web service requests |
aoqi@0 | 335 | */ |
aoqi@0 | 336 | public void setCodec(@NotNull Codec codec) { |
aoqi@0 | 337 | this.codec = codec; |
aoqi@0 | 338 | } |
aoqi@0 | 339 | |
aoqi@0 | 340 | } |