001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.jaxws;
019:
020: import java.util.concurrent.ExecutionException;
021: import java.util.concurrent.Future;
022: import java.util.concurrent.TimeUnit;
023: import java.util.concurrent.TimeoutException;
024: import java.util.logging.Level;
025: import java.util.logging.Logger;
026:
027: import javax.xml.ws.AsyncHandler;
028: import javax.xml.ws.Response;
029:
030: import org.apache.cxf.common.i18n.Message;
031: import org.apache.cxf.common.logging.LogUtils;
032:
033: public class AsyncCallbackFuture implements Runnable, Future {
034:
035: private static final Logger LOG = LogUtils
036: .getL7dLogger(AsyncCallbackFuture.class);
037: private final Response response;
038: private final AsyncHandler callback;
039: private boolean done;
040:
041: public AsyncCallbackFuture(Response r, AsyncHandler c) {
042: response = r;
043: callback = c;
044: }
045:
046: @SuppressWarnings("unchecked")
047: public synchronized void run() {
048: try {
049: callback.handleResponse(response);
050: } finally {
051: done = true;
052: notifyAll();
053: }
054: }
055:
056: public boolean cancel(boolean interrupt) {
057: return response.cancel(interrupt);
058: }
059:
060: public boolean isCancelled() {
061: return response.isCancelled();
062: }
063:
064: public boolean isDone() {
065: return done;
066: }
067:
068: public Object get() throws InterruptedException, ExecutionException {
069: waitForCallbackExecutionToFinish();
070: return null;
071: }
072:
073: public Object get(long timeout, TimeUnit unit)
074: throws InterruptedException, ExecutionException,
075: TimeoutException {
076: long ms = TimeUnit.MILLISECONDS.convert(timeout, unit);
077: waitForCallbackExecutionToFinish(ms);
078: return null;
079: }
080:
081: private synchronized void waitForCallbackExecutionToFinish() {
082: while (!done) {
083: LOG.fine("waiting for callback to finish execution.");
084: try {
085: wait();
086: } catch (InterruptedException ex) {
087: // deliberately ignore
088: }
089: }
090: }
091:
092: private synchronized void waitForCallbackExecutionToFinish(
093: long millis) throws TimeoutException {
094: while (!done && millis > 0) {
095: if (LOG.isLoggable(Level.FINE)) {
096: LOG
097: .fine("waiting (max "
098: + millis
099: + " milliseconds for callback to finish execution (max .");
100: }
101: long startedAt = System.currentTimeMillis();
102: try {
103: wait(millis);
104: } catch (InterruptedException ex) {
105: // deliberately ignore
106: millis -= System.currentTimeMillis() - startedAt;
107: }
108: }
109: if (!done) {
110: throw new TimeoutException(new Message(
111: "ASYNC_HANDLER_TIMEDOUT_EXC", LOG).toString());
112: }
113: }
114:
115: }
|