package org.playorm.nio.impl.util; import java.io.IOException; import org.playorm.nio.api.channels.Channel; import org.playorm.nio.api.channels.RegisterableChannel; import org.playorm.nio.api.handlers.FutureOperation; import org.playorm.nio.api.handlers.NioInterruptException; import org.playorm.nio.api.handlers.OperationCallback; import org.playorm.nio.api.handlers.TimeoutException; public class FutureOperationImpl implements FutureOperation, OperationCallback { private RegisterableChannel channel; private Throwable e; private OperationCallback operationCallback; @Override public synchronized void finished(Channel channel) throws IOException { this.channel = channel; this.notify(); if(operationCallback != null) operationCallback.finished(channel); } @Override public synchronized void failed(RegisterableChannel channel, Throwable e) { this.channel = channel; this.e = e; this.notify(); if(operationCallback != null) operationCallback.failed(channel, e); } @Override public synchronized void waitForOperation(long timeoutInMillis) { if(channel != null) { if(e != null) throw new RuntimeException(e); return; } try { if(timeoutInMillis > 0) { this.wait(timeoutInMillis); } else this.wait(); } catch(InterruptedException e) { throw new NioInterruptException(e); } if(channel == null) throw new TimeoutException("Waited for operation for time="+timeoutInMillis+" but did not complete"); } @Override public synchronized void waitForOperation() { waitForOperation(0); } @Override public synchronized void setListener(OperationCallback cb) { if(channel != null) { if(e != null) { cb.failed(channel, e); } else fireFinished(cb); return; } operationCallback = cb; } private void fireFinished(OperationCallback cb) { try { cb.finished((Channel) channel); } catch (IOException e) { throw new RuntimeException(e); } } }