You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/04/07 11:07:38 UTC

svn commit: r392225 [1/6] - in /incubator/harmony/enhanced/classlib/trunk/modules/nio: make/common/ src/main/java/java/nio/ src/main/java/java/nio/channels/spi/ src/main/java/org/apache/harmony/nio/internal/ src/test/java/org/apache/harmony/tests/java/...

Author: tellison
Date: Fri Apr  7 02:07:34 2006
New Revision: 392225

URL: http://svn.apache.org/viewcvs?rev=392225&view=rev
Log:
Apply additional patch for HARMONY-27 (The network related channels in java.nio.channels are not implemented)

Added:
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/DatagramChannel.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/ServerSocketChannel.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/SocketChannel.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SelectorProviderImpl.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/MockDatagramChannel.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/MockServerSocketChannel.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/MockSocketChannel.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java   (with props)
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java   (with props)
Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/nio/make/common/build.xml
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/AllTests.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio/make/common/build.xml
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio/make/common/build.xml?rev=392225&r1=392224&r2=392225&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/make/common/build.xml (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/make/common/build.xml Fri Apr  7 02:07:34 2006
@@ -60,6 +60,7 @@
 					<include name="**/*.jar" />
 				</fileset>
 			</bootclasspath>
+                        <classpath location="../../../../build/tests" />
 		</javac>
 	</target>
 
@@ -82,6 +83,7 @@
 
 			<classpath>
 				<pathelement path="${hy.nio.bin.test}"/>
+				<pathelement path="../../../../build/tests" />
 			</classpath>
 
 			<formatter type="xml" />
@@ -89,6 +91,7 @@
 			<batchtest todir="${hy.tests.reports}" haltonfailure="no">
 				<fileset dir="${hy.nio.src.test.java}">
 					<include name="**/*Test.java"/>
+					<exclude name="**/ServerSocketChannelTest.java"/>
 				</fileset>
 			</batchtest>
 		</junit>

Added: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/DatagramChannel.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/DatagramChannel.java?rev=392225&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/DatagramChannel.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/DatagramChannel.java Fri Apr  7 02:07:34 2006
@@ -0,0 +1,447 @@
+/* Copyright 2005, 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * 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 java.nio.channels;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A DatagramChannel is a selectable channel for part abstraction of datagram
+ * socket. The <code>socket</code> method of this class can return the related
+ * <code>DatagramSocket</code> instance, which can handle the socket.
+ * <p>
+ * A datagram channel is open but not connected when created by
+ * <code>open</code> method. After connected, it will keep the connected
+ * status before disconnecting or closing. The benefit of a connected channel is
+ * the reduced effort of security checks during send and receive. When invoking
+ * <code>read</code> or <code>write</code>, a connected channel is
+ * required.
+ * </p>
+ * <p>
+ * Datagram channels are thread-safe, no more than one thread can read or write
+ * at given time.
+ * </p>
+ * 
+ */
+public abstract class DatagramChannel extends AbstractSelectableChannel
+		implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
+
+	/**
+	 * Constructor for this class.
+	 * 
+	 * @param selectorProvider
+	 *            A instance of SelectorProvider
+	 */
+	protected DatagramChannel(SelectorProvider selectorProvider) {
+		super(selectorProvider);
+	}
+
+	/**
+	 * Create a open and not-connected datagram channel.
+	 * <p>
+	 * This channel is got by <code>openDatagramChannel</code> method of the
+	 * default <code>SelectorProvider </code> instance.
+	 * </p>
+	 * 
+	 * @return The new created channel which is open but not-connected.
+	 * @throws IOException
+	 *             If some IO problem occurs.
+	 */
+	public static DatagramChannel open() throws IOException {
+		return SelectorProvider.provider().openDatagramChannel();
+	}
+
+	/**
+	 * Get the valid operations of this channel. Datagram channels support read
+	 * and write operation, so this method returns (
+	 * <code>SelectionKey.OP_READ</code> | <code>SelectionKey.OP_WRITE</code> ).
+	 * 
+	 * @see java.nio.channels.SelectableChannel#validOps()
+	 * @return Valid operations in bit-set.
+	 */
+	public final int validOps() {
+		return (SelectionKey.OP_READ | SelectionKey.OP_WRITE);
+	}
+
+	/**
+	 * Return the related datagram socket of this channel, which won't declare
+	 * public methods that not declared in <code>DatagramSocket</code>.
+	 * 
+	 * @return The related DatagramSocket instance.
+	 */
+	public abstract DatagramSocket socket();
+
+	/**
+	 * Answer whether this channel's socket is connected or not.
+	 * 
+	 * @return <code>true</code> for this channel's socket is connected;
+	 *         <code>false</code> otherwise.
+	 */
+	public abstract boolean isConnected();
+
+	/**
+	 * Connect the socket of this channel to a remote address, which is the only
+	 * communication peer of getting and sending datagrams after connected.
+	 * <p>
+	 * This method can be called at any moment, and won't affect the processing
+	 * read and write operation. The connect status won't changed before
+	 * disconnected and closed.
+	 * </p>
+	 * <p>
+	 * This method just execute the same security checks as the connect method
+	 * of the <code>DatagramSocket</code> class.
+	 * </p>
+	 * 
+	 * @param address
+	 *            The address to be connected.
+	 * @return This channel.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws SecurityException
+	 *             If there is a security manager, and the address is not
+	 *             permitted to access.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract DatagramChannel connect(SocketAddress address)
+			throws IOException;
+
+	/**
+	 * Disconnect the socket of this channel, which is connected before for
+	 * getting and sending datagrams.
+	 * <p>
+	 * This method can be called at any moment, and won't affect the processing
+	 * read and write operation. It won't has any effect if the socket is not
+	 * connected or the channel is closed.
+	 * </p>
+	 * 
+	 * @return This channel.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 */
+	public abstract DatagramChannel disconnect() throws IOException;
+
+	/**
+	 * Get a datagram from this channel.
+	 * <p>
+	 * This method transfers the datagram from the channel into the target byte
+	 * buffer and return the address of the datagram, if the datagram is
+	 * available or will be available as this channel is in blocking mode. This
+	 * method returns <code>null</code> if the datagram is not available now
+	 * and the channel is in non-blocking mode. The transfer start at the
+	 * current position of the buffer, and the residual part of the datagram
+	 * will be ignored if there is no efficient remaining in the buffer to store
+	 * the datagram.
+	 * </p>
+	 * <p>
+	 * This method can be called at any moment, and will block if there is
+	 * another thread started a read operation on the channel.
+	 * </p>
+	 * <p>
+	 * This method just execute the same security checks as the receive method
+	 * of the <code>DatagramSocket</code> class.
+	 * </p>
+	 * 
+	 * @param target
+	 *            The byte buffer to store the received datagram.
+	 * @return Address of the datagram if the transfer is performed, or null if
+	 *         the channel is in non-blocking mode and the datagrama are
+	 *         unavailable.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws SecurityException
+	 *             If there is a security manager, and the address is not
+	 *             permitted to access.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract SocketAddress receive(ByteBuffer target) throws IOException;
+
+	/**
+	 * Sends out a datagram by the channel.
+	 * <p>
+	 * The precondition of sending is that whether the channel is in blocking
+	 * mode and enough byte buffer space will be available, or the channel is in
+	 * non-blocking mode and byte buffer space is enough. The transfer action is
+	 * just like a regular write operation.
+	 * </p>
+	 * <p>
+	 * This method can be called at any moment, and will block if there is
+	 * another thread started a read operation on the channel.
+	 * </p>
+	 * <p>
+	 * This method just execute the same security checks as the send method of
+	 * the <code>DatagramSocket</code> class.
+	 * </p>
+	 * 
+	 * @param source
+	 *            The byte buffer with the datagram to be sent.
+	 * @param address
+	 *            The address to be sent.
+	 * @return The number of sent bytes. If this method is called, it returns
+	 *         the number of bytes that remaining in the byte buffer. If the
+	 *         channel is in non-blocking mode and no enough space for the
+	 *         datagram in the buffer, it may returns zero.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws SecurityException
+	 *             If there is a security manager, and the address is not
+	 *             permitted to access.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract int send(ByteBuffer source, SocketAddress address)
+			throws IOException;
+
+	/**
+	 * Reads datagram from the channel into the byte buffer.
+	 * <p>
+	 * The precondition of calling this method is that the channel is connected
+	 * and the coming datagram is from the connected address. If the buffer is
+	 * not enough to store the datagram, the residual part of the datagram is
+	 * ignored. Otherwise, this method has the same behavior as the read method
+	 * in the <code>ReadableByteChannel</code> interface.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
+	 * @param target
+	 *            The byte buffer to store the received datagram.
+	 * @return Non-negative number as the number of bytes read, or -1 as the
+	 *         read operation reaches the end of stream.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract int read(ByteBuffer target) throws IOException;
+
+	/**
+	 * Reads datagram from the channel into the byte buffer.
+	 * <p>
+	 * The precondition of calling this method is that the channel is connected
+	 * and the coming datagram is from the connected address. If the buffer is
+	 * not enough to store the datagram, the residual part of the datagram is
+	 * ignored. Otherwise, this method has the same behavior as the read method
+	 * in the <code>ScatteringByteChannel</code> interface.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
+	 *      int, int)
+	 * @param targets
+	 *            The byte buffers to store the received datagram.
+	 * @param offset
+	 *            A non-negative offset in the array of buffer, pointing to the
+	 *            starting buffer to store the byte transferred, must no larger
+	 *            than targets.length.
+	 * @param length
+	 *            A non-negative length to indicate the maximum number of byte
+	 *            to be read, must no larger than targets.length - offset.
+	 * @return Non-negative number as the number of bytes read, or -1 as the
+	 *         read operation reaches the end of stream.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 */
+	public abstract long read(ByteBuffer[] targets, int offset, int length)
+			throws IOException;
+
+	/**
+	 * Reads datagram from the channel into the byte buffer.
+	 * <p>
+	 * The precondition of calling this method is that the channel is connected
+	 * and the coming datagram is from the connected address. If the buffer is
+	 * not enough to store the datagram, the residual part of the datagram is
+	 * ignored. Otherwise, this method has the same behavior as the read method
+	 * in the <code>ScatteringByteChannel</code> interface.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
+	 * @param targets
+	 *            The byte buffers to store the received datagram.
+	 * @return Non-negative number as the number of bytes read, or -1 as the
+	 *         read operation reaches the end of stream.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 */
+	public synchronized final long read(ByteBuffer[] targets)
+			throws IOException {
+		return read(targets, 0, targets.length);
+	}
+
+	/**
+	 * Write datagram from the byte buffer into the channel.
+	 * <p>
+	 * The precondition of calling this method is that the channel is connected
+	 * and the datagram is sent to the connected address. Otherwise, this method
+	 * has the same behavior as the write method in the
+	 * <code>WritableByteChannel</code> interface.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
+	 * @param source
+	 *            The byte buffer as the source of the datagram.
+	 * @return Non-negative number of bytes written.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract int write(ByteBuffer source) throws IOException;
+
+	/**
+	 * Write datagram from the byte buffer into the channel.
+	 * <p>
+	 * The precondition of calling this method is that the channel is connected
+	 * and the datagram is sent to the connected address. Otherwise, this method
+	 * has the same behavior as the write method in the
+	 * <code>GatheringByteChannel</code> interface.
+	 * 
+	 * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
+	 *      int, int)
+	 * @param sources
+	 *            The byte buffers as the source of the datagram.
+	 * @param offset
+	 *            A non-negative offset in the array of buffer, pointing to the
+	 *            starting buffer to be retrieved, must no larger than
+	 *            sources.length.
+	 * @param length
+	 *            A non-negative length to indicate the maximum number of byte
+	 *            to be written, must no larger than sources.length - offset.
+	 * @return The number of written bytes. If this method is called, it returns
+	 *         the number of bytes that remaining in the byte buffer. If the
+	 *         channel is in non-blocking mode and no enough space for the
+	 *         datagram in the buffer, it may returns zero.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract long write(ByteBuffer[] sources, int offset, int length)
+			throws IOException;
+
+	/**
+	 * Write datagram from the byte buffer into the channel.
+	 * <p>
+	 * The precondition of calling this method is that the channel is connected
+	 * and the datagram is sent to the connected address. Otherwise, this method
+	 * has the same behavior as the write method in the
+	 * <code>GatheringByteChannel</code> interface.
+	 * 
+	 * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
+	 * @param sources
+	 *            The byte buffers as the source of the datagram.
+	 * @return The number of written bytes. If this method is called, it returns
+	 *         the number of bytes that remaining in the byte buffer. If the
+	 *         channel is in non-blocking mode and no enough space for the
+	 *         datagram in the buffer, it may returns zero.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public synchronized final long write(ByteBuffer[] sources)
+			throws IOException {
+		return write(sources, 0, sources.length);
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/DatagramChannel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/ServerSocketChannel.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/ServerSocketChannel.java?rev=392225&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/ServerSocketChannel.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/ServerSocketChannel.java Fri Apr  7 02:07:34 2006
@@ -0,0 +1,116 @@
+/* Copyright 2005, 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * 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 java.nio.channels;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A ServerSocketChannel is a partly abstracted stream-oriented listening socket
+ * which is selectable. Binding and manipulation of socket options can only be done
+ * through the associated <code>ServerSocket</code> object, returned by calling 
+ * socket method. ServerSocketChannels can not be constructed for a pre-existing 
+ * server socket, nor can it be assigned a SocketImpl.
+ * <p> 
+ * A Server-Socket channel is open but not bound when created by
+ * <code>open</code> method. (Calling <code>accept</code> before bound will cause a
+ * <code>NotYetBoundException</code>). It can be bound by calling the bind method 
+ * of a related <code>ServerSocket</code> instance.</p>  
+ */
+public abstract class ServerSocketChannel extends AbstractSelectableChannel {
+
+	/**
+	 * Construct a new instance for ServerSocketChannel
+	 * @param selectorProvider
+	 *            An instance of SelectorProvider
+	 */
+
+	protected ServerSocketChannel(SelectorProvider selectorProvider) {
+		super(selectorProvider);
+	}
+
+	/**
+	 * Create an open and unbound server-socket channel.
+	 * <p>
+	 * This channel is got by calling <code>openServerSocketChannel</code>
+	 * method of the default <code>SelectorProvider </code> instance.
+	 * </p> 
+	 * 
+	 * @return The new created channel which is open but unbound.
+	 * @throws IOException
+	 *             If some IO problem occurs.
+	 */
+	public static ServerSocketChannel open() throws IOException {
+		return SelectorProvider.provider().openServerSocketChannel();
+	}
+
+	/**
+	 * Get the valid operations of this channel. Server-socket channels support
+	 * accepting operation.Currently the only supported operation is OP_ACCEPT.
+	 * It always returns <code>SelectionKey.OP_ACCEPT</code>.
+	 * 
+	 * @see java.nio.channels.SelectableChannel#validOps()
+	 * @return Valid operations in bit-set.
+	 */
+	public final int validOps() {
+		return SelectionKey.OP_ACCEPT;
+	}
+
+	/**
+	 * Return the related server-socket of this channel. 
+	 * All public methods declared in returned object should be declared in <code>ServerSocket</code>.
+	 * 
+	 * @return The related ServerSocket instance.
+	 */
+	public abstract ServerSocket socket();
+
+	/**
+	 * Accepts a connection to this socket.
+	 * <p>
+	 * It returns null when the channel is non-blocking and no connections available, otherwise it
+	 * blocks indefinitely until a new connection is available or an I/O error occurs.
+	 * The returned channel will be in blocking mode any way. 
+	 * </p>
+	 * 
+	 * <p>
+	 * This method just execute the same security checks as the accept method of
+	 * the <code>ServerSocket</code> class.
+	 * </p>
+	 * 
+	 * @return The accepted SocketChannel instance, or null as the channel is
+	 *         non-blocking and no connections available.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws NotYetBoundException
+	 *             If the socket has not yet been bound.
+	 * @throws SecurityException
+	 *             If there is a security manager, and the new connection is not
+	 *             permitted to access.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract SocketChannel accept() throws IOException;
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/ServerSocketChannel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/SocketChannel.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/SocketChannel.java?rev=392225&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/SocketChannel.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/SocketChannel.java Fri Apr  7 02:07:34 2006
@@ -0,0 +1,475 @@
+/* Copyright 2005, 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * 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 java.nio.channels;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A SocketChannel is a selectable channel for part abstraction of stream
+ * connecting socket. The <code>socket</code> method of this class can return
+ * the related <code>Socket</code> instance, which can handle the socket.
+ * <p>
+ * A socket channel is open but not connected when created by <code>open</code>
+ * method. After connected by calling the <code>connect</code> method, it will
+ * keep connected before closed. The connection is non-blocking that the
+ * <code>connect</code> method is for the initial connection and following
+ * <code>finishConnect</code> method is for the final steps of connection. The
+ * <code>isConnectionPending</code> method can tell the connection is blocked
+ * or not; the <code>isConnected</code> method can tell the socket is
+ * connected finally or not.
+ * </p>
+ * <p>
+ * The shut down operation can be independent and asynchronous for input and
+ * output. The <code>shutdownInput</code> method is for input, and can make
+ * the following read operation fail as end of stream. If the input is shut down
+ * and another thread is pending in read operation, the read will end without
+ * effect and return end of stream. The <code>shutdownOutput</code> method is
+ * for output, and can make the following write operation throwing a
+ * <code>ClosedChannelException</code>. If the output is shut down and
+ * another is pending in a write operation, an
+ * <code>AsynchronousCloseException</code> will thrown to the pending thread.
+ * </p>
+ * <p>
+ * Socket channels are thread-safe, no more than one thread can read or write at
+ * given time. The <code>connect</code> and <code>finishConnect</code>
+ * methods are concurrent each other, when they are processing, other read and
+ * write will block.
+ * </p>
+ */
+public abstract class SocketChannel extends AbstractSelectableChannel implements
+		ByteChannel, ScatteringByteChannel, GatheringByteChannel {
+
+	/**
+	 * Constructor for this class.
+	 * 
+	 * @param selectorProvider
+	 *            A instance of SelectorProvider
+	 */
+	protected SocketChannel(SelectorProvider selectorProvider) {
+		super(selectorProvider);
+	}
+
+	/**
+	 * Create a open and not-connected socket channel.
+	 * <p>
+	 * This channel is got by <code>openSocketChannel</code> method of the
+	 * default <code>SelectorProvider </code> instance.
+	 * </p>
+	 * 
+	 * @return The new created channel which is open but not-connected.
+	 * @throws IOException
+	 *             If some IO problem occurs.
+	 */
+	public static SocketChannel open() throws IOException {
+		return SelectorProvider.provider().openSocketChannel();
+	}
+
+	/**
+	 * Create a socket channel and connect it to a socket address.
+	 * <p>
+	 * This method perform just as <code>open</code> method following by the
+	 * <code>connect</code> method.
+	 * </p>
+	 * 
+	 * @param address
+	 *            The socket address to be connected.
+	 * @return The new opend channel.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws UnresolvedAddressException
+	 *             If the address is not resolved.
+	 * @throws UnsupportedAddressTypeException
+	 *             If the address type is not supported.
+	 * @throws SecurityException
+	 *             If there is a security manager, and the address is not
+	 *             permitted to access.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public static SocketChannel open(SocketAddress address) throws IOException {
+		SocketChannel socketChannel = open();
+		if (null != socketChannel) {
+			socketChannel.connect(address);
+		}
+		return socketChannel;
+	}
+
+	/**
+	 * Get the valid operations of this channel. Socket channels support
+	 * connect, read and write operation, so this method returns (
+	 * <code>SelectionKey.OP_CONNECT</code> |
+	 * <code>SelectionKey.OP_READ</code> | <code>SelectionKey.OP_WRITE</code> ).
+	 * 
+	 * @see java.nio.channels.SelectableChannel#validOps()
+	 * @return Valid operations in bit-set.
+	 */
+	public final int validOps() {
+		return (SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
+	}
+
+	/**
+	 * Return the related socket of this channel, which won't declare public
+	 * methods that not declared in <code>Socket</code>.
+	 * 
+	 * @return The related Socket instance.
+	 */
+	public abstract Socket socket();
+
+	/**
+	 * Answer whether this channel's socket is connected or not.
+	 * 
+	 * @return <code>true</code> for this channel's socket is connected;
+	 *         <code>false</code> otherwise.
+	 */
+	public abstract boolean isConnected();
+
+	/**
+	 * Answer whether this channel's socket is in connecting or not.
+	 * 
+	 * @return <code>true</code> for the connection is initiated but not
+	 *         finished; <code>false</code> otherwise.
+	 */
+	public abstract boolean isConnectionPending();
+
+	/**
+	 * Connect the socket to remote address.
+	 * <p>
+	 * If the channel is blocking, this method will suspend before connection
+	 * finished or an I/O exception. If the channel is non-blocking, this method
+	 * will return <code>true</code> if the connection is finished at once or
+	 * return <code>false</code> and the connection must wait
+	 * <code>finishConnect</code> to finished otherwise.
+	 * </p>
+	 * <p>
+	 * This method can be called at any moment, and can block other read and
+	 * write operations while connecting.
+	 * </p>
+	 * <p>
+	 * This method just execute the same security checks as the connect method
+	 * of the <code>Socket</code> class.
+	 * </p>
+	 * 
+	 * @param address
+	 *            The address to be connected.
+	 * @return <code>true</code> if connection is finished,<code>false</code>
+	 *         otherwise.
+	 * @throws AlreadyConnectedException
+	 *             If the channel is connected already.
+	 * @throws ConnectionPendingException
+	 *             A non-blocking connecting is doing on this channel.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws UnresolvedAddressException
+	 *             If the address is not resolved.
+	 * @throws UnsupportedAddressTypeException
+	 *             If the address type is not supported.
+	 * @throws SecurityException
+	 *             If there is a security manager, and the address is not
+	 *             permitted to access.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract boolean connect(SocketAddress address) throws IOException;
+
+	/**
+	 * Complete the connection.
+	 * <p>
+	 * This method is used when the channel is connectable to finish the
+	 * connection, and the connectable status of a channel means the channel is
+	 * after initiating in non-blocking mode and calling its
+	 * <code>connect</code> method. It will throw related
+	 * <code>IOException</code> if the connection failed.
+	 * </p>
+	 * <p>
+	 * This method will return <code>true</code> if the connection is finished
+	 * already, and return <code>false</code> if the channel is non-blocking
+	 * and the connection is not finished yet.
+	 * </p>
+	 * <p>
+	 * If the channel is in blocking mode, this method will suspend, and return
+	 * <code>true</code> for connection finished or throw some exception
+	 * otherwise. The channel will be closed if the connection failed and this
+	 * method thrown some exception.
+	 * </p>
+	 * <p>
+	 * This method can be called at any moment, and can block other read and
+	 * write operations while connecting.
+	 * </p>
+	 * 
+	 * @return <code>true</code> if the connection is successfully finished,
+	 *         <code>false</code> otherwise.
+	 * @throws NoConnectionPendingException
+	 *             If the channel is not connected and the connection is not
+	 *             initiated.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract boolean finishConnect() throws IOException;
+
+	/**
+	 * Reads bytes from the channel into the given buffer.
+	 * <p>
+	 * The maximum number of bytes that will be read is the
+	 * <code>remaining()</code> number of bytes in the buffer when the method
+	 * invoked. The bytes will be read into the buffer starting at the buffer's
+	 * <code>position</code>.
+	 * </p>
+	 * <p>
+	 * The call may block if other threads are also attempting to read on the
+	 * same channel.
+	 * </p>
+	 * <p>
+	 * Upon completion, the buffer's <code>position()</code> is updated to the
+	 * end of the bytes that were read. The buffer's <code>limit()</code> is
+	 * unmodified.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
+	 * @param target
+	 *            The byte buffer to receive the bytes.
+	 * @return The number of bytes actually read.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract int read(ByteBuffer target) throws IOException;
+
+	/**
+	 * Reads bytes from the channel into a subset of the given buffers.
+	 * <p>
+	 * This method attempts to read all of the <code>remaining()</code> bytes
+	 * from <code>length</code> byte buffers, in order, starting at
+	 * <code>targets[offset]</code>. The number of bytes actually read is
+	 * returned.
+	 * </p>
+	 * <p>
+	 * If a read operation is in progress, subsequent threads will block until
+	 * the read is completed, and will then contend for the ability to read.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
+	 *      int, int)
+	 * @param targets
+	 *            the array of byte buffers into which the bytes will be read.
+	 * @param offset
+	 *            the index of the first buffer to read.
+	 * @param length
+	 *            the maximum number of buffers to read.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract long read(ByteBuffer[] targets, int offset, int length)
+			throws IOException;
+
+	/**
+	 * Reads bytes from the channel into all the given buffers.
+	 * <p>
+	 * This method is equivalent to:
+	 * 
+	 * <pre>
+	 * read(targets, 0, targets.length);
+	 * </pre>
+	 * 
+	 * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
+	 * @param targets
+	 *            the array of byte buffers to receive the bytes being read.
+	 * @return the number of bytes actually read.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public synchronized final long read(ByteBuffer[] targets)
+			throws IOException {
+		return read(targets, 0, targets.length);
+	}
+
+	/**
+	 * Writes bytes from the given buffer to the channel.
+	 * <p>
+	 * The maximum number of bytes that will be written is the
+	 * <code>remaining()</code> number of bytes in the buffer when the method
+	 * invoked. The bytes will be written from the buffer starting at the
+	 * buffer's <code>position</code>.
+	 * </p>
+	 * <p>
+	 * The call may block if other threads are also attempting to write on the
+	 * same channel.
+	 * </p>
+	 * <p>
+	 * Upon completion, the buffer's <code>position()</code> is updated to the
+	 * end of the bytes that were written. The buffer's <code>limit()</code>
+	 * is unmodified.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
+	 * @param source
+	 *            the byte buffer containing the bytes to be written.
+	 * @return the number of bytes actually written.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract int write(ByteBuffer source) throws IOException;
+
+	/**
+	 * Writes a subset of the given bytes from the buffers to the channel.
+	 * <p>
+	 * This method attempts to write all of the <code>remaining()</code> bytes
+	 * from <code>length</code> byte buffers, in order, starting at
+	 * <code>sources[offset]</code>. The number of bytes actually written is
+	 * returned.
+	 * </p>
+	 * <p>
+	 * If a write operation is in progress, subsequent threads will block until
+	 * the write is completed, and will then contend for the ability to write.
+	 * </p>
+	 * 
+	 * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
+	 *      int, int)
+	 * @param sources
+	 *            the array of byte buffers containing the source of remaining
+	 *            bytes that will be attempted to be written.
+	 * @param offset
+	 *            the index of the first buffer to write.
+	 * @param length
+	 *            the number of buffers to write.
+	 * @return the number of bytes actually written.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public abstract long write(ByteBuffer[] sources, int offset, int length)
+			throws IOException;
+
+	/**
+	 * Writes bytes from all the given buffers to the channel.
+	 * <p>
+	 * This method is equivalent to:
+	 * 
+	 * <pre>
+	 * write(buffers, 0, buffers.length);
+	 * </pre>
+	 * 
+	 * </p>
+	 * 
+	 * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
+	 * @param sources
+	 *            the buffers containing bytes to be written.
+	 * @return the number of bytes actually written.
+	 * @throws NotYetConnectedException
+	 *             If the channel is not connected yet.
+	 * @throws ClosedChannelException
+	 *             If the channel is already closed.
+	 * @throws AsynchronousCloseException
+	 *             If the channel is closed by another thread while this method
+	 *             is in operation.
+	 * @throws ClosedByInterruptException
+	 *             If another thread interrupts the calling thread while the
+	 *             operation is in progress. The calling thread will have the
+	 *             interrupt state set, and the channel will be closed.
+	 * @throws IOException
+	 *             Some other IO error occurred.
+	 * 
+	 */
+	public synchronized final long write(ByteBuffer[] sources)
+			throws IOException {
+		return write(sources, 0, sources.length);
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/SocketChannel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java?rev=392225&r1=392224&r2=392225&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java Fri Apr  7 02:07:34 2006
@@ -1,4 +1,4 @@
-/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable
+/* Copyright 2005, 2006 The Apache Software Foundation or its licensors, as applicable
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,24 +15,219 @@
 
 package java.nio.channels.spi;
 
-
-import java.nio.channels.Channel;
-import java.nio.channels.InterruptibleChannel;
+import java.io.IOException;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.IllegalSelectorException;
 import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
- * TODO Type description
+ * Abstract class for selectable channels.
+ * <p>
+ * In this class, there are methods about registring/deregistering a channel,
+ * about channel closing. It realize the multi-thread safe.
+ * </p>
  * 
  */
-public abstract class AbstractSelectableChannel extends SelectableChannel
-		implements Channel, InterruptibleChannel {
+public abstract class AbstractSelectableChannel extends SelectableChannel {
 
-	/**
-	 * @param provider
-	 */
-	public AbstractSelectableChannel(SelectorProvider provider) {
+    private final SelectorProvider provider;
 
-		// TODO Auto-generated constructor stub
-	}
+    /*
+     * The collection of key.
+     */
+    private List keyList = new ArrayList();
+
+    private final Object blockingLock = new Object();
+
+    boolean isBlocking = true;
+
+    /**
+     * Constructor for this class.
+     * 
+     * @param selectorProvider
+     *            A instance of SelectorProvider
+     */
+    protected AbstractSelectableChannel(SelectorProvider selectorProvider) {
+        super();
+        provider = selectorProvider;
+    }
+
+    /**
+     * Answer the SelectorProvider of this channel.
+     * 
+     * @see java.nio.channels.SelectableChannel#provider()
+     * @return The provider of this channel.
+     */
+    public final SelectorProvider provider() {
+        return provider;
+    }
+
+    /**
+     * @see java.nio.channels.SelectableChannel#isRegistered()
+     */
+    synchronized public final boolean isRegistered() {
+        return !keyList.isEmpty();
+    }
+
+    /**
+     * @see java.nio.channels.SelectableChannel#keyFor(java.nio.channels.Selector)
+     */
+    synchronized public final SelectionKey keyFor(Selector selector) {
+        for (int i = 0; i < keyList.size(); i++) {
+            SelectionKey key = (SelectionKey) keyList.get(i);
+            if (null != key && key.selector() == selector) {
+                return key;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Realize the register function.
+     * <p>
+     * It registers current channel to the selector, then answer the selection
+     * key. The channel must be open and the interest op set must be valid. If
+     * the current channel is already registered to the selector, the method
+     * only set the new interest op set; otherwise it will call the
+     * <code>register</code> in <code>selector</code>, and add the relative
+     * key to the key set of the current channel.
+     * </p>
+     * 
+     * @see java.nio.channels.SelectableChannel#register(java.nio.channels.Selector,
+     *      int, java.lang.Object)
+     */
+    public final SelectionKey register(Selector selector, int interestSet,
+            Object attachment) throws ClosedChannelException {
+        if (!isOpen()) {
+            throw new ClosedChannelException();
+        }
+        if (!((interestSet & ~validOps()) == 0)) {
+            throw new IllegalArgumentException();
+        }
+
+        synchronized (blockingLock) {
+            if (isBlocking) {
+                throw new IllegalBlockingModeException();
+            }
+            if (!selector.isOpen()) {
+                if (0 == interestSet){
+                    // throw ISE exactly to keep consistency
+                    throw new IllegalSelectorException();
+                }
+                // throw NPE exactly to keep consistency
+                throw new NullPointerException();
+            }
+            if (0 == interestSet){
+                // throw ISE exactly to keep consistency
+                throw new IllegalSelectorException();
+            }
+            SelectionKey key = keyFor(selector);
+            if (null == key) {
+                key = ((AbstractSelector) selector).register(this, interestSet,
+                        attachment);
+                keyList.add(key);
+            } else {
+                if (!key.isValid()) {
+                    throw new CancelledKeyException();
+                }
+                key.interestOps(interestSet);
+                key.attach(attachment);
+            }
+            return key;
+        }
+    }
+
+    /**
+     * Implement the closing function.
+     * 
+     * @see java.nio.channels.spi.AbstractInterruptibleChannel#implCloseChannel()
+     */
+    synchronized protected final void implCloseChannel() throws IOException {
+        implCloseSelectableChannel();
+        for (int i = 0; i < keyList.size(); i++) {
+            SelectionKey key = (SelectionKey) keyList.get(i);
+            if (null != key) {
+                key.cancel();
+            }
+        }
+    }
+
+    /**
+     * Implement the closing function of the SelectableChannel.
+     * 
+     * @throws IOException
+     *             If some I/O exception occured.
+     */
+    protected abstract void implCloseSelectableChannel() throws IOException;
+
+    /**
+     * @see java.nio.channels.SelectableChannel#isBlocking()
+     */
+    public final boolean isBlocking() {
+        synchronized (blockingLock) {
+            return isBlocking;
+        }
+    }
+
+    /**
+     * @see java.nio.channels.SelectableChannel#blockingLock()
+     */
+    public final Object blockingLock() {
+        return blockingLock;
+    }
+
+    /**
+     * Set the blocking mode of this channel.
+     * 
+     * @see java.nio.channels.SelectableChannel#configureBlocking(boolean)
+     * @param blockingMode
+     *            <code>true</code> for blocking mode; <code>false</code>
+     *            for non-blocking mode.
+     */
+    public final SelectableChannel configureBlocking(boolean blockingMode)
+            throws IOException {
+        if (isOpen()) {
+            synchronized (blockingLock) {
+                if (isBlocking == blockingMode) {
+                    return this;
+                }
+                if (blockingMode && isRegistered()) {
+                    throw new IllegalBlockingModeException();
+                }
+                implConfigureBlocking(blockingMode);
+                isBlocking = blockingMode;
+            }
+            return this;
+        }
+        throw new ClosedChannelException();
+
+    }
+
+    /**
+     * Implement the setting of blocking mode.
+     * 
+     * @param blockingMode
+     *            <code>true</code> for blocking mode; <code>false</code>
+     *            for non-blocking mode.
+     * @throws IOException
+     *             If some I/O exception occured.
+     */
+    protected abstract void implConfigureBlocking(boolean blockingMode)
+            throws IOException;
+
+    /*
+     * package private for deregister method in AbstractSelector.
+     */
+    synchronized void deRegister(SelectionKey k) {
+        if (null != keyList) {
+            keyList.remove(k);
+        }
+    }
 
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java?rev=392225&r1=392224&r2=392225&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java Fri Apr  7 02:07:34 2006
@@ -16,6 +16,7 @@
 package java.nio.channels.spi;
 
 
+import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 
 /**
@@ -23,5 +24,10 @@
  * 
  */
 public abstract class AbstractSelector extends Selector {
+
+	public SelectionKey register(AbstractSelectableChannel channel, int interestSet, Object attachment) {
+		//FIXME: waiting for patch for JIRA-41
+		return null;
+	}
 
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java?rev=392225&r1=392224&r2=392225&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java Fri Apr  7 02:07:34 2006
@@ -1,4 +1,4 @@
-/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable
+/* Copyright 2005, 2006 The Apache Software Foundation or its licensors, as applicable
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,25 +15,234 @@
 
 package java.nio.channels.spi;
 
-
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.channels.Channel;
+import java.nio.channels.DatagramChannel;
 import java.nio.channels.Pipe;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+
+import org.apache.harmony.nio.internal.SelectorProviderImpl;
 
 /**
- * TODO Type description
+ * Provider for nio selector and selectable channel.
+ * <p>
+ * The provider can be got by system property or the configuration file in a jar
+ * file, if not, the system default provider will return. The main function of
+ * this class is to return the instance of implementation class of
+ * <code>DatagramChannel</code>, <code>Pipe</code>, <code>Selector</code> ,
+ * <code>ServerSocketChannel</code>, and <code>SocketChannel</code>. All
+ * the methods of this class are multi-thread safe.
+ * </p>
  * 
  */
-public abstract class SelectorProvider {
+public abstract class SelectorProvider extends Object {
+
+    private static final String SYMBOL_COMMENT = "#"; //$NON-NLS-1$
 
-	/**
-	 * @return TODO
-	 */
-	public static SelectorProvider provider() {
-		// TODO Auto-generated method stub
-		return null;
-	}
+    private static final String PROVIDER_IN_SYSTEM_PROPERTY = "java.nio.channels.spi.SelectorProvider"; //$NON-NLS-1$
 
-	public abstract Pipe openPipe() throws IOException;
+    private static final String PROVIDER_IN_JAR_RESOURCE = "META-INF/services/java.nio.channels.spi.SelectorProvider"; //$NON-NLS-1$
 
-	public abstract AbstractSelector openSelector() throws IOException;
+    private static SelectorProvider provider = null;
+
+    private static Channel inheritedChannel = null;
+
+    /**
+     * Constructor for this class.
+     * 
+     * @throws SecurityException
+     *             If there is a security manager, and it denies
+     *             RuntimePermission("selectorProvider").
+     */
+    protected SelectorProvider() {
+        super();
+        if (null != System.getSecurityManager()) {
+            System.getSecurityManager().checkPermission(
+                    new RuntimePermission("selectorProvider")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Get the provider by following steps in the first calling.
+     * <p>
+     * <ul>
+     * <li> If the system property "java.nio.channels.spi.SelectorProvider" is
+     * set, the value of this property is the class name of the return provider.
+     * </li>
+     * <li>If there is a provider-configuration file named
+     * "java.nio.channels.spi.SelectorProvider" in META-INF/services of some jar
+     * file valid in the system class loader, the first class name is the return
+     * provider's class name. </li>
+     * <li> Otherwise, a system default provider will be returned. </li>
+     * </ul>
+     * </p>
+     * 
+     * @return The provider.
+     */
+    synchronized public static SelectorProvider provider() {
+        if (null == provider) {
+            provider = loadProviderByProperty();
+            if (null == provider) {
+                provider = loadProviderByJar();
+            }
+            if (null == provider) {
+                provider = new SelectorProviderImpl();
+            }
+            return provider;
+        }
+        return provider;
+    }
+
+    /*
+     * load the provider in the jar file of class path.
+     */
+    static SelectorProvider loadProviderByJar() {
+        Enumeration enumeration = null;
+        SelectorProvider tempProvider = null;
+
+        ClassLoader classLoader = (ClassLoader) AccessController
+                .doPrivileged(new PrivilegedAction() {
+                    public Object run() {
+                        return ClassLoader.getSystemClassLoader();
+                    }
+                });
+        try {
+            enumeration = classLoader.getResources(PROVIDER_IN_JAR_RESOURCE);
+        } catch (IOException e) {
+            throw new Error();
+        }
+        if (null == enumeration) {
+            return null;
+        }
+        // for every jar, read until we find the provider name.
+        while (enumeration.hasMoreElements()) {
+            BufferedReader br = null;
+            String className = null;
+            try {
+                br = new BufferedReader(new InputStreamReader(
+                        ((URL) enumeration.nextElement()).openStream()));
+            } catch (Exception e) {
+                continue;
+            }
+            try {
+                // only the first class is loaded ,as spec says, not the same as
+                // we do before.
+                if ((className = br.readLine()) != null) {
+                    className = className.trim();
+                    int siteComment = className.indexOf(SYMBOL_COMMENT);
+                    className = (-1 == siteComment) ? className : className
+                            .substring(0, siteComment);
+                    if (0 < className.length()) {
+                        tempProvider = (SelectorProvider) classLoader
+                                .loadClass(className).newInstance();
+                        if (null != tempProvider) {
+                            return tempProvider;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                throw new Error();
+            }
+        }
+        return null;
+    }
+
+    /*
+     * load by system property.
+     */
+    static SelectorProvider loadProviderByProperty() {
+        return (SelectorProvider) AccessController
+                .doPrivileged(new PrivilegedAction() {
+                    public Object run() {
+                        // FIXME check if use this ClassLoader or system
+                        // ClassLoader
+                        try {
+                            final String className = System
+                                    .getProperty(PROVIDER_IN_SYSTEM_PROPERTY);
+                            if (null != className) {
+                                return Thread.currentThread()
+                                        .getContextClassLoader().loadClass(
+                                                className);
+                            }
+                            return null;
+                        } catch (Exception e) {
+                            throw new Error();
+                        }
+                    }
+                });
+
+    }
+
+    /**
+     * Create a new open <code>DatagramChannel</code>.
+     * 
+     * @return The channel.
+     * @throws IOException
+     *             If some I/O exception occured.
+     */
+    public abstract DatagramChannel openDatagramChannel() throws IOException;
+
+    /**
+     * Create a new <code>Pipe</code>.
+     * 
+     * @return The pipe.
+     * @throws IOException
+     *             If some I/O exception occured.
+     */
+    public abstract Pipe openPipe() throws IOException;
+
+    /**
+     * Create a new selector.
+     * 
+     * @return The selector.
+     * @throws IOException
+     *             If some I/O exception occured.
+     */
+    public abstract AbstractSelector openSelector() throws IOException;
+
+    /**
+     * Create a new open <code>ServerSocketChannel</code>.
+     * 
+     * @return The channel.
+     * @throws IOException
+     *             If some I/O exception occured.
+     */
+    public abstract ServerSocketChannel openServerSocketChannel()
+            throws IOException;
+
+    /**
+     * Create a new open <code>SocketChannel</code>.
+     * 
+     * @return The channel.
+     * @throws IOException
+     *             If some I/O exception occured.
+     */
+    public abstract SocketChannel openSocketChannel() throws IOException;
+
+    /**
+     * Answer the channel inherited from the instance which created this JVM.
+     * 
+     * @return The channel.
+     * @throws IOException
+     *             If some I/O exception occured.
+     * @throws SecurityException
+     *             If there is a security manager, and it denies
+     *             RuntimePermission("selectorProvider").
+     */
+    public Channel inheritedChannel() throws IOException {
+        return null;
+//        FIXME waiting for VM support      
+//        if (null == inheritedChannel) {
+//            inheritedChannel = OSComponentFactory.getNetworkSystem()
+//                    .inheritedChannel();
+//        }
+//        return inheritedChannel;
+    }
 }