diff options
author | rsuen | 2009-04-29 11:14:47 +0000 |
---|---|---|
committer | rsuen | 2009-04-29 11:14:47 +0000 |
commit | 99cdd8e06df8ead2348f36d754480742091fe4db (patch) | |
tree | f7d6bee05657924fa11d395a69bf5d8553763695 /providers/bundles/org.eclipse.ecf.provider.datashare.nio | |
parent | 2f6fe002e0c0b02a2a9ff7143fe890e53250ab4d (diff) | |
download | org.eclipse.ecf-99cdd8e06df8ead2348f36d754480742091fe4db.tar.gz org.eclipse.ecf-99cdd8e06df8ead2348f36d754480742091fe4db.tar.xz org.eclipse.ecf-99cdd8e06df8ead2348f36d754480742091fe4db.zip |
Externalize strings.
Diffstat (limited to 'providers/bundles/org.eclipse.ecf.provider.datashare.nio')
4 files changed, 209 insertions, 34 deletions
diff --git a/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/Messages.java b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/Messages.java new file mode 100644 index 000000000..8eab26d8e --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/Messages.java @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2009 Remy Chi Jian Suen and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Remy Chi Jian Suen - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.provider.datashare.nio; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.ecf.provider.datashare.nio.messages"; //$NON-NLS-1$ + + public static String NIOChannel_CouldNotCreateServerSocket; + public static String NIOChannel_BindOperationFailed; + public static String NIOChannel_ReceiverUnspecified; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + +} diff --git a/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIOChannel.java b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIOChannel.java index 06afdd22d..5e950493c 100644 --- a/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIOChannel.java +++ b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIOChannel.java @@ -47,6 +47,28 @@ import org.eclipse.ecf.datashare.events.IChannelMessageEvent; * An abstract implementation of <code>IChannel</code> that uses Java 1.4 NIO * APIs for sending and retrieving data. * <p> + * This channel will inherently spawn multiple socket connections as messages + * are sent to different remote clients via {@link #sendMessage(ID, byte[])}. + * Please note that the current implementation does not handle repeated + * invocations to that method well. Please refer to its javadoc for further + * information. + * </p> + * <p> + * Subclasses must implement the following: + * <ul> + * <li>For communicating local information for establishing a socket connection: + * <ul> + * <li>{@link #sendRequest(ID)}</li> + * </ul> + * </li> + * <li>To facilitate the logging of statuses: + * <ul> + * <li>{@link #log(IStatus)}</li> + * </ul> + * </li> + * </ul> + * </p> + * <p> * <b>Note:</b> This class/interface is part of an interim API that is still * under development and expected to change significantly before reaching * stability. It is being made available at this early stage to solicit feedback @@ -147,8 +169,8 @@ public abstract class NIOChannel implements IChannel { serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); } catch (IOException e) { - log(new Status(IStatus.ERROR, Util.PLUGIN_ID, - "Could not create server socket", e)); //$NON-NLS-1$ + throw new ECFException(new Status(IStatus.ERROR, Util.PLUGIN_ID, + Messages.NIOChannel_CouldNotCreateServerSocket, e)); } try { @@ -156,8 +178,8 @@ public abstract class NIOChannel implements IChannel { ServerSocket socket = serverSocketChannel.socket(); socket.bind(getBindAddress(), getBackLog()); } catch (IOException e) { - log(new Status(IStatus.ERROR, Util.PLUGIN_ID, - "Bind operation failed for the server socket", e)); //$NON-NLS-1$ + throw new ECFException(new Status(IStatus.ERROR, Util.PLUGIN_ID, + Messages.NIOChannel_BindOperationFailed, e)); } localPort = serverSocketChannel.socket().getLocalPort(); @@ -172,6 +194,13 @@ public abstract class NIOChannel implements IChannel { processingThread.start(); } + /** + * Fires a channel connected event to this channel's listener if there is + * one attached. + * + * @param containerId + * the target ID of the container has connected to + */ void fireChannelConnectEvent(final ID containerId) { IChannelListener listener = getListener(); if (listener != null) { @@ -195,6 +224,13 @@ public abstract class NIOChannel implements IChannel { } } + /** + * Fires a channel disconnected event to this channel's listener if there is + * one attached. + * + * @param containerId + * the target ID of the container has disconnected from + */ void fireChannelDisconnectEvent(final ID containerId) { IChannelListener listener = getListener(); if (listener != null) { @@ -243,11 +279,8 @@ public abstract class NIOChannel implements IChannel { /** * Sends any pending messages we may have queued up. - * - * @throws IOException - * if an error occurs while trying to send a message */ - private void sendPendingMessages() throws IOException { + private void sendPendingMessages() { Collection deadSockets = null; Collection processedMessages = null; @@ -368,6 +401,14 @@ public abstract class NIOChannel implements IChannel { return channelData.isOpen(); } + /** + * Processes the message that has been received from the specified channel. + * + * @param socketChannel + * the channel that the message was from + * @param message + * the message that was received + */ void processIncomingMessage(SocketChannel socketChannel, byte[] message) { // we read something, need to notify IChannelListener listener = getListener(); @@ -420,10 +461,21 @@ public abstract class NIOChannel implements IChannel { } } - private void fireMessageEvents(IChannelListener listener, SocketChannel so, - byte[][] messages) { + /** + * Fires message events to the specified listener for each of the message + * that was received. + * + * @param listener + * the listener to notify + * @param socketChannel + * the socket that the message was read from + * @param messages + * the messages that have been received + */ + private void fireMessageEvents(IChannelListener listener, + SocketChannel socketChannel, byte[][] messages) { for (int i = 0; i < messages.length; i++) { - IChannelEvent event = createMessageEvent(so, messages[i]); + IChannelEvent event = createMessageEvent(socketChannel, messages[i]); if (event != null) { fireChannelEvent(listener, event); } @@ -456,6 +508,17 @@ public abstract class NIOChannel implements IChannel { }); } + /** + * Creates and returns a message event corresponding to the specified + * channel and the data that was read. + * + * @param channel + * the socket channel that the message was from + * @param data + * the message from the remote peer + * @return a message event describing the received message, may be + * <code>null</code> if the channel could not be identified + */ private IChannelEvent createMessageEvent(SocketChannel channel, final byte[] data) { // search for the id of the corresponding channel @@ -632,10 +695,30 @@ public abstract class NIOChannel implements IChannel { protected abstract void sendRequest(ID receiver) throws ECFException; public void sendMessage(byte[] message) throws ECFException { - throw new ECFException( - "A receiver must be specified, see sendMessage(ID, byte[])"); //$NON-NLS-1$ + throw new ECFException(new Status(IStatus.ERROR, Util.PLUGIN_ID, + Messages.NIOChannel_ReceiverUnspecified)); } + /** + * Sends a message to a remote instance of this channel of the target peer. + * <p> + * <b>Note:</b> The current implementation does not handle repeated + * invocations of this method in succession prior to a socket connection + * established. For optimal performance and some assurance of success, there + * needs to be a time lag between the first message that is sent and the + * ones that follow it. This lag should hopefully allow the provider + * sufficient time for establishing a socket connection with the remote + * peer. Otherwise, there may be multiple invocations of + * {@link #sendRequest(ID)} and clients are responsible for handling this + * individually. + * </p> + * + * @param receiver + * the receiver to send the message to, must not be + * <code>null</code> + * @param message + * the message to send, must not be <code>null</code> + */ public void sendMessage(ID receiver, byte[] message) throws ECFException { Assert.isNotNull(receiver, "A receiver must be specified"); //$NON-NLS-1$ Assert.isNotNull(message, "Message cannot be null"); //$NON-NLS-1$ @@ -778,8 +861,6 @@ public abstract class NIOChannel implements IChannel { oos.writeObject(data); return baos.toByteArray(); } catch (IOException e) { - log(new Status(IStatus.ERROR, Util.PLUGIN_ID, - "Could not serialize data", e)); //$NON-NLS-1$ throw new ECFException(e); } } diff --git a/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIODatashareContainer.java b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIODatashareContainer.java index 9a0c7b388..a0f674c64 100644 --- a/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIODatashareContainer.java +++ b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/NIODatashareContainer.java @@ -82,8 +82,7 @@ import org.eclipse.ecf.datashare.events.IChannelContainerEvent; * API will almost certainly be broken (repeatedly) as the API evolves. * </p> */ -public abstract class NIODatashareContainer implements - IChannelContainerAdapter { +public abstract class NIODatashareContainer implements IChannelContainerAdapter { /** * A thread for establishing a connection to remote clients. @@ -152,15 +151,31 @@ public abstract class NIODatashareContainer implements listenerList = new ListenerList(); } - private void fireChannelConnectedEvent(ID id) { + /** + * Fires a channel connected event to all of this channel container's + * channels notifying that the parent container has connected to the + * specified target id. + * + * @param containerTargetId + * the target id that the parent container has connected to + */ + private void fireChannelConnectedEvent(ID containerTargetId) { synchronized (channels) { for (Iterator it = channels.values().iterator(); it.hasNext();) { NIOChannel channel = (NIOChannel) it.next(); - channel.fireChannelConnectEvent(id); + channel.fireChannelConnectEvent(containerTargetId); } } } + /** + * Fires a channel disconnected event to all of this channel container's + * channels notifying that the parent container has disconnected from the + * specified target id. + * + * @param containerTargetId + * the target id that the parent container has disconnected from + */ private void fireChannelDisconnectedEvent(ID id) { synchronized (channels) { for (Iterator it = channels.values().iterator(); it.hasNext();) { @@ -292,24 +307,37 @@ public abstract class NIODatashareContainer implements } } + /** + * Attempts to connect to a remote address that has been enqueued to this + * channel container for processing via the {@link #enqueue(SocketAddress)} + * method. + * + * @param buffer + * the buffer to use for reading and writing data + * @throws IOException + * if an IO error occurs while attempting to contact the peer + */ private void connect(ByteBuffer buffer) throws IOException { - // retrieve an IP address to connect to - SocketAddress remote = (SocketAddress) pendingConnections.removeFirst(); + while (!pendingConnections.isEmpty()) { + // retrieve an IP address to connect to + SocketAddress remote = (SocketAddress) pendingConnections + .removeFirst(); - // open a socket channel to the remote address - SocketChannel socketChannel = SocketChannel.open(remote); + // open a socket channel to the remote address + SocketChannel socketChannel = SocketChannel.open(remote); - byte[] bytes = Util.serialize(container.getConnectedID()); - if (bytes == null) { - // serialization failed, close the socket - Util.closeChannel(socketChannel); - return; - } + byte[] bytes = Util.serialize(container.getConnectedID()); + if (bytes == null) { + // serialization failed, close the socket + Util.closeChannel(socketChannel); + return; + } - socketChannel.configureBlocking(false); - Util.write(socketChannel, buffer, bytes); + socketChannel.configureBlocking(false); + Util.write(socketChannel, buffer, bytes); - pendingSockets.add(socketChannel); + pendingSockets.add(socketChannel); + } } /** @@ -333,7 +361,19 @@ public abstract class NIODatashareContainer implements pendingConnections.add(address); } - private void processHandshake(SocketChannel socketChannel, ChannelData data) + /** + * Performs a handshake operation with the remote peer. + * + * @param socketChannel + * the socket channel to handshake with + * @param data + * the data sent from the channel thus far + * @throws ClassNotFoundException + * if a deserialization error occurs + * @throws IOException + * if an IO error occurs while reading or writing data + */ + private void handshake(SocketChannel socketChannel, ChannelData data) throws ClassNotFoundException, IOException { // retrieve the data that was sent byte[] message = data.getData(); @@ -381,6 +421,19 @@ public abstract class NIODatashareContainer implements } } + /** + * Processes any pending sockets that are currently queued up in this + * channel container and is waiting to initiate the handshake process with + * the remote peer. + * + * @param buffer + * the buffer to use for reading and writing data + * @throws ClassNotFoundException + * if a serialization or deserialization operation encountered + * errors + * @throws IOException + * if an IO error occurs while reading or writing data + */ private void processPendingSockets(ByteBuffer buffer) throws ClassNotFoundException, IOException { for (int i = 0; i < pendingSockets.size(); i++) { @@ -397,7 +450,7 @@ public abstract class NIODatashareContainer implements i--; } else if (data.getData() != null) { try { - processHandshake(socketChannel, data); + handshake(socketChannel, data); } finally { // this socket has been processed, remove it pendingSockets.remove(i); diff --git a/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/messages.properties b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/messages.properties new file mode 100644 index 000000000..f4f9a6553 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.datashare.nio/src/org/eclipse/ecf/provider/datashare/nio/messages.properties @@ -0,0 +1,14 @@ +################################################################################ +# Copyright (c) 2009 Remy Chi Jian Suen and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Remy Chi Jian Suen <remy.suen@gmail.com> - initial API and implementation +################################################################################ + +NIOChannel_CouldNotCreateServerSocket = Could not create server socket +NIOChannel_BindOperationFailed = Bind operation failed for the server socket +NIOChannel_ReceiverUnspecified = A receiver must be specified, see sendMessage(ID, byte[]) |