/****************************************************************************** * 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.internal.provider.irc.datashare; import java.net.InetSocketAddress; import java.net.SocketAddress; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.ecf.core.identity.ID; import org.eclipse.ecf.core.identity.Namespace; import org.eclipse.ecf.core.util.ECFException; import org.eclipse.ecf.datashare.IChannelListener; import org.eclipse.ecf.internal.provider.irc.Activator; import org.eclipse.ecf.internal.provider.irc.identity.IRCID; import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender; import org.eclipse.ecf.presence.im.IChatID; import org.eclipse.ecf.provider.datashare.nio.NIOChannel; import org.eclipse.ecf.provider.datashare.nio.NIODatashareContainer; class IRCDatashareChannel extends NIOChannel { private static final String BIND_IP_PROPERTY = "org.eclipse.ecf.provider.irc.bindIP"; private static final String BIND_PORT_PROPERTY = "org.eclipse.ecf.provider.irc.bindPort"; /** * The key value to a system property that can be used for specifying the IP * that remote peers will use to connect to for establishing a connection * with the local machine. If this is not set, the IP is retrieved from the * IRC server directly via the <code>USERHOST</code> command. * * @see #setIP(String) */ private static final String LOCAL_IP_PROPERTY = "org.eclipse.ecf.provider.irc.localIP"; /** * A namespace for instantiating IDs for message identification. */ private Namespace receiverNamespace; /** * Our own container's target ID. This will be used for instantiating an ID * that corresponds to the remote peer. * * @see #receiverNamespace * @see #sendMessage(ID, byte[]) */ private IRCID userId; /** * A message sender to send the connection request to. */ private IChatRoomMessageSender sender; /** * The IP that will be sent to the remote peer for establishing a * connection. */ private String ip; IRCDatashareChannel(NIODatashareContainer datashareContainer, Namespace receiverNamespace, ID userId, IChatRoomMessageSender sender, ID id, IChannelListener listener) throws ECFException { super(datashareContainer, userId, id, listener); this.receiverNamespace = receiverNamespace; this.userId = (IRCID) userId; this.sender = sender; } protected void log(IStatus status) { Activator.getDefault().log(status); } protected SocketAddress getBindAddress() { String bindIP = System.getProperty(BIND_IP_PROPERTY); String bindPort = System.getProperty(BIND_PORT_PROPERTY); if (bindIP == null) { if (bindPort == null) { return super.getBindAddress(); } else { try { return new InetSocketAddress(Integer.parseInt(bindPort)); } catch (NumberFormatException e) { Activator.log("Invalid bind property value (" + BIND_PORT_PROPERTY + ") specified: " + bindPort); return super.getBindAddress(); } } } else { if (bindPort == null) { return new InetSocketAddress(bindIP, 0); } else { try { return new InetSocketAddress(bindIP, Integer .parseInt(bindPort)); } catch (NumberFormatException e) { Activator.log("Invalid bind property value (" + BIND_PORT_PROPERTY + ") specified: " + bindPort); return new InetSocketAddress(bindIP, 0); } } } } /** * Sets the IP that should be sent to the remote peer for connecting with * the local computer. * <p> * <b>Note:</b> The provided IP address may be ignored if the * <code>org.eclipse.ecf.provider.irc.localIP</code> system property has * been set. * </p> * * @param ip * the local computer's IP */ void setIP(String ip) { String propertyIP = System.getProperty(LOCAL_IP_PROPERTY); if (propertyIP == null) { this.ip = ip; } else { this.ip = propertyIP; } } protected void sendRequest(ID receiver) throws ECFException { String name = ((IChatID) receiver).getUsername(); StringBuffer buffer = new StringBuffer(); buffer.append("/msg ").append(name); //$NON-NLS-1$ buffer.append(" \01ECF "); //$NON-NLS-1$ buffer.append(ip).append(':').append(getLocalPort()); buffer.append('\01'); sender.sendMessage(buffer.toString()); } public void sendMessage(ID receiver, byte[] message) throws ECFException { Assert.isNotNull(receiver, "A receiver must be specified"); //$NON-NLS-1$ // retrieve the target's name String name = receiver instanceof IChatID ? ((IChatID) receiver) .getUsername() : receiver.getName(); // now create a string that is similar to our own ID, using the form // username@irc.freenode.net:6667 StringBuffer buffer = new StringBuffer(name); buffer.append('@').append(userId.getHost()); buffer.append(':').append(userId.getPort()); // now create a new ID ID modifiedId = receiverNamespace.createInstance(new Object[] { buffer .toString() }); // send the message with the new ID super.sendMessage(modifiedId, message); } }