aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.client; aoqi@0: aoqi@0: import com.sun.istack.internal.Nullable; aoqi@0: import com.sun.xml.internal.ws.api.Cancelable; aoqi@0: import com.sun.xml.internal.ws.util.CompletedFuture; aoqi@0: aoqi@0: import javax.xml.ws.AsyncHandler; aoqi@0: import javax.xml.ws.Response; aoqi@0: import javax.xml.ws.WebServiceException; aoqi@0: import java.util.Map; aoqi@0: import java.util.concurrent.FutureTask; aoqi@0: aoqi@0: /** aoqi@0: * {@link Response} implementation. When Runnbale is executed, it just hands the aoqi@0: * request to Fiber and returns. When the Fiber finishes the execution, it sets aoqi@0: * response in the {@link FutureTask} aoqi@0: * aoqi@0: * @author Jitendra Kotamraju aoqi@0: */ aoqi@0: public final class AsyncResponseImpl extends FutureTask implements Response, ResponseContextReceiver { aoqi@0: aoqi@0: /** aoqi@0: * Optional {@link AsyncHandler} that gets invoked aoqi@0: * at the completion of the task. aoqi@0: */ aoqi@0: private final AsyncHandler handler; aoqi@0: private ResponseContext responseContext; aoqi@0: private final Runnable callable; aoqi@0: private Cancelable cancelable; aoqi@0: aoqi@0: /** aoqi@0: * aoqi@0: * @param runnable aoqi@0: * This {@link Runnable} is executed asynchronously. aoqi@0: * @param handler aoqi@0: * Optional {@link AsyncHandler} to invoke at the end aoqi@0: * of the processing. Can be null. aoqi@0: */ aoqi@0: public AsyncResponseImpl(Runnable runnable, @Nullable AsyncHandler handler) { aoqi@0: super(runnable, null); aoqi@0: this.callable = runnable; aoqi@0: this.handler = handler; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public void run() { aoqi@0: // override so that AsyncInvoker calls set() aoqi@0: // when Fiber calls the callback aoqi@0: try { aoqi@0: callable.run(); aoqi@0: } catch (WebServiceException e) { aoqi@0: //it could be a WebServiceException or a ProtocolException or any RuntimeException aoqi@0: // resulting due to some internal bug. aoqi@0: set(null, e); aoqi@0: } catch (Throwable e) { aoqi@0: //its some other exception resulting from user error, wrap it in aoqi@0: // WebServiceException aoqi@0: set(null, new WebServiceException(e)); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: public ResponseContext getContext() { aoqi@0: return responseContext; aoqi@0: } aoqi@0: aoqi@0: public void setResponseContext(ResponseContext rc) { aoqi@0: responseContext = rc; aoqi@0: } aoqi@0: aoqi@0: public void set(final T v, final Throwable t) { aoqi@0: // call the handler before we mark the future as 'done' aoqi@0: if (handler!=null) { aoqi@0: try { aoqi@0: /** aoqi@0: * {@link Response} object passed into the callback. aoqi@0: * We need a separate {@link java.util.concurrent.Future} because we don't want {@link ResponseImpl} aoqi@0: * to be marked as 'done' before the callback finishes execution. aoqi@0: * (That would provide implicit synchronization between the application code aoqi@0: * in the main thread and the callback code, and is compatible with the JAX-RI 2.0 FCS. aoqi@0: */ aoqi@0: class CallbackFuture extends CompletedFuture implements Response { aoqi@0: public CallbackFuture(T v, Throwable t) { aoqi@0: super(v, t); aoqi@0: } aoqi@0: aoqi@0: public Map getContext() { aoqi@0: return AsyncResponseImpl.this.getContext(); aoqi@0: } aoqi@0: } aoqi@0: handler.handleResponse(new CallbackFuture(v, t)); aoqi@0: } catch (Throwable e) { aoqi@0: super.setException(e); aoqi@0: return; aoqi@0: } aoqi@0: } aoqi@0: if (t != null) { aoqi@0: super.setException(t); aoqi@0: } else { aoqi@0: super.set(v); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public void setCancelable(Cancelable cancelable) { aoqi@0: this.cancelable = cancelable; aoqi@0: } aoqi@0: aoqi@0: public boolean cancel(boolean mayInterruptIfRunning) { aoqi@0: if (cancelable != null) aoqi@0: cancelable.cancel(mayInterruptIfRunning); aoqi@0: return super.cancel(mayInterruptIfRunning); aoqi@0: } aoqi@0: }