ServerTubeAssemblerContext.java revision 524:dcaa586ab756
117683Spst/*
217683Spst * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
339294Sfenner * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
417683Spst *
517683Spst * This code is free software; you can redistribute it and/or modify it
617683Spst * under the terms of the GNU General Public License version 2 only, as
717683Spst * published by the Free Software Foundation.  Oracle designates this
817683Spst * particular file as subject to the "Classpath" exception as provided
917683Spst * by Oracle in the LICENSE file that accompanied this code.
1017683Spst *
1117683Spst * This code is distributed in the hope that it will be useful, but WITHOUT
1217683Spst * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1317683Spst * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1417683Spst * version 2 for more details (a copy is included in the LICENSE file that
1517683Spst * accompanied this code).
1617683Spst *
1717683Spst * You should have received a copy of the GNU General Public License version
1817683Spst * 2 along with this work; if not, write to the Free Software Foundation,
1917683Spst * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2017683Spst *
2156891Sfenner * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2256891Sfenner * or visit www.oracle.com if you need additional information or have any
2317683Spst * questions.
2417683Spst */
2517683Spst
26127667Sbmspackage com.sun.xml.internal.ws.api.pipe;
27190225Srpaulo
2817683Spstimport com.sun.istack.internal.NotNull;
2917683Spstimport com.sun.istack.internal.Nullable;
3075110Sfennerimport com.sun.xml.internal.ws.addressing.W3CWsaServerTube;
3175110Sfennerimport com.sun.xml.internal.ws.addressing.v200408.MemberSubmissionWsaServerTube;
3275110Sfennerimport com.sun.xml.internal.ws.api.addressing.AddressingVersion;
3375110Sfennerimport com.sun.xml.internal.ws.api.model.SEIModel;
3417683Spstimport com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
3556891Sfennerimport com.sun.xml.internal.ws.api.pipe.helper.PipeAdapter;
3617683Spstimport com.sun.xml.internal.ws.api.server.ServerPipelineHook;
3717683Spstimport com.sun.xml.internal.ws.api.server.WSEndpoint;
3817683Spstimport com.sun.xml.internal.ws.binding.BindingImpl;
3917683Spstimport com.sun.xml.internal.ws.developer.SchemaValidationFeature;
4056891Sfennerimport com.sun.xml.internal.ws.handler.HandlerTube;
41127667Sbmsimport com.sun.xml.internal.ws.handler.ServerLogicalHandlerTube;
42127667Sbmsimport com.sun.xml.internal.ws.handler.ServerMessageHandlerTube;
43127667Sbmsimport com.sun.xml.internal.ws.handler.ServerSOAPHandlerTube;
44127667Sbmsimport com.sun.xml.internal.ws.protocol.soap.ServerMUTube;
45127667Sbmsimport com.sun.xml.internal.ws.server.ServerSchemaValidationTube;
46127667Sbmsimport com.sun.xml.internal.ws.util.pipe.DumpTube;
47127667Sbms
48127667Sbmsimport javax.xml.ws.soap.SOAPBinding;
49127667Sbmsimport java.io.PrintStream;
50127667Sbms
51127667Sbms/**
5275110Sfenner * Factory for well-known server {@link Tube} implementations
5375110Sfenner * that the {@link TubelineAssembler} needs to use
5475110Sfenner * to satisfy JAX-WS requirements.
5575110Sfenner *
5656891Sfenner * @author Jitendra Kotamraju
57190225Srpaulo */
5817683Spstpublic class ServerTubeAssemblerContext {
5917683Spst
6017683Spst    private final SEIModel seiModel;
6117683Spst    private final WSDLPort wsdlModel;
6217683Spst    private final WSEndpoint endpoint;
6317683Spst    private final BindingImpl binding;
6417683Spst    private final Tube terminal;
6517683Spst    private final boolean isSynchronous;
6617683Spst    private @NotNull Codec codec;
6717683Spst
6826178Sfenner    public ServerTubeAssemblerContext(@Nullable SEIModel seiModel,
6975110Sfenner                                      @Nullable WSDLPort wsdlModel, @NotNull WSEndpoint endpoint,
7017683Spst                                      @NotNull Tube terminal, boolean isSynchronous) {
7175110Sfenner        this.seiModel = seiModel;
7275110Sfenner        this.wsdlModel = wsdlModel;
7317683Spst        this.endpoint = endpoint;
7417683Spst        this.terminal = terminal;
7517683Spst        // WSBinding is actually BindingImpl
7617683Spst        this.binding = (BindingImpl)endpoint.getBinding();
7717683Spst        this.isSynchronous = isSynchronous;
7817683Spst        this.codec = this.binding.createCodec();
7917683Spst    }
8017683Spst
8117683Spst    /**
8217683Spst     * The created pipeline will use seiModel to get java concepts for the endpoint
83190225Srpaulo     *
8456891Sfenner     * @return Null if the service doesn't have SEI model e.g. Provider endpoints,
8517683Spst     *         and otherwise non-null.
86172680Smlaier     */
87172680Smlaier    public @Nullable SEIModel getSEIModel() {
88172680Smlaier        return seiModel;
89172680Smlaier    }
90172680Smlaier
9175110Sfenner    /**
9217683Spst     * The created pipeline will be used to serve this port.
9356891Sfenner     *
9456891Sfenner     * @return Null if the service isn't associated with any port definition in WSDL,
9556891Sfenner     *         and otherwise non-null.
9656891Sfenner     */
9756891Sfenner    public @Nullable WSDLPort getWsdlModel() {
9856891Sfenner        return wsdlModel;
9956891Sfenner    }
10056891Sfenner
10156891Sfenner    /**
10256891Sfenner     *
10356891Sfenner     * The created pipeline is used to serve this {@link com.sun.xml.internal.ws.api.server.WSEndpoint}.
10456891Sfenner     * Specifically, its {@link com.sun.xml.internal.ws.api.WSBinding} should be of interest to  many
10556891Sfenner     * {@link com.sun.xml.internal.ws.api.pipe.Pipe}s.
10656891Sfenner     *  @return Always non-null.
10756891Sfenner     */
10856891Sfenner    public @NotNull WSEndpoint<?> getEndpoint() {
10956891Sfenner        return endpoint;
11056891Sfenner    }
11156891Sfenner
11256891Sfenner    /**
11356891Sfenner     * The last {@link com.sun.xml.internal.ws.api.pipe.Pipe} in the pipeline. The assembler is expected to put
11456891Sfenner     * additional {@link com.sun.xml.internal.ws.api.pipe.Pipe}s in front of it.
11556891Sfenner     *
11656891Sfenner     * <p>
11756891Sfenner     * (Just to give you the idea how this is used, normally the terminal pipe
11856891Sfenner     * is the one that invokes the user application or {@link javax.xml.ws.Provider}.)
11956891Sfenner     *
12056891Sfenner     * @return always non-null terminal pipe
12156891Sfenner     */
12256891Sfenner    public @NotNull Tube getTerminalTube() {
12356891Sfenner         return terminal;
12456891Sfenner    }
12556891Sfenner
12656891Sfenner    /**
12756891Sfenner     * If this server pipeline is known to be used for serving synchronous transport,
12856891Sfenner     * then this method returns true. This can be potentially use as an optimization
12956891Sfenner     * hint, since often synchronous versions are cheaper to execute than asycnhronous
13056891Sfenner     * versions.
13156891Sfenner     */
13256891Sfenner    public boolean isSynchronous() {
13356891Sfenner        return isSynchronous;
13456891Sfenner    }
13556891Sfenner
13656891Sfenner    /**
13756891Sfenner     * Creates a {@link Tube} that performs SOAP mustUnderstand processing.
13856891Sfenner     * This pipe should be before HandlerPipes.
13956891Sfenner     */
14056891Sfenner    public @NotNull Tube createServerMUTube(@NotNull Tube next) {
14156891Sfenner        if (binding instanceof SOAPBinding)
14256891Sfenner            return new ServerMUTube(this,next);
14356891Sfenner        else
14456891Sfenner            return next;
14556891Sfenner    }
14656891Sfenner
14756891Sfenner    /**
14856891Sfenner     * Creates a {@link Tube} that invokes protocol and logical handlers.
14956891Sfenner     */
15056891Sfenner    public @NotNull Tube createHandlerTube(@NotNull Tube next) {
15156891Sfenner        if (!binding.getHandlerChain().isEmpty()) {
15256891Sfenner            HandlerTube cousin = new ServerLogicalHandlerTube(binding, seiModel, wsdlModel, next);
15356891Sfenner            next = cousin;
15456891Sfenner            if (binding instanceof SOAPBinding) {
15556891Sfenner                //Add SOAPHandlerTube
15656891Sfenner                next = cousin = new ServerSOAPHandlerTube(binding, next, cousin);
15756891Sfenner
15856891Sfenner                //Add MessageHandlerTube
15956891Sfenner                next = new ServerMessageHandlerTube(seiModel, binding, next, cousin);
16056891Sfenner            }
16156891Sfenner        }
16256891Sfenner        return next;
16356891Sfenner    }
16456891Sfenner
16556891Sfenner    /**
16656891Sfenner     * Creates a {@link Tube} that does the monitoring of the invocation for a
16756891Sfenner     * container
16856891Sfenner     */
16956891Sfenner    public @NotNull Tube createMonitoringTube(@NotNull Tube next) {
17056891Sfenner        ServerPipelineHook hook = endpoint.getContainer().getSPI(ServerPipelineHook.class);
171190225Srpaulo        if (hook != null) {
172190225Srpaulo            ServerPipeAssemblerContext ctxt = new ServerPipeAssemblerContext(seiModel, wsdlModel, endpoint, terminal, isSynchronous);
173190225Srpaulo            return PipeAdapter.adapt(hook.createMonitoringPipe(ctxt, PipeAdapter.adapt(next)));
174190225Srpaulo        }
17517683Spst        return next;
17617683Spst    }
17717683Spst
17817683Spst    /**
17917683Spst     * Creates a {@link Tube} that adds container specific security
180127667Sbms     */
18117683Spst    public @NotNull Tube createSecurityTube(@NotNull Tube next) {
18217683Spst        ServerPipelineHook hook = endpoint.getContainer().getSPI(ServerPipelineHook.class);
18317683Spst        if (hook != null) {
18498533Sfenner            ServerPipeAssemblerContext ctxt = new ServerPipeAssemblerContext(seiModel, wsdlModel, endpoint, terminal, isSynchronous);
18517683Spst            return PipeAdapter.adapt(hook.createSecurityPipe(ctxt, PipeAdapter.adapt(next)));
18617683Spst        }
18717683Spst        return next;
18817683Spst    }
18917683Spst
19056891Sfenner    /**
19198533Sfenner     * creates a {@link Tube} that dumps messages that pass through.
192147897Ssam     */
19317683Spst    public Tube createDumpTube(String name, PrintStream out, Tube next) {
19498533Sfenner        return new DumpTube(name, out, next);
19598533Sfenner    }
19698533Sfenner
19798533Sfenner    /**
19898533Sfenner     * creates a {@link Tube} that validates messages against schema
19998533Sfenner     */
20098533Sfenner    public Tube createValidationTube(Tube next) {
20198533Sfenner        if (binding instanceof SOAPBinding && binding.isFeatureEnabled(SchemaValidationFeature.class) && wsdlModel!=null)
20298533Sfenner            return new ServerSchemaValidationTube(endpoint, binding, seiModel, wsdlModel, next);
20398533Sfenner        else
20498533Sfenner            return next;
20598533Sfenner    }
20698533Sfenner
20798533Sfenner    /**
20856891Sfenner     * Creates WS-Addressing pipe
20956891Sfenner     */
21056891Sfenner    public Tube createWsaTube(Tube next) {
21117683Spst        if (binding instanceof SOAPBinding && AddressingVersion.isEnabled(binding)) {
21275110Sfenner            if(AddressingVersion.fromBinding(binding) == AddressingVersion.MEMBER) {
21317683Spst                return new MemberSubmissionWsaServerTube(endpoint, wsdlModel, binding, next);
21417683Spst            } else {
21517683Spst                return new W3CWsaServerTube(endpoint, wsdlModel, binding, next);
21617683Spst            }
21717683Spst        } else
21817683Spst            return next;
21917749Spst    }
22017749Spst
22117749Spst    /**
22217749Spst     * Gets the {@link Codec} that is set by {@link #setCodec} or the default codec
22317749Spst     * based on the binding. The codec is a full codec that is responsible for
224127667Sbms     * encoding/decoding entire protocol message(for e.g: it is responsible to
225127667Sbms     * encode/decode entire MIME messages in SOAP binding)
226127667Sbms     *
227127667Sbms     * @return codec to be used for web service requests
228127667Sbms     * @see Codecs
229127667Sbms     */
230127667Sbms    public @NotNull Codec getCodec() {
231127667Sbms        return codec;
23275110Sfenner    }
23317749Spst
23498533Sfenner    /**
23598533Sfenner     * Interception point to change {@link Codec} during {@link Tube}line assembly. The
23698533Sfenner     * new codec will be used by jax-ws server runtime for encoding/decoding web service
23798533Sfenner     * request/response messages. {@link WSEndpoint#createCodec()} will return a copy
23898533Sfenner     * of this new codec and will be used in the server runtime.
23998533Sfenner     *
24017683Spst     * <p>
24117683Spst     * The codec is a full codec that is responsible for
242127667Sbms     * encoding/decoding entire protocol message(for e.g: it is responsible to
24317683Spst     * encode/decode entire MIME messages in SOAP binding)
244147897Ssam     *
24517683Spst     * <p>
24656891Sfenner     * the codec should correctly implement {@link Codec#copy} since it is used while
24756891Sfenner     * serving requests concurrently.
24856891Sfenner     *
24956891Sfenner     * @param codec codec to be used for web service requests
25056891Sfenner     * @see Codecs
25156891Sfenner     */
25256891Sfenner    public void setCodec(@NotNull Codec codec) {
25317683Spst        this.codec = codec;
25417683Spst    }
25517683Spst
256190225Srpaulo}
257190225Srpaulo