src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 418
43240b8b995b
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.ws.api.server;
ohair@286 27
ohair@286 28 import com.sun.istack.internal.NotNull;
ohair@286 29 import com.sun.xml.internal.ws.api.message.Message;
ohair@286 30 import com.sun.xml.internal.ws.api.message.Packet;
ohair@286 31 import com.sun.xml.internal.ws.resources.ServerMessages;
ohair@286 32 import com.sun.xml.internal.ws.resources.WsservletMessages;
ohair@286 33 import com.sun.xml.internal.ws.server.ServerRtException;
ohair@286 34 import com.sun.xml.internal.ws.server.SingletonResolver;
ohair@286 35
ohair@286 36 import javax.xml.ws.Provider;
ohair@286 37 import javax.xml.ws.WebServiceContext;
ohair@286 38 import javax.xml.ws.WebServiceException;
ohair@286 39 import java.lang.annotation.Annotation;
ohair@286 40 import java.lang.reflect.InvocationTargetException;
ohair@286 41 import java.lang.reflect.Method;
ohair@286 42 import java.util.logging.Level;
ohair@286 43 import java.util.logging.Logger;
ohair@286 44
ohair@286 45 /**
ohair@286 46 * Determines the instance that serves
ohair@286 47 * the given request packet.
ohair@286 48 *
ohair@286 49 * <p>
ohair@286 50 * The JAX-WS spec always use a singleton instance
ohair@286 51 * to serve all the requests, but this hook provides
ohair@286 52 * a convenient way to route messages to a proper receiver.
ohair@286 53 *
ohair@286 54 * <p>
ohair@286 55 * Externally, an instance of {@link InstanceResolver} is
ohair@286 56 * associated with {@link WSEndpoint}.
ohair@286 57 *
ohair@286 58 * <h2>Possible Uses</h2>
ohair@286 59 * <p>
ohair@286 60 * One can use WS-Addressing message properties to
ohair@286 61 * decide which instance to deliver a message. This
ohair@286 62 * would be an important building block for a stateful
ohair@286 63 * web services.
ohair@286 64 *
ohair@286 65 * <p>
ohair@286 66 * One can associate an instance of a service
ohair@286 67 * with a specific WS-RM session.
ohair@286 68 *
ohair@286 69 * @author Kohsuke Kawaguchi
ohair@286 70 */
ohair@286 71 public abstract class InstanceResolver<T> {
ohair@286 72 /**
ohair@286 73 * Decides which instance of 'T' serves the given request message.
ohair@286 74 *
ohair@286 75 * <p>
ohair@286 76 * This method is called concurrently by multiple threads.
ohair@286 77 * It is also on a criticail path that affects the performance.
ohair@286 78 * A good implementation should try to avoid any synchronization,
ohair@286 79 * and should minimize the amount of work as much as possible.
ohair@286 80 *
ohair@286 81 * @param request
ohair@286 82 * Always non-null. Represents the request message to be served.
ohair@286 83 * The caller may not consume the {@link Message}.
ohair@286 84 */
ohair@286 85 public abstract @NotNull T resolve(@NotNull Packet request);
ohair@286 86
ohair@286 87 /**
ohair@286 88 * Called by the default {@link Invoker} after the method call is done.
ohair@286 89 * This gives {@link InstanceResolver} a chance to do clean up.
ohair@286 90 *
ohair@286 91 * <p>
ohair@286 92 * Alternatively, one could override {@link #createInvoker()} to
ohair@286 93 * create a custom invoker to do this in more flexible way.
ohair@286 94 *
ohair@286 95 * <p>
ohair@286 96 * The default implementation is a no-op.
ohair@286 97 *
ohair@286 98 * @param request
ohair@286 99 * The same request packet given to {@link #resolve(Packet)} method.
ohair@286 100 * @param servant
ohair@286 101 * The object returned from the {@link #resolve(Packet)} method.
ohair@286 102 * @since 2.1.2
ohair@286 103 */
ohair@286 104 public void postInvoke(@NotNull Packet request, @NotNull T servant) {
ohair@286 105 }
ohair@286 106
ohair@286 107 /**
ohair@286 108 * Called by {@link WSEndpoint} when it's set up.
ohair@286 109 *
ohair@286 110 * <p>
ohair@286 111 * This is an opportunity for {@link InstanceResolver}
ohair@286 112 * to do a endpoint-specific initialization process.
ohair@286 113 *
ohair@286 114 * @param wsc
ohair@286 115 * The {@link WebServiceContext} instance to be injected
ohair@286 116 * to the user instances (assuming {@link InstanceResolver}
ohair@286 117 */
ohair@286 118 public void start(@NotNull WSWebServiceContext wsc, @NotNull WSEndpoint endpoint) {
ohair@286 119 // backward compatibility
ohair@286 120 start(wsc);
ohair@286 121 }
ohair@286 122
ohair@286 123 /**
ohair@286 124 * @deprecated
ohair@286 125 * Use {@link #start(WSWebServiceContext,WSEndpoint)}.
ohair@286 126 */
ohair@286 127 public void start(@NotNull WebServiceContext wsc) {}
ohair@286 128
ohair@286 129 /**
ohair@286 130 * Called by {@link WSEndpoint}
ohair@286 131 * when {@link WSEndpoint#dispose()} is called.
ohair@286 132 *
ohair@286 133 * This allows {@link InstanceResolver} to do final clean up.
ohair@286 134 *
ohair@286 135 * <p>
ohair@286 136 * This method is guaranteed to be only called once by {@link WSEndpoint}.
ohair@286 137 */
ohair@286 138 public void dispose() {}
ohair@286 139
ohair@286 140
ohair@286 141 /**
ohair@286 142 * Creates a {@link InstanceResolver} implementation that always
ohair@286 143 * returns the specified singleton instance.
ohair@286 144 */
ohair@286 145 public static <T> InstanceResolver<T> createSingleton(T singleton) {
ohair@286 146 assert singleton!=null;
ohair@286 147 InstanceResolver ir = createFromInstanceResolverAnnotation(singleton.getClass());
ohair@286 148 if(ir==null)
ohair@286 149 ir = new SingletonResolver<T>(singleton);
ohair@286 150 return ir;
ohair@286 151 }
ohair@286 152
ohair@286 153 /**
ohair@286 154 * @deprecated
ohair@286 155 * This is added here because a Glassfish integration happened
ohair@286 156 * with this signature. Please do not use this. Will be removed
ohair@286 157 * after the next GF integration.
ohair@286 158 */
ohair@286 159 public static <T> InstanceResolver<T> createDefault(@NotNull Class<T> clazz, boolean bool) {
ohair@286 160 return createDefault(clazz);
ohair@286 161 }
ohair@286 162
ohair@286 163 /**
ohair@286 164 * Creates a default {@link InstanceResolver} that serves the given class.
ohair@286 165 */
ohair@286 166 public static <T> InstanceResolver<T> createDefault(@NotNull Class<T> clazz) {
ohair@286 167 InstanceResolver<T> ir = createFromInstanceResolverAnnotation(clazz);
ohair@286 168 if(ir==null)
ohair@286 169 ir = new SingletonResolver<T>(createNewInstance(clazz));
ohair@286 170 return ir;
ohair@286 171 }
ohair@286 172
ohair@286 173 /**
ohair@286 174 * Checks for {@link InstanceResolverAnnotation} and creates an instance resolver from it if any.
ohair@286 175 * Otherwise null.
ohair@286 176 */
ohair@286 177 public static <T> InstanceResolver<T> createFromInstanceResolverAnnotation(@NotNull Class<T> clazz) {
ohair@286 178 for( Annotation a : clazz.getAnnotations() ) {
ohair@286 179 InstanceResolverAnnotation ira = a.annotationType().getAnnotation(InstanceResolverAnnotation.class);
ohair@286 180 if(ira==null) continue;
ohair@286 181 Class<? extends InstanceResolver> ir = ira.value();
ohair@286 182 try {
ohair@286 183 return ir.getConstructor(Class.class).newInstance(clazz);
ohair@286 184 } catch (InstantiationException e) {
ohair@286 185 throw new WebServiceException(ServerMessages.FAILED_TO_INSTANTIATE_INSTANCE_RESOLVER(
ohair@286 186 ir.getName(),a.annotationType(),clazz.getName()));
ohair@286 187 } catch (IllegalAccessException e) {
ohair@286 188 throw new WebServiceException(ServerMessages.FAILED_TO_INSTANTIATE_INSTANCE_RESOLVER(
ohair@286 189 ir.getName(),a.annotationType(),clazz.getName()));
ohair@286 190 } catch (InvocationTargetException e) {
ohair@286 191 throw new WebServiceException(ServerMessages.FAILED_TO_INSTANTIATE_INSTANCE_RESOLVER(
ohair@286 192 ir.getName(),a.annotationType(),clazz.getName()));
ohair@286 193 } catch (NoSuchMethodException e) {
ohair@286 194 throw new WebServiceException(ServerMessages.FAILED_TO_INSTANTIATE_INSTANCE_RESOLVER(
ohair@286 195 ir.getName(),a.annotationType(),clazz.getName()));
ohair@286 196 }
ohair@286 197 }
ohair@286 198
ohair@286 199 return null;
ohair@286 200 }
ohair@286 201
ohair@286 202 protected static <T> T createNewInstance(Class<T> cl) {
ohair@286 203 try {
ohair@286 204 return cl.newInstance();
ohair@286 205 } catch (InstantiationException e) {
ohair@286 206 logger.log(Level.SEVERE, e.getMessage(), e);
ohair@286 207 throw new ServerRtException(
ohair@286 208 WsservletMessages.ERROR_IMPLEMENTOR_FACTORY_NEW_INSTANCE_FAILED(cl));
ohair@286 209 } catch (IllegalAccessException e) {
ohair@286 210 logger.log(Level.SEVERE, e.getMessage(), e);
ohair@286 211 throw new ServerRtException(
ohair@286 212 WsservletMessages.ERROR_IMPLEMENTOR_FACTORY_NEW_INSTANCE_FAILED(cl));
ohair@286 213 }
ohair@286 214 }
ohair@286 215
ohair@286 216 /**
ohair@286 217 * Wraps this {@link InstanceResolver} into an {@link Invoker}.
ohair@286 218 */
ohair@286 219 public @NotNull Invoker createInvoker() {
ohair@286 220 return new Invoker() {
ohair@286 221 @Override
ohair@286 222 public void start(@NotNull WSWebServiceContext wsc, @NotNull WSEndpoint endpoint) {
ohair@286 223 InstanceResolver.this.start(wsc,endpoint);
ohair@286 224 }
ohair@286 225
ohair@286 226 @Override
ohair@286 227 public void dispose() {
ohair@286 228 InstanceResolver.this.dispose();
ohair@286 229 }
ohair@286 230
ohair@286 231 @Override
ohair@286 232 public Object invoke(Packet p, Method m, Object... args) throws InvocationTargetException, IllegalAccessException {
ohair@286 233 T t = resolve(p);
ohair@286 234 try {
ohair@286 235 return m.invoke(t, args );
ohair@286 236 } finally {
ohair@286 237 postInvoke(p,t);
ohair@286 238 }
ohair@286 239 }
ohair@286 240
ohair@286 241 @Override
ohair@286 242 public <U> U invokeProvider(@NotNull Packet p, U arg) {
ohair@286 243 T t = resolve(p);
ohair@286 244 try {
ohair@286 245 return ((Provider<U>) t).invoke(arg);
ohair@286 246 } finally {
ohair@286 247 postInvoke(p,t);
ohair@286 248 }
ohair@286 249 }
ohair@286 250
ohair@286 251 public String toString() {
ohair@286 252 return "Default Invoker over "+InstanceResolver.this.toString();
ohair@286 253 }
ohair@286 254 };
ohair@286 255 }
ohair@286 256
ohair@286 257 private static final Logger logger =
ohair@286 258 Logger.getLogger(
ohair@286 259 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server");
ohair@286 260 }

mercurial