/* * Copyright 2009 Richard Zschech. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package net.zschech.gwt.comet.server.impl; import java.util.concurrent.Callable; import java.util.concurrent.Delayed; import java.util.concurrent.ExecutionException; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * A {@link ScheduledThreadPoolExecutor} that removes cancelled tasks from the work queue. * * This is required until Java 7's ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true) is available. * * @author Richard Zschech */ public class RemoveOnCancelScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { public RemoveOnCancelScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler) { super(corePoolSize, handler); } public RemoveOnCancelScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, threadFactory, handler); } public RemoveOnCancelScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) { super(corePoolSize, threadFactory); } public RemoveOnCancelScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize); } @Override public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { return wrap(super.schedule(callable, delay, unit)); } @Override public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { return wrap(super.schedule(command, delay, unit)); } @Override public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { return wrap(super.scheduleAtFixedRate(command, initialDelay, period, unit)); } @Override public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { return wrap(super.scheduleWithFixedDelay(command, initialDelay, delay, unit)); } public <V> ScheduledFuture<V> wrap(final ScheduledFuture<V> wrap) { return new WrapScheduledFuture<V>(wrap); } public class WrapScheduledFuture<V> implements ScheduledFuture<V> { private final ScheduledFuture<V> wrap; public WrapScheduledFuture(ScheduledFuture<V> wrap) { this.wrap = wrap; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((wrap == null) ? 0 : wrap.hashCode()); return result; } @SuppressWarnings("unchecked") @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } WrapScheduledFuture other = (WrapScheduledFuture) obj; if (wrap == null) { if (other.wrap != null) { return false; } } else if (!wrap.equals(other.wrap)) { return false; } return true; } @Override public long getDelay(TimeUnit unit) { return wrap.getDelay(unit); } @SuppressWarnings("unchecked") @Override public int compareTo(Delayed o) { return wrap.compareTo(((WrapScheduledFuture) o).wrap); } @Override public boolean cancel(boolean mayInterruptIfRunning) { boolean cancelled = wrap.cancel(mayInterruptIfRunning); if (cancelled) { getQueue().remove(wrap); } return cancelled; } @Override public V get() throws InterruptedException, ExecutionException { return wrap.get(); } @Override public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return wrap.get(timeout, unit); } @Override public boolean isCancelled() { return wrap.isCancelled(); } @Override public boolean isDone() { return wrap.isDone(); } } }