1 /*
   2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.ws.api.addressing;
  27 
  28 import com.sun.istack.internal.NotNull;
  29 
  30 import com.sun.xml.internal.ws.api.WSBinding;
  31 import com.sun.xml.internal.ws.api.WSService;
  32 import com.sun.xml.internal.ws.api.message.Packet;
  33 import com.sun.xml.internal.ws.api.pipe.ClientTubeAssemblerContext;
  34 import com.sun.xml.internal.ws.api.pipe.Fiber;
  35 import com.sun.xml.internal.ws.api.pipe.TransportTubeFactory;
  36 import com.sun.xml.internal.ws.api.pipe.Tube;
  37 import com.sun.xml.internal.ws.api.server.WSEndpoint;
  38 import com.sun.xml.internal.ws.binding.BindingImpl;
  39 
  40 /**
  41  * Delivers response messages targeted at non-anonymous endpoint addresses
  42  * @since 2.2.6
  43  */
  44 public class NonAnonymousResponseProcessor {
  45         private static final NonAnonymousResponseProcessor DEFAULT = new NonAnonymousResponseProcessor();
  46 
  47         public static NonAnonymousResponseProcessor getDefault() {
  48                 return DEFAULT;
  49         }
  50 
  51         protected NonAnonymousResponseProcessor() {}
  52 
  53     /**
  54      * Send a response to a non-anonymous address. Also closes the transport back channel
  55      * of {@link Packet} if it's not closed already.
  56      *
  57      * @param packet
  58      *      The response from our server, which will be delivered to the destination.
  59      * @return The response packet that should be used to complete the tubeline response processing
  60      */
  61         public Packet process(Packet packet) {
  62         Fiber.CompletionCallback fiberCallback = null;
  63         Fiber currentFiber = Fiber.getCurrentIfSet();
  64         if (currentFiber != null) {
  65             // Link completion of the current fiber to the new fiber that will
  66             // deliver the async response. This allows access to the response
  67             // packet that may be generated by sending a new message for the
  68             // current async response.
  69 
  70                 final Fiber.CompletionCallback currentFiberCallback =
  71                     currentFiber.getCompletionCallback();
  72 
  73                         if (currentFiberCallback != null) {
  74                           fiberCallback = new Fiber.CompletionCallback() {
  75                           public void onCompletion(@NotNull Packet response) {
  76                             currentFiberCallback.onCompletion(response);
  77                           }
  78 
  79                           public void onCompletion(@NotNull Throwable error) {
  80                             currentFiberCallback.onCompletion(error);
  81                           }
  82                         };
  83                         currentFiber.setCompletionCallback(null);
  84                 }
  85         }
  86 
  87         // we need to assemble a pipeline to talk to this endpoint.
  88                 WSEndpoint<?> endpoint = packet.endpoint;
  89                 WSBinding binding = endpoint.getBinding();
  90         Tube transport = TransportTubeFactory.create(Thread.currentThread().getContextClassLoader(),
  91             new ClientTubeAssemblerContext(
  92                         packet.endpointAddress, endpoint.getPort(), (WSService) null,
  93                         binding, endpoint.getContainer(),
  94                         ((BindingImpl) binding).createCodec(), null, null));
  95         Fiber fiber = endpoint.getEngine().createFiber();
  96         fiber.start(transport, packet, fiberCallback);
  97 
  98         // then we'll proceed the rest like one-way.
  99         Packet copy = packet.copy(false);
 100         copy.endpointAddress = null;
 101 
 102         return copy;
 103         }
 104 }