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 26package com.sun.xml.internal.ws.server; 27 28import com.sun.istack.internal.NotNull; 29import com.sun.istack.internal.Nullable; 30import com.sun.xml.internal.ws.api.message.Packet; 31import com.sun.xml.internal.ws.api.pipe.TubeCloner; 32import com.sun.xml.internal.ws.api.pipe.helper.AbstractTubeImpl; 33import com.sun.xml.internal.ws.api.server.*; 34import com.sun.xml.internal.ws.resources.ServerMessages; 35import com.sun.xml.internal.ws.server.provider.ProviderInvokerTube; 36import com.sun.xml.internal.ws.server.sei.SEIInvokerTube; 37 38import javax.xml.ws.WebServiceContext; 39import javax.xml.ws.WebServiceException; 40import java.lang.reflect.InvocationTargetException; 41import java.lang.reflect.Method; 42 43/** 44 * Base code for {@link ProviderInvokerTube} and {@link SEIInvokerTube}. 45 * 46 * <p> 47 * This hides {@link InstanceResolver} and performs a set up 48 * necessary for {@link WebServiceContext} to correctly. 49 * 50 * @author Kohsuke Kawaguchi 51 */ 52public abstract class InvokerTube<T> extends com.sun.xml.internal.ws.server.sei.InvokerTube<Invoker> implements EndpointAwareTube { 53 54 private WSEndpoint endpoint; 55 56 protected InvokerTube(Invoker invoker) { 57 super(invoker); 58 } 59 60 public void setEndpoint(WSEndpoint endpoint) { 61 this.endpoint = endpoint; 62 WSWebServiceContext webServiceContext = new AbstractWebServiceContext(endpoint) { 63 public @Nullable Packet getRequestPacket() { 64 Packet p = packets.get(); 65 return p; 66 } 67 }; 68 invoker.start(webServiceContext,endpoint); 69 } 70 71 protected WSEndpoint getEndpoint() { 72 return endpoint; 73 } 74 75 /** 76 * Returns the application object that serves the request. 77 * 78 public final @NotNull T getServant(Packet request) { 79 // this allows WebServiceContext to find this packet 80 packets.set(request); 81 return invoker.resolve(request); 82 } 83 */ 84 85 /** 86 * Returns the {@link Invoker} object that serves the request. 87 */ 88 public final @NotNull Invoker getInvoker(Packet request) { 89 return wrapper; 90 } 91 92 /** 93 * processRequest() and processResponse() do not share any instance variables 94 * while processing the request. {@link InvokerTube} is stateless and terminal, 95 * so no need to create copies. 96 */ 97 public final AbstractTubeImpl copy(TubeCloner cloner) { 98 cloner.add(this,this); 99 return this; 100 } 101 102 public void preDestroy() { 103 invoker.dispose(); 104 } 105 106 /** 107 * Heart of {@link WebServiceContext}. 108 * Remembers which thread is serving which packet. 109 */ 110 private static final ThreadLocal<Packet> packets = new ThreadLocal<Packet>(); 111 112 /** 113 * This method can be called while the user service is servicing the request 114 * synchronously, to obtain the current request packet. 115 * 116 * <p> 117 * This is primarily designed for {@link StatefulInstanceResolver}. Use with care. 118 */ 119 public static @NotNull Packet getCurrentPacket() { 120 Packet packet = packets.get(); 121 if(packet==null) 122 throw new WebServiceException(ServerMessages.NO_CURRENT_PACKET()); 123 return packet; 124 } 125 126 /** 127 * {@link Invoker} filter that sets and restores the current packet. 128 */ 129 private final Invoker wrapper = new Invoker() { 130 @Override 131 public Object invoke(Packet p, Method m, Object... args) throws InvocationTargetException, IllegalAccessException { 132 Packet old = set(p); 133 try { 134 return invoker.invoke(p, m, args); 135 } finally { 136 set(old); 137 } 138 } 139 140 @Override 141 public <T>T invokeProvider(Packet p, T arg) throws IllegalAccessException, InvocationTargetException { 142 Packet old = set(p); 143 try { 144 return invoker.invokeProvider(p, arg); 145 } finally { 146 set(old); 147 } 148 } 149 150 @Override 151 public <T>void invokeAsyncProvider(Packet p, T arg, AsyncProviderCallback cbak, WebServiceContext ctxt) throws IllegalAccessException, InvocationTargetException { 152 Packet old = set(p); 153 try { 154 invoker.invokeAsyncProvider(p, arg, cbak, ctxt); 155 } finally { 156 set(old); 157 } 158 } 159 160 private Packet set(Packet p) { 161 Packet old = packets.get(); 162 packets.set(p); 163 return old; 164 } 165 }; 166 167} 168