001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.server;
038:
039: import com.sun.istack.NotNull;
040: import com.sun.istack.Nullable;
041: import com.sun.xml.ws.api.message.Packet;
042: import com.sun.xml.ws.api.pipe.TubeCloner;
043: import com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl;
044: import com.sun.xml.ws.api.server.*;
045: import com.sun.xml.ws.resources.ServerMessages;
046: import com.sun.xml.ws.server.provider.ProviderInvokerTube;
047: import com.sun.xml.ws.server.sei.SEIInvokerTube;
048:
049: import javax.xml.ws.WebServiceContext;
050: import javax.xml.ws.WebServiceException;
051: import java.lang.reflect.InvocationTargetException;
052: import java.lang.reflect.Method;
053:
054: /**
055: * Base code for {@link ProviderInvokerTube} and {@link SEIInvokerTube}.
056: *
057: * <p>
058: * This hides {@link InstanceResolver} and performs a set up
059: * necessary for {@link WebServiceContext} to correctly.
060: *
061: * @author Kohsuke Kawaguchi
062: */
063: public abstract class InvokerTube<T> extends AbstractTubeImpl {
064:
065: private final Invoker invoker;
066: private WSEndpoint endpoint;
067:
068: protected InvokerTube(Invoker invoker) {
069: this .invoker = invoker;
070: }
071:
072: public void setEndpoint(WSEndpoint endpoint) {
073: this .endpoint = endpoint;
074: WSWebServiceContext webServiceContext = new AbstractWebServiceContext(
075: endpoint) {
076: public @Nullable
077: Packet getRequestPacket() {
078: Packet p = packets.get();
079: return p;
080: }
081: };
082: invoker.start(webServiceContext, endpoint);
083: }
084:
085: protected WSEndpoint getEndpoint() {
086: return endpoint;
087: }
088:
089: /**
090: * Returns the application object that serves the request.
091: *
092: public final @NotNull T getServant(Packet request) {
093: // this allows WebServiceContext to find this packet
094: packets.set(request);
095: return invoker.resolve(request);
096: }
097: */
098:
099: /**
100: * Returns the {@link Invoker} object that serves the request.
101: */
102: public final @NotNull
103: Invoker getInvoker(Packet request) {
104: return wrapper;
105: }
106:
107: /**
108: * processRequest() and processResponse() do not share any instance variables
109: * while processing the request. {@link InvokerTube} is stateless and terminal,
110: * so no need to create copies.
111: */
112: public final AbstractTubeImpl copy(TubeCloner cloner) {
113: cloner.add(this , this );
114: return this ;
115: }
116:
117: public void preDestroy() {
118: invoker.dispose();
119: }
120:
121: /**
122: * Heart of {@link WebServiceContext}.
123: * Remembers which thread is serving which packet.
124: */
125: private static final ThreadLocal<Packet> packets = new ThreadLocal<Packet>();
126:
127: /**
128: * This method can be called while the user service is servicing the request
129: * synchronously, to obtain the current request packet.
130: *
131: * <p>
132: * This is primarily designed for {@link StatefulInstanceResolver}. Use with care.
133: */
134: public static @NotNull
135: Packet getCurrentPacket() {
136: Packet packet = packets.get();
137: if (packet == null)
138: throw new WebServiceException(ServerMessages
139: .NO_CURRENT_PACKET());
140: return packet;
141: }
142:
143: /**
144: * {@link Invoker} filter that sets and restores the current packet.
145: */
146: private final Invoker wrapper = new Invoker() {
147: @Override
148: public Object invoke(Packet p, Method m, Object... args)
149: throws InvocationTargetException,
150: IllegalAccessException {
151: Packet old = set(p);
152: try {
153: return invoker.invoke(p, m, args);
154: } finally {
155: set(old);
156: }
157: }
158:
159: @Override
160: public <T> T invokeProvider(Packet p, T arg)
161: throws IllegalAccessException,
162: InvocationTargetException {
163: Packet old = set(p);
164: try {
165: return invoker.invokeProvider(p, arg);
166: } finally {
167: set(old);
168: }
169: }
170:
171: @Override
172: public <T> void invokeAsyncProvider(Packet p, T arg,
173: AsyncProviderCallback cbak, WebServiceContext ctxt)
174: throws IllegalAccessException,
175: InvocationTargetException {
176: Packet old = set(p);
177: try {
178: invoker.invokeAsyncProvider(p, arg, cbak, ctxt);
179: } finally {
180: set(old);
181: }
182: }
183:
184: private Packet set(Packet p) {
185: Packet old = packets.get();
186: packets.set(p);
187: return old;
188: }
189: };
190:
191: }
|