Author: mheath
Date: Tue Jan 23 22:00:32 2007
New Revision: 499269

URL: http://svn.apache.org/viewvc?view=rev&rev=499269
Log:
Updated API.  Started work on implementing asynchronous opens.

Added:
    mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Modes.java
      - copied, changed from r498707, 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Flags.java
    
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/AioFutureImpl.java
    
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannel.java
    mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/test/
Removed:
    mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Flags.java
Modified:
    mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java
    
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java
    
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelFactory.java
    
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelProvider.java
    
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannelProvider.java

Modified: 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java?view=diff&rev=499269&r1=499268&r2=499269
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java 
(original)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java 
Tue Jan 23 22:00:32 2007
@@ -19,7 +19,6 @@
  */
 package org.apache.aio;
 
-import java.nio.channels.FileLock;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
@@ -38,21 +37,21 @@
  * @param <F>  The type of <tt>AioFuture</tt> passed into the [EMAIL 
PROTECTED] AioCompletionHandler}'s associated with this
  *             future
  */
-public interface AioFuture<V, F extends AioFuture> extends Future<V> {
+public interface AioFuture<V> extends Future<V> {
     
-    static interface BatchFuture extends AioFuture<Long, BatchFuture> {
+    static interface BatchFuture extends AioFuture<Long> {
         ByteBufferPosition[] getBatch();
     }
 
-    static interface ByteBufferFuture extends AioFuture<Integer, 
ByteBufferFuture>, ByteBufferPosition {}
+    static interface ByteBufferFuture extends AioFuture<Integer>, 
ByteBufferPosition {}
     
-    static interface LockFuture extends AioFuture<FileLock, LockFuture> {}
+    //static interface LockFuture extends AioFuture<FileLock, LockFuture> {}
     
-    static interface OpenFuture extends AioFuture<AsynchronousFileChannel, 
OpenFuture> {}
+    //static interface OpenFuture extends AioFuture<AsynchronousFileChannel, 
OpenFuture> {}
     
-    static interface SyncFuture extends AioFuture<Void, SyncFuture> {}
+    //static interface SyncFuture extends AioFuture<Void, SyncFuture> {}
     
-    static interface TruncateFuture extends AioFuture<Void, TruncateFuture> {}
+    //static interface TruncateFuture extends AioFuture<Void, TruncateFuture> 
{}
     
     /**
      * Associates a [EMAIL PROTECTED] AioCompletionHandler} with this future.  
The completion handler will be invoked when
@@ -60,7 +59,7 @@
      * 
      * @param completionHandler  The completion handler to be invoked.
      */
-    void addCompletionHandler(AioCompletionHandler<F> completionHandler);
+    void addCompletionHandler(AioCompletionHandler<AioFuture> 
completionHandler);
 
     /**
      * Removes a [EMAIL PROTECTED] AioCompletionHandler} from this future.
@@ -68,7 +67,7 @@
      * @param completionHandler  The completion handler to be disassociated 
with this future
      * @return  Returns true if the completion handler was disassociated with 
this future, false otherwise.
      */
-    boolean removeCompletionHandler(AioCompletionHandler<F> completionHandler);
+    boolean removeCompletionHandler(AioCompletionHandler<AioFuture> 
completionHandler);
 
     /**
      * Returns the [EMAIL PROTECTED] AsynchronousFileChannel} where the 
operation represnted by this future orginated.

Modified: 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java?view=diff&rev=499269&r1=499268&r2=499269
==============================================================================
--- 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java
 (original)
+++ 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java
 Tue Jan 23 22:00:32 2007
@@ -27,9 +27,6 @@
 
 import org.apache.aio.AioFuture.BatchFuture;
 import org.apache.aio.AioFuture.ByteBufferFuture;
-import org.apache.aio.AioFuture.LockFuture;
-import org.apache.aio.AioFuture.SyncFuture;
-import org.apache.aio.AioFuture.TruncateFuture;
 
 /**
  * A channel for reading, writing and manipulating a file in an asynchronous 
manner.
@@ -96,7 +93,7 @@
      * @see #tryLock()
      * @see #tryLock(long,long,boolean)
      */
-    public LockFuture lock() {
+    public AioFuture<FileLock> lock() {
         return lock(0L, Long.MAX_VALUE, false);
     }
 
@@ -138,7 +135,7 @@
      * @see     #tryLock()
      * @see     #tryLock(long,long,boolean)
      */
-    public abstract LockFuture lock(long position, long size, boolean shared) 
throws AioException;
+    public abstract AioFuture<FileLock> lock(long position, long size, boolean 
shared) throws AioException;
 
     /**
      * Attempts to acquire an exclusive lock on this channel's file.
@@ -212,7 +209,7 @@
      *          callbacks will be invoked when the sync has completed.
      * @throws AioException  Thrown if an error occurs scheduling the sync 
operation.
      */
-    public abstract SyncFuture sync(boolean metaData) throws AioException;
+    public abstract AioFuture<Void> sync(boolean metaData) throws AioException;
 
     /**
      * Reads a sequence of bytes from this channel into the given buffer, 
starting at the given file position.
@@ -252,8 +249,6 @@
      * <p>This method is able to schedule multiple reads with a single call.  
On some platforms this can allow multiple
      * reads to be sheduled with a single system call.
      * 
-     * <p>TODO Determin what the future's get method should return.
-     * 
      * @param byteBufferPositions  The ByteBufferPositions that indicate what 
buffers to read data into and which file
      *                             positions in the file should be read
      * @param offset  The offset within the byteBufferPositions array of the 
first byteBufferPositions into which date
@@ -312,7 +307,7 @@
      * @return  A TruncateFuture object representing the pending result
      * @throws AioException  Thrown if an occurs occurs scheduling the 
truncation
      */
-    public abstract TruncateFuture truncate(long size) throws AioException;
+    public abstract AioFuture<Void> truncate(long size) throws AioException;
 
     /**
      * Closes the file channel.

Modified: 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelFactory.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelFactory.java?view=diff&rev=499269&r1=499268&r2=499269
==============================================================================
--- 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelFactory.java
 (original)
+++ 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelFactory.java
 Tue Jan 23 22:00:32 2007
@@ -19,11 +19,10 @@
  */
 package org.apache.aio;
 
-import java.util.EnumSet;
+import java.io.File;
 import java.util.Properties;
 import java.util.concurrent.ExecutorService;
 
-import org.apache.aio.AioFuture.OpenFuture;
 import org.apache.aio.concurrent.ConcurrentAsynchronousFileChannelProvider;
 import org.apache.aio.posix.PosixAsynchronousFileChannelProvider;
 
@@ -44,16 +43,16 @@
         return ConcurrentAsynchronousFileChannelProvider.class.getName();
     }
 
-    public static OpenFuture open(String fileName, EnumSet<Flags> flags) {
-        return open(fileName, flags, null);
+    public static AioFuture<AsynchronousFileChannel> open(File file, Modes 
mode) {
+        return open(file, mode, null);
     }
     
-    public static OpenFuture open(String fileName, EnumSet<Flags> flags, 
ExecutorService executorService) {
-        return open(fileName, flags, executorService, System.getProperties());
+    public static AioFuture<AsynchronousFileChannel> open(File file, Modes 
mode, ExecutorService executorService) {
+        return open(file, mode, executorService, System.getProperties());
     }
 
     @SuppressWarnings("unchecked")
-    public static OpenFuture open(final String fileName, final EnumSet<Flags> 
flags, ExecutorService executorService, final Properties properties) {
+    public static AioFuture<AsynchronousFileChannel> open(final File file, 
final Modes mode, ExecutorService executorService, final Properties properties) 
{
         String systemProvider = System.getProperty(
                 PROPERTY_ASYNCHRONOUS_FILE_CHANNEL_PROVIDER,
                 asynchronousFileChannelProvider);
@@ -61,12 +60,10 @@
         try {
             Class<? extends AsynchronousFileChannelProvider> clazz = (Class<? 
extends AsynchronousFileChannelProvider>)Class.forName(providerName);
             AsynchronousFileChannelProvider provider = clazz.newInstance();
-            return provider.open(fileName, flags, executorService, properties);
-        } catch (ClassNotFoundException e) {
-            throw new AioException(e);
-        } catch (InstantiationException e) {
-            throw new AioException(e);
-        } catch (IllegalAccessException e) {
+            return provider.open(file, mode, executorService, properties);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
             throw new AioException(e);
         }
     }

Modified: 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelProvider.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelProvider.java?view=diff&rev=499269&r1=499268&r2=499269
==============================================================================
--- 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelProvider.java
 (original)
+++ 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannelProvider.java
 Tue Jan 23 22:00:32 2007
@@ -19,12 +19,10 @@
  */
 package org.apache.aio;
 
-import java.util.EnumSet;
+import java.io.File;
 import java.util.Properties;
 import java.util.concurrent.ExecutorService;
 
-import org.apache.aio.AioFuture.OpenFuture;
-
 public interface AsynchronousFileChannelProvider {
 
     /**
@@ -35,6 +33,6 @@
      * @param properties
      * @return
      */
-    public OpenFuture open(final String fileName, final EnumSet<Flags> flags, 
ExecutorService executorService, final Properties properties);
+    public AioFuture<AsynchronousFileChannel> open(File fileName, Modes mode, 
ExecutorService executorService, Properties properties);
     
 }

Copied: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Modes.java 
(from r498707, 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Flags.java)
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Modes.java?view=diff&rev=499269&p1=mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Flags.java&r1=498707&p2=mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Modes.java&r2=499269
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Flags.java 
(original)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Modes.java Tue 
Jan 23 22:00:32 2007
@@ -24,22 +24,23 @@
  * 
  * @author mheath
  */
-public enum Flags {
+public enum Modes {
     /**
      * Indicates the [EMAIL PROTECTED] AsynchronousFileChannel} should be 
opened in read-only mode.
      */
-    READ_ONLY,
-    /**
-     * Indicates the [EMAIL PROTECTED] AsynchronousFileChannel} should be 
opened in write-only mode.
-     */
-    WRITE_ONLY,
+    READ_ONLY("r"),
     /**
      * Indicates the [EMAIL PROTECTED] AsynchronousFileChannel} should be 
opened in read-write mode.
      */
-    READ_WRITE,
-    /**
-     * If the [EMAIL PROTECTED] AsynchronousFileChannel} is opened for 
writing, indicates if the file should be appeneded instead
-     * of truncating the file to 0 bytes when opened.
-     */
-    APPEND
+    READ_WRITE("rw");
+    
+    private final String modeString;
+    
+    private Modes(String modeString) {
+        this.modeString = modeString;
+    }
+    
+    public String getModeString() {
+        return modeString;
+    }
 }

Added: 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/AioFutureImpl.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/AioFutureImpl.java?view=auto&rev=499269
==============================================================================
--- 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/AioFutureImpl.java
 (added)
+++ 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/AioFutureImpl.java
 Tue Jan 23 22:00:32 2007
@@ -0,0 +1,155 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.aio.concurrent;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.aio.AioCallbackException;
+import org.apache.aio.AioCompletionHandler;
+import org.apache.aio.AioFuture;
+import org.apache.aio.AsynchronousFileChannel;
+import org.apache.aio.ByteBufferPosition;
+
+public class AioFutureImpl<V> implements AioFuture<V> {
+
+    public static class BatchFutureImpl extends AioFutureImpl<Long> implements 
BatchFuture {
+
+        private final ByteBufferPosition[] batch;
+        
+        public BatchFutureImpl(ByteBufferPosition[] batch) {
+            this.batch = batch;
+        }
+        
+        public ByteBufferPosition[] getBatch() {
+            return batch;
+        }
+
+    }
+    
+    public static class ByteBufferFutureImpl extends AioFutureImpl<Integer> 
implements ByteBufferFuture {
+
+        private final ByteBuffer byteBuffer;
+        private final long position;
+        
+        public ByteBufferFutureImpl(ByteBuffer byteBuffer, long position) {
+            this.byteBuffer = byteBuffer;
+            this.position = position;
+        }
+        
+        public ByteBuffer getByteBuffer() {
+            return byteBuffer;
+        }
+
+        public long position() {
+            return position;
+        }
+        
+    }
+    
+//    public static class LockFutureImpl extends AbstractAioFuture<FileLock, 
LockFuture> implements LockFuture {
+//        
+//    }
+//    
+//    public static class OpenFutureImpl extends 
AbstractAioFuture<AsynchronousFileChannel, OpenFuture> implements OpenFuture {
+//        
+//    }
+//    
+//    public static class SyncFutureImpl
+//    
+//    public static class TruncateFutureImpl
+//    
+    private Future<V> future;
+    private Object attachment = null;
+    private AsynchronousFileChannel asynchronousFileChannel = null;
+    private final List<AioCompletionHandler<AioFuture>> completionHandlers = 
new ArrayList<AioCompletionHandler<AioFuture>>();
+    private ExecutionException exception;
+    
+    public synchronized void 
addCompletionHandler(AioCompletionHandler<AioFuture> completionHandler) {
+        completionHandlers.add(completionHandler);
+    }
+
+    public synchronized boolean 
removeCompletionHandler(AioCompletionHandler<AioFuture> completionHandler) {
+        return completionHandlers.remove(completionHandler);
+    }
+    
+    public synchronized void callCompletionHandlers() {
+        try {
+            for (AioCompletionHandler<AioFuture> completionHandler : 
completionHandlers) {
+                completionHandler.onCompletion(this);
+            }
+        } catch (Throwable e) {
+            exception = new ExecutionException(e);
+        }
+    }
+
+    public V get() throws InterruptedException, ExecutionException, 
AioCallbackException {
+        if (exception != null) {
+            throw exception;
+        }
+        return future.get();
+    }
+
+    public V get(long timeout, TimeUnit unit) throws InterruptedException, 
ExecutionException, TimeoutException {
+        if (exception != null) {
+            throw exception;
+        }
+        return future.get(timeout, unit);
+    }
+
+    public Object getAttachment() {
+        return attachment;
+    }
+
+    public void setAttachment(Object attachment) {
+        this.attachment = attachment;
+    }
+
+    public AsynchronousFileChannel getChannel() {
+        return asynchronousFileChannel;
+    }
+
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        // TODO: We may have to close the channel per JSR-203
+        return future.cancel(true);
+    }
+
+    public boolean isCancelled() {
+        return future.isCancelled();
+    }
+
+    public boolean isDone() {
+        return future.isDone();
+    }
+
+    public Future<V> getFuture() {
+        return future;
+    }
+
+    public void setFuture(Future<V> future) {
+        this.future = future;
+    }
+
+}

Added: 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannel.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannel.java?view=auto&rev=499269
==============================================================================
--- 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannel.java
 (added)
+++ 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannel.java
 Tue Jan 23 22:00:32 2007
@@ -0,0 +1,114 @@
+package org.apache.aio.concurrent;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.util.concurrent.ExecutorService;
+
+import org.apache.aio.AioException;
+import org.apache.aio.AioFuture;
+import org.apache.aio.AsynchronousFileChannel;
+import org.apache.aio.ByteBufferPosition;
+import org.apache.aio.Modes;
+import org.apache.aio.AioFuture.BatchFuture;
+import org.apache.aio.AioFuture.ByteBufferFuture;
+
+public class ConcurrentAsynchronousFileChannel extends AsynchronousFileChannel 
{
+
+    private final FileChannel channel;
+    private final ExecutorService service;
+    private final Modes mode;
+    
+    public ConcurrentAsynchronousFileChannel(FileChannel channel, Modes mode, 
ExecutorService service) {
+        this.channel = channel;
+        this.mode = mode;
+        this.service = service;
+    }
+    
+
+    @Override
+    public void close() throws AioException {
+        try {
+            channel.close();
+        } catch (IOException e) {
+            throw new AioException(e);
+        }
+    }
+
+    @Override
+    public boolean isReadable() throws AioException {
+        return true;
+    }
+
+    @Override
+    public boolean isWriteable() throws AioException {
+        return mode == Modes.READ_WRITE;
+    }
+
+    @Override
+    public AioFuture<FileLock> lock(long position, long size, boolean shared) 
throws AioException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ByteBufferFuture read(ByteBuffer buffer, long position) throws 
AioException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BatchFuture read(ByteBufferPosition[] byteBufferPositions, int 
offset, int length) throws AioException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public long size() throws AioException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public AioFuture<Void> sync(boolean metaData) throws AioException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AioFuture<Void> truncate(long size) throws AioException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public FileLock tryLock() throws AioException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public FileLock tryLock(long position, long size, boolean shared) throws 
AioException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ByteBufferFuture write(ByteBuffer buffer, long position) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BatchFuture write(ByteBufferPosition[] byteBufferPositions, int 
offset, int length) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public boolean isOpen() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

Modified: 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannelProvider.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannelProvider.java?view=diff&rev=499269&r1=499268&r2=499269
==============================================================================
--- 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannelProvider.java
 (original)
+++ 
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/concurrent/ConcurrentAsynchronousFileChannelProvider.java
 Tue Jan 23 22:00:32 2007
@@ -19,6 +19,82 @@
  */
 package org.apache.aio.concurrent;
 
-public class ConcurrentAsynchronousFileChannelProvider {
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.aio.AioException;
+import org.apache.aio.AioFuture;
+import org.apache.aio.AsynchronousFileChannel;
+import org.apache.aio.AsynchronousFileChannelProvider;
+import org.apache.aio.Modes;
+
+public class ConcurrentAsynchronousFileChannelProvider implements 
AsynchronousFileChannelProvider {
+
+    public static final String PROPERTY_DEFAULT_THREAD_POOL_SIZE =
+            ConcurrentAsynchronousFileChannelProvider.class.getName() + 
".defaultThreadPoolSize";
+
+    private static final Integer DEFAULT_THREAD_POOL_SIZE = 
(Runtime.getRuntime().availableProcessors() + 1) * 2;
+
+    private static ExecutorService staticExecutorService;
+
+    public AioFuture<AsynchronousFileChannel> open(
+            final File file,
+            final Modes mode,
+            final ExecutorService executorService,
+            final Properties properties) {
+        
+        // Determine which ExecutorService to use
+        final ExecutorService service;
+        if (executorService == null) {
+            service = getExecutorService();
+        } else {
+            service = executorService;
+        }
+        
+        final AioFutureImpl<AsynchronousFileChannel> aioFuture = new 
AioFutureImpl<AsynchronousFileChannel>();
+        
+        Future<AsynchronousFileChannel> future = service.submit(new 
Callable<AsynchronousFileChannel>() {
+            public AsynchronousFileChannel call() throws Exception {
+                final FileChannel channel = new RandomAccessFile(file, 
mode.getModeString()).getChannel();
+                AsynchronousFileChannel afc = new 
ConcurrentAsynchronousFileChannel(channel, mode, service);
+                
+                // Call completion handlers
+                service.submit(new Runnable() {
+                   public void run() {
+                       aioFuture.callCompletionHandlers();
+                    } 
+                });
+                
+                return afc;
+            }
+        });
+        aioFuture.setFuture(future);
+        
+        return aioFuture;
+    }
+
+    private static synchronized ExecutorService getExecutorService() {
+        if (staticExecutorService == null) {
+            staticExecutorService = 
Executors.newFixedThreadPool(getThreadPoolSizeSetting());
+        }
+        return staticExecutorService;
+    }
+
+    private static int getThreadPoolSizeSetting() {
+        String threadPoolSize = 
System.getProperty(PROPERTY_DEFAULT_THREAD_POOL_SIZE, DEFAULT_THREAD_POOL_SIZE
+                .toString());
+        try {
+            return Integer.valueOf(threadPoolSize);
+        } catch (NumberFormatException e) {
+            throw new AioException(String.format("Property '%s' contains the 
value '%s' which is not a valid integer",
+                    PROPERTY_DEFAULT_THREAD_POOL_SIZE, threadPoolSize), e);
+        }
+    }
 
 }


Reply via email to