You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ha...@apache.org on 2011/09/10 01:38:39 UTC

svn commit: r1167400 - in /camel/trunk/components/camel-irc/src: main/java/org/apache/camel/component/irc/ test/java/org/apache/camel/component/irc/

Author: hadrian
Date: Fri Sep  9 23:38:39 2011
New Revision: 1167400

URL: http://svn.apache.org/viewvc?rev=1167400&view=rev
Log:
CAMEL-4427. Use valid URIs in camel-irc

Modified:
    camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcComponent.java
    camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConfiguration.java
    camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConsumer.java
    camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcEndpoint.java
    camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcProducer.java
    camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/CodehausIrcChat.java
    camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConfigurationTest.java
    camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConsumerTest.java
    camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcEndpointTest.java
    camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcProducerTest.java

Modified: camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcComponent.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcComponent.java (original)
+++ camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcComponent.java Fri Sep  9 23:38:39 2011
@@ -21,6 +21,7 @@ import java.util.Map;
 
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.schwering.irc.lib.IRCConnection;
 import org.schwering.irc.lib.IRCEventListener;
 import org.schwering.irc.lib.ssl.SSLIRCConnection;
@@ -67,7 +68,7 @@ public class IrcComponent extends Defaul
         if (configuration.getUsingSSL()) {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Creating SSL Connection to {} destination(s): {} nick: {} user: {}",
-                        new Object[]{configuration.getHostname(), configuration.getListOfChannels(), configuration.getNickname(), configuration.getUsername()});
+                    new Object[]{configuration.getHostname(), configuration.getListOfChannels(), configuration.getNickname(), configuration.getUsername()});
             }
             SSLIRCConnection sconn = new SSLIRCConnection(configuration.getHostname(), configuration.getPorts(), configuration.getPassword(),
                     configuration.getNickname(), configuration.getUsername(), configuration.getRealname());
@@ -125,4 +126,9 @@ public class IrcComponent extends Defaul
     protected IRCEventListener createIrcLogger(String hostname) {
         return new IrcLogger(LOG, hostname);
     }
+
+    @Deprecated
+    protected String preProcessUri(String uri) {
+        return IrcConfiguration.sanitize(uri);
+    }
 }

Modified: camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConfiguration.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConfiguration.java (original)
+++ camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConfiguration.java Fri Sep  9 23:38:39 2011
@@ -22,19 +22,28 @@ import java.net.URISyntaxException;
 import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
+import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.schwering.irc.lib.ssl.SSLDefaultTrustManager;
 import org.schwering.irc.lib.ssl.SSLTrustManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class IrcConfiguration implements Cloneable {
-    private String target;
-    private List<String> channels = new ArrayList<String>();
-    private Dictionary<String, String> keys = new Hashtable<String, String>();
+    private static final transient Logger LOG = LoggerFactory.getLogger(IrcConfiguration.class);
+
+    private List<IrcChannel> channels = new ArrayList<IrcChannel>();
     private String hostname;
     private String password;
     private String nickname;
@@ -56,23 +65,14 @@ public class IrcConfiguration implements
     private boolean autoRejoin = true;
     private int[] ports = {6667, 6668, 6669};
 
-    /*
-     * Temporary storage for when keys are listed in the parameters before channels.
-     */
-    private String channelKeys;
-
     public IrcConfiguration() {
     }
 
-    public IrcConfiguration(String hostname, String nickname, String displayname, List<String> channels) {
-        this.channels = channels;
-        this.hostname = hostname;
-        this.nickname = nickname;
-        this.username = nickname;
-        this.realname = displayname;
+    public IrcConfiguration(String hostname, String nickname, String displayname, List<IrcChannel> channels) {
+        this(hostname, null, null, nickname, displayname, channels);
     }
 
-    public IrcConfiguration(String hostname, String username, String password, String nickname, String displayname, List<String> channels) {
+    public IrcConfiguration(String hostname, String username, String password, String nickname, String displayname, List<IrcChannel> channels) {
         this.channels = channels;
         this.hostname = hostname;
         this.username = username;
@@ -93,12 +93,15 @@ public class IrcConfiguration implements
         return hostname + ":" + nickname;
     }
 
+    /*
+     * Return space separated list of channel names without pwd
+     */
     public String getListOfChannels() {
         String retval = "";
-        for (String channel : channels) {
-            retval += channel + " ";
+        for (IrcChannel channel : channels) {
+            retval += (retval.isEmpty() ? "" : " ") + channel.getName();
         }
-        return retval.trim();
+        return retval;
     }
 
     public void configure(String uriStr) throws URISyntaxException, UnsupportedEncodingException  {
@@ -124,65 +127,32 @@ public class IrcConfiguration implements
         setHostname(uri.getHost());
 
         String path = uri.getPath();
-        if (path != null) {
-            path = URLDecoder.decode(path, "UTF-8");
-            if (path.startsWith("/")) {
-                path = path.substring(1);
-            }
-            if (path.startsWith("#")) {
-                addChannel(path);
-            } // else should probably issue a warning?
+        if (path != null && !path.isEmpty()) {
+            LOG.warn("Channel {} should not be specified in the URI path. Use an @channel query parameter instead.", path);
         }
     }
 
-    public void addChannel(String channel) {
-        boolean alreadyHave = false;
-        for (String aChannel : channels) {
-            if (channel.contentEquals(aChannel)) {
-                alreadyHave = true;
-            }
-        }
-        if (!alreadyHave) {
-            channels.add(channel);
-        }
+    public void setChannel(String channel) {
+        channels.add(createChannel(channel));
     }
 
-    public void setChannels(String channels) {
-        String[] args = channels.split(",");
-
-        for (String channel : args) {
-            channel = channel.trim();
-            if (channel.startsWith("#")) {
-                addChannel(channel);
-            }
-        }
-
-        if (keys.size() == 0 && channelKeys != null) {
-            setKeys(channelKeys);
+    public void setChannel(List<String> channels) {
+        for (String ci : channels) {
+            this.channels.add(createChannel(ci));
         }
     }
 
-    public void setKeys(String keys) {
-        if (channels.size() == 0) {
-            // keys are listed in the parameters before channels
-            // store the string and process after channels
-            channelKeys = keys;
-        } else {
-            String[] s = keys.split(",");
-            int index = 0;
-            for (String key : s) {
-                this.keys.put(channels.get(index), key);
-                index++;
+    public List<IrcChannel> getChannels() {
+        return channels;
+    }
+    
+    public IrcChannel findChannel(String name) {
+        for (IrcChannel channel : channels) {
+            if (channel.getName().equals(name)) {
+                return channel;
             }
         }
-    }
-
-    public String getKey(String channel) {
-        return keys.get(channel);
-    }
-
-    public Dictionary<String, String> getKeys() {
-        return keys;
+        return null;
     }
 
     public void setTrustManager(SSLTrustManager trustManager) {
@@ -249,10 +219,6 @@ public class IrcConfiguration implements
         this.ports = ports;
     }
 
-    public List<String> getChannels() {
-        return channels;
-    }
-
     public boolean isPersistent() {
         return persistent;
     }
@@ -350,6 +316,157 @@ public class IrcConfiguration implements
     }
 
     public String toString() {
-        return "IrcConfiguration[hostname: " + hostname + ", ports=" + Arrays.toString(ports) + ", target: " + target + ", username=" + username + "]";
+        return "IrcConfiguration[hostname: " + hostname + ", ports=" + Arrays.toString(ports) + ", username=" + username + "]";
+    }
+    
+    private static IrcChannel createChannel(String channelInfo) {
+        String[] pair = channelInfo.split("!");
+        return new IrcChannel(pair[0], pair.length > 1 ? pair[1] : null);
+    }
+
+    @Deprecated
+    public static String sanitize(String uri) {
+        // may be removed in camel-3.0.0 
+        // make sure it's an URL first
+        int colon = uri.indexOf(':');
+        if (colon != -1 && uri.indexOf("://") != colon) {
+            uri = uri.substring(0, colon) + "://" + uri.substring(colon + 1);
+        }
+
+        try {
+            URI u = new URI(UnsafeUriCharactersEncoder.encode(uri));
+            String[] userInfo = u.getUserInfo() != null ? u.getUserInfo().split(":") : null;
+            String username = userInfo != null ? userInfo[0] : null;
+            String password = userInfo != null && userInfo.length > 1 ? userInfo[1] : null;
+
+            String path = URLDecoder.decode(u.getPath() != null ? u.getPath() : "", "UTF-8");
+            if (path.startsWith("/")) {
+                path = path.substring(1);
+            }
+            if (path.startsWith("#") && !path.startsWith("##")) {
+                path = path.substring(1);
+            }
+
+            Map<String, Object> parameters = URISupport.parseParameters(u);
+            String user = (String)parameters.get("username");
+            String nick = (String)parameters.get("nickname");
+            // not specified in authority
+            if (user != null) {
+                if (username == null) {
+                    username = user;
+                } else if (!username.equals(user)) {
+                    LOG.warn("Username specified twice in endpoint URI with different values. "
+                        + "The userInfo value ('{}') will be used, paramter ('{}') ignored", username, user);
+                }
+                parameters.remove("username");
+            }
+            if (nick != null) {
+                if (username == null) {
+                    username = nick;
+                }
+                if (username.equals(nick)) {
+                    parameters.remove("nickname");      // redundant
+                }
+            }
+            if (username == null) {
+                throw new RuntimeCamelException("IrcEndpoint URI with no user/nick specified is invalid");
+            }
+
+            String pwd = (String)parameters.get("password");
+            if (pwd != null) {
+                password = pwd;
+                parameters.remove("password");
+            }
+            
+            // Remove unneeded '#' channel prefixes per convention
+            // and replace ',' separators and merge channel and key using convention "channel!key"
+            ArrayList<String> cl = new ArrayList<String>();
+            String channels = (String)parameters.get("channels");
+            String keys =  (String)parameters.get("keys");
+            keys = keys == null ? keys : keys + " ";    // if @keys ends with a ',' it will miss the last empty key after split(",")
+            if (channels != null) {
+                String[] chs = channels.split(",");
+                String[] ks = keys != null ? keys.split(",") : null;
+                parameters.remove("channels");
+                int count = chs.length;
+                if (ks != null) {
+                    parameters.remove("keys");
+                    if (!path.isEmpty()) {
+                        LOG.warn("Specifying a channel '{}' in the URI path is ambiguous"
+                            + " when @channels and @keys are provided and will be ignored", path);
+                        path = "";
+                    }
+                    if (ks.length != chs.length) {
+                        count = count < ks.length ? count : ks.length;
+                        LOG.warn("Different count of @channels and @keys. Only the first {} are used.", count);
+                    }
+                }
+                for (int i = 0; i < count; i++) {
+                    String channel = chs[i].trim();
+                    String key = ks != null ? ks[i].trim() : null;
+                    if (channel.startsWith("#") && !channel.startsWith("##")) {
+                        channel = channel.substring(1);
+                    }
+                    if (key != null && !key.isEmpty()) {
+                        channel += "!" + key;
+                    }
+                    cl.add(channel);
+                }
+            } else {
+                if (path.isEmpty()) {
+                    LOG.warn("No channel specified for the irc endpoint");
+                }
+                cl.add(path);
+            }
+            parameters.put("channel", cl);
+
+            StringBuilder sb = new StringBuilder();
+            sb.append(u.getScheme());
+            sb.append("://");
+            sb.append(username);
+            sb.append(password == null ? "" : ":" + password);
+            sb.append("@");
+            sb.append(u.getHost());
+            sb.append(u.getPort() == -1 ? "" : ":" + u.getPort());
+            // ignore the path we have it as a @channel now
+            String query = formatQuery(parameters);
+            if (!query.isEmpty()) {
+                sb.append("?");
+                sb.append(query);
+            }
+            // make things a bit more predictable
+            return sb.toString();
+        } catch (Exception e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
+    
+    private static String formatQuery(Map<String, Object> params) {
+        if (params == null || params.size() == 0) {
+            return "";
+        }
+        StringBuilder result = new StringBuilder();
+        for (Map.Entry<String, Object> pair : params.entrySet()) {
+            Object value = pair.getValue();
+            // the value may be a list since the same key has multiple values
+            if (value instanceof List) {
+                List list = (List)value;
+                for (Object s : list) {
+                    addQueryParameter(result, pair.getKey(), s);
+                }
+            } else {
+                addQueryParameter(result, pair.getKey(), value);
+            }
+        }
+        return result.toString();
+    }
+    
+    private static void addQueryParameter(StringBuilder sb, String key, Object value) {
+        sb.append(sb.length() == 0 ? "" : "&");
+        sb.append(key);
+        if (value != null) {
+            String s = value.toString();
+            sb.append(s.isEmpty() ? "" : "=" + UnsafeUriCharactersEncoder.encode(s));
+        }
     }
 }

Modified: camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConsumer.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConsumer.java (original)
+++ camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcConsumer.java Fri Sep  9 23:38:39 2011
@@ -44,9 +44,9 @@ public class IrcConsumer extends Default
     @Override
     protected void doStop() throws Exception {
         if (connection != null) {
-            for (String channel : endpoint.getConfiguration().getChannels()) {
+            for (IrcChannel channel : endpoint.getConfiguration().getChannels()) {
                 LOG.debug("Parting: {}", channel);
-                connection.doPart(channel);
+                connection.doPart(channel.getName());
             }
             connection.removeIRCEventListener(listener);
         }

Modified: camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcEndpoint.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcEndpoint.java (original)
+++ camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcEndpoint.java Fri Sep  9 23:38:39 2011
@@ -24,6 +24,7 @@ import org.apache.camel.Processor;
 import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.impl.DefaultExchange;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.schwering.irc.lib.IRCConnection;
 import org.schwering.irc.lib.IRCEventAdapter;
 import org.schwering.irc.lib.IRCModeParser;
@@ -44,7 +45,7 @@ public class IrcEndpoint extends Default
     private IrcComponent component;
 
     public IrcEndpoint(String endpointUri, IrcComponent component, IrcConfiguration configuration) {
-        super(endpointUri, component);
+        super(UnsafeUriCharactersEncoder.encode(endpointUri), component);
         this.component = component;
         this.configuration = configuration;
     }
@@ -179,28 +180,35 @@ public class IrcEndpoint extends Default
 
 
     public void joinChannels() {
-        for (String channel : configuration.getChannels()) {
+        for (IrcChannel channel : configuration.getChannels()) {
             joinChannel(channel);
         }
     }
 
-    public void joinChannel(String channel) {
+    public void joinChannel(String name) {
+        joinChannel(configuration.findChannel(name));
+    }
+
+    public void joinChannel(IrcChannel channel) {
+        if (channel == null) {
+            return;
+        }
 
         IRCConnection connection = component.getIRCConnection(configuration);
 
-        // check for key for channel
-        String key = configuration.getKey(channel);
+        String chn = channel.getName();
+        String key = channel.getKey();
 
         if (ObjectHelper.isNotEmpty(key)) {
             if (LOG.isDebugEnabled()) {
-                LOG.debug("Joining: {} using {} with key {}", new Object[]{channel, connection.getClass().getName(), key});
+                LOG.debug("Joining: {} using {} with secret key", channel, connection.getClass().getName());
             }
-            connection.doJoin(channel, key);
+            connection.doJoin(chn, key);
         } else {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Joining: {} using {}", channel, connection.getClass().getName());
             }
-            connection.doJoin(channel);
+            connection.doJoin(chn);
         }
     }
 }

Modified: camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcProducer.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcProducer.java (original)
+++ camel/trunk/components/camel-irc/src/main/java/org/apache/camel/component/irc/IrcProducer.java Fri Sep  9 23:38:39 2011
@@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
 
 public class IrcProducer extends DefaultProducer {
 
-    public static final String[] COMMANDS = new String[]{"AWAY", "INVITE", "ISON", "JOIN", "KICK", "LIST", "NAMES",
+    public static final String[] COMMANDS = new String[] {"AWAY", "INVITE", "ISON", "JOIN", "KICK", "LIST", "NAMES",
         "PRIVMSG", "MODE", "NICK", "NOTICE", "PART", "PONG", "QUIT", "TOPIC", "WHO", "WHOIS", "WHOWAS", "USERHOST"};
 
     private static final transient Logger LOG = LoggerFactory.getLogger(IrcProducer.class);
@@ -57,9 +57,9 @@ public class IrcProducer extends Default
             LOG.debug("Sending to: {} message: {}", targetChannel, msg);
             connection.doPrivmsg(targetChannel, msg);
         } else {
-            for (String channel : endpoint.getConfiguration().getChannels()) {
+            for (IrcChannel channel : endpoint.getConfiguration().getChannels()) {
                 LOG.debug("Sending to: {} message: {}", channel, msg);
-                connection.doPrivmsg(channel, msg);
+                connection.doPrivmsg(channel.getName(), msg);
             }
         }
     }
@@ -76,9 +76,9 @@ public class IrcProducer extends Default
     @Override
     protected void doStop() throws Exception {
         if (connection != null) {
-            for (String channel : endpoint.getConfiguration().getChannels()) {
+            for (IrcChannel channel : endpoint.getConfiguration().getChannels()) {
                 LOG.debug("Parting: {}", channel);
-                connection.doPart(channel);
+                connection.doPart(channel.getName());
             }
             connection.removeIRCEventListener(listener);
         }

Modified: camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/CodehausIrcChat.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/CodehausIrcChat.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/CodehausIrcChat.java (original)
+++ camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/CodehausIrcChat.java Fri Sep  9 23:38:39 2011
@@ -91,10 +91,8 @@ public final class CodehausIrcChat {
     }
 
     public static void main(String[] args) throws InterruptedException {
-        //final IrcConfiguration config = new IrcConfiguration("irc.codehaus.org", "camel-irc", "Camel IRC Component", "#camel-test");
-
-        List<String> channels = new ArrayList<String>();
-        channels.add("#camel-test");
+        List<IrcChannel> channels = new ArrayList<IrcChannel>();
+        channels.add(new IrcChannel("camel-test", null));
         final IrcConfiguration config = new IrcConfiguration("irc.codehaus.org", "camel-rc", "Camel IRC Component", channels);
 
         final IRCConnection conn = new IRCConnection(config.getHostname(), config.getPorts(), config.getPassword(), config.getNickname(), config.getUsername(), config.getRealname());
@@ -119,8 +117,8 @@ public final class CodehausIrcChat {
 
         // System.out.println("Joining Channel: " + config.getTarget());
 
-        for (String channel : config.getChannels()) {
-            conn.doJoin(channel);
+        for (IrcChannel channel : config.getChannels()) {
+            conn.doJoin(channel.getName());
         }
 
         conn.doPrivmsg("#camel-test", "hi!");

Modified: camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConfigurationTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConfigurationTest.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConfigurationTest.java (original)
+++ camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConfigurationTest.java Fri Sep  9 23:38:39 2011
@@ -16,15 +16,98 @@
  */
 package org.apache.camel.component.irc;
 
+import java.net.URI;
+import java.net.URLEncoder;
 import java.util.Dictionary;
 import java.util.List;
 
+import org.apache.camel.Endpoint;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.junit.Test;
 
 public class IrcConfigurationTest extends CamelTestSupport {
 
     @Test
+    public void testInvalidUriConversion() throws Exception {
+        // Note: valid URIs won't throw on new URI(endpoint.getEndpointUri())
+        
+        String deprecate;
+        String sanitized;
+        Endpoint endpoint;
+        IrcComponent component = context.getComponent("irc", IrcComponent.class);
+
+        // Test conversion of the URI path to @channel parameter (drop the '#')
+        deprecate = "irc://camelbot@irc.freenode.net:1234/#camel";
+        sanitized = "irc://camelbot@irc.freenode.net:1234?channel=camel";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test conversion of the URI path to @channel parameter (encode the double '##')
+        deprecate = "irc://camelbot@irc.freenode.net/##camel";
+        sanitized = "irc://camelbot@irc.freenode.net?channel=%23%23camel";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test drop path and both path and @channels are specified
+        deprecate = "irc://camelbot@irc.freenode.net/#karaf?channels=#camel,#cxf";
+        sanitized = "irc://camelbot@irc.freenode.net?channel=camel&channel=cxf";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test multiple channels, no keys
+        deprecate = "irc://camelbot@irc.freenode.net?channels=#camel,#cxf";
+        sanitized = "irc://camelbot@irc.freenode.net?channel=camel&channel=cxf";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test multiple channels, with keys
+        deprecate = "irc://camelbot@irc.freenode.net?channels=#camel,#cxf&keys=foo,bar";
+        sanitized = "irc://camelbot@irc.freenode.net?channel=camel!foo&channel=cxf!bar";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test multiple channels, with keys (last key is empty)
+        deprecate = "irc://camelbot@irc.freenode.net?channels=#camel,#cxf&keys=foo,";
+        sanitized = "irc://camelbot@irc.freenode.net?channel=camel!foo&channel=cxf";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test multiple channels, deprecated @username
+        deprecate = "irc://irc.freenode.net?keys=,foo&channels=#camel,#cxf&username=camelbot";
+        sanitized = "irc://camelbot@irc.freenode.net?channel=camel&channel=cxf!foo";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test multiple channels, deprecated @username and @password
+        deprecate = "irc://irc.freenode.net?keys=,foo&channels=#camel,#cxf&username=camelbot&password=secret";
+        sanitized = "irc://camelbot:secret@irc.freenode.net?channel=camel&channel=cxf!foo";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test multiple channels, drop @nickname same as @username
+        deprecate = "irc://irc.freenode.net?channels=#camel,#cxf&nickname=camelbot";
+        sanitized = "irc://camelbot@irc.freenode.net?channel=camel&channel=cxf";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+
+        // Test with encoding of @realname
+        deprecate = "irc://user@irc.freenode.net?keys=foo,&channels=#camel,#cxf&realname=Camel Bot&username=user&nickname=camelbot";
+        sanitized = "irc://user@irc.freenode.net?realname=Camel%20Bot&nickname=camelbot&channel=camel!foo&channel=cxf";
+        endpoint = component.createEndpoint(deprecate); 
+        assertEquals(sanitized, endpoint.getEndpointUri());
+        assertNotNull(new URI(endpoint.getEndpointUri()));
+    }
+
+    @Test
     public void testConfigureFormat1() throws Exception {
         IrcComponent component = context.getComponent("irc", IrcComponent.class);
 
@@ -33,9 +116,9 @@ public class IrcConfigurationTest extend
         IrcConfiguration conf = endpoint.getConfiguration();
         assertEquals("camelbot", conf.getNickname());
         assertEquals("irc.freenode.net", conf.getHostname());
-        List<String> channels = conf.getChannels();
+        List<IrcChannel> channels = conf.getChannels();
         assertEquals(1, channels.size());
-        assertEquals("#camel", channels.get(0));
+        assertEquals("#camel", channels.get(0).getName());
     }
 
     @Test
@@ -48,9 +131,9 @@ public class IrcConfigurationTest extend
         IrcConfiguration conf = endpoint.getConfiguration();
         assertEquals("camelbot", conf.getNickname());
         assertEquals("irc.freenode.net", conf.getHostname());
-        List<String> channels = conf.getChannels();
+        List<IrcChannel> channels = conf.getChannels();
         assertEquals(1, channels.size());
-        assertEquals("#camel", channels.get(0));
+        assertEquals("#camel", channels.get(0).getName());
     }
 
     @Test
@@ -63,9 +146,9 @@ public class IrcConfigurationTest extend
         IrcConfiguration conf = endpoint.getConfiguration();
         assertEquals("camelbot", conf.getNickname());
         assertEquals("irc.freenode.net", conf.getHostname());
-        List<String> channels = conf.getChannels();
+        List<IrcChannel> channels = conf.getChannels();
         assertEquals(1, channels.size());
-        assertEquals("#camel", channels.get(0));
+        assertEquals("#camel", channels.get(0).getName());
     }
 
     @Test
@@ -78,12 +161,11 @@ public class IrcConfigurationTest extend
         IrcConfiguration conf = endpoint.getConfiguration();
         assertEquals("camelbot", conf.getNickname());
         assertEquals("irc.freenode.net", conf.getHostname());
-        List<String> channels = conf.getChannels();
+        List<IrcChannel> channels = conf.getChannels();
         assertEquals(2, channels.size());
-        assertEquals("#camel", channels.get(0));
-        Dictionary<String, String> keys = conf.getKeys();
-        assertEquals(2, keys.size());
-        assertEquals("foo", conf.getKey("#smx"));
+        assertNotNull(conf.findChannel("#camel"));
+        assertNotNull(conf.findChannel("#smx"));
+        assertEquals("foo", conf.findChannel("#smx").getKey());
     }
 
     @Test
@@ -97,12 +179,10 @@ public class IrcConfigurationTest extend
         IrcConfiguration conf = endpoint.getConfiguration();
         assertEquals("camelbot", conf.getNickname());
         assertEquals("irc.freenode.net", conf.getHostname());
-        List<String> channels = conf.getChannels();
+        List<IrcChannel> channels = conf.getChannels();
         assertEquals(2, channels.size());
-        assertEquals("#camel", channels.get(0));
-        Dictionary<String, String> keys = conf.getKeys();
-        assertEquals(1, keys.size());
-        assertEquals("foo", conf.getKey("#camel"));
+        assertNotNull(conf.findChannel("#camel"));
+        assertEquals("foo", conf.findChannel("#camel").getKey());
         assertEquals("Camel Bot", conf.getRealname());
     }
 
@@ -117,14 +197,12 @@ public class IrcConfigurationTest extend
         IrcConfiguration conf = endpoint.getConfiguration();
         assertEquals("camelbot", conf.getNickname());
         assertEquals("irc.freenode.net", conf.getHostname());
-        List<String> channels = conf.getChannels();
+        List<IrcChannel> channels = conf.getChannels();
         assertEquals(2, channels.size());
-        assertEquals("#camel", channels.get(0));
-        Dictionary<String, String> keys = conf.getKeys();
-        assertEquals(2, keys.size());
-        assertEquals("foo", conf.getKey("#camel"));
-        assertEquals("bar", conf.getKey("#smx"));
+        assertNotNull(conf.findChannel("#camel"));
+        assertNotNull(conf.findChannel("#smx"));
+        assertEquals("foo", conf.findChannel("#camel").getKey());
+        assertEquals("bar", conf.findChannel("#smx").getKey());
         assertEquals("Camel Bot", conf.getRealname());
     }
-
 }

Modified: camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConsumerTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConsumerTest.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConsumerTest.java (original)
+++ camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcConsumerTest.java Fri Sep  9 23:38:39 2011
@@ -46,17 +46,11 @@ public class IrcConsumerTest {
         configuration = mock(IrcConfiguration.class);
         listener = mock(IRCEventAdapter.class);
 
-        List<String> channels = new ArrayList<String>();
-        List<String> keys = new ArrayList<String>();
-
-        channels.add("chan1");
-        channels.add("chan2");
-
-        keys.add("");
-        keys.add("chan2key");
+        List<IrcChannel> channels = new ArrayList<IrcChannel>();
+        channels.add(new IrcChannel("#chan1", null));
+        channels.add(new IrcChannel("#chan2", "chan2key"));
 
         when(configuration.getChannels()).thenReturn(channels);
-
         when(endpoint.getConfiguration()).thenReturn(configuration);
 
         consumer = new IrcConsumer(endpoint, processor, connection);
@@ -66,8 +60,8 @@ public class IrcConsumerTest {
     @Test
     public void doStopTest() throws Exception {
         consumer.doStop();
-        verify(connection).doPart("chan1");
-        verify(connection).doPart("chan2");
+        verify(connection).doPart("#chan1");
+        verify(connection).doPart("#chan2");
         verify(connection).removeIRCEventListener(listener);
     }
 

Modified: camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcEndpointTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcEndpointTest.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcEndpointTest.java (original)
+++ camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcEndpointTest.java Fri Sep  9 23:38:39 2011
@@ -44,54 +44,44 @@ public class IrcEndpointTest {
         configuration = mock(IrcConfiguration.class);
         connection = mock(IRCConnection.class);
 
-        List<String> channels = new ArrayList<String>();
-        Dictionary<String, String> keys = new Hashtable<String, String>();
-
-        channels.add("chan1");
-        channels.add("chan2");
-
-        keys.put("chan1", "");
-        keys.put("chan2", "chan2key");
+        List<IrcChannel> channels = new ArrayList<IrcChannel>();
+        channels.add(new IrcChannel("#chan1", null));
+        channels.add(new IrcChannel("#chan2", "chan2key"));
 
         when(configuration.getChannels()).thenReturn(channels);
-        when(configuration.getKey("chan1")).thenReturn("");
-        when(configuration.getKey("chan2")).thenReturn("chan2key");
-
-
+        when(configuration.findChannel("#chan1")).thenReturn(channels.get(0));
+        when(configuration.findChannel("#chan2")).thenReturn(channels.get(1));
         when(component.getIRCConnection(configuration)).thenReturn(connection);
 
-
         endpoint = new IrcEndpoint("foo", component, configuration);
     }
 
     @Test
     public void doJoinChannelTestNoKey() throws Exception {
-        endpoint.joinChannel("chan1");
-        verify(connection).doJoin("chan1");
+        endpoint.joinChannel("#chan1");
+        verify(connection).doJoin("#chan1");
     }
 
     @Test
     public void doJoinChannelTestKey() throws Exception {
-        endpoint.joinChannel("chan2");
-        verify(connection).doJoin("chan2", "chan2key");
+        endpoint.joinChannel("#chan2");
+        verify(connection).doJoin("#chan2", "chan2key");
     }
 
     @Test
     public void doJoinChannels() throws Exception {
         endpoint.joinChannels();
-        verify(connection).doJoin("chan1");
-        verify(connection).doJoin("chan2", "chan2key");
+        verify(connection).doJoin("#chan1");
+        verify(connection).doJoin("#chan2", "chan2key");
     }
 
 
     @Test
     public void doHandleIrcErrorNickInUse() throws Exception {
         when(connection.getNick()).thenReturn("nick");
-
         endpoint.handleIrcError(IRCEventAdapter.ERR_NICKNAMEINUSE, "foo");
 
         verify(connection).doNick("nick-");
-
         when(connection.getNick()).thenReturn("nick---");
 
         // confirm doNick was not called

Modified: camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcProducerTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcProducerTest.java?rev=1167400&r1=1167399&r2=1167400&view=diff
==============================================================================
--- camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcProducerTest.java (original)
+++ camel/trunk/components/camel-irc/src/test/java/org/apache/camel/component/irc/IrcProducerTest.java Fri Sep  9 23:38:39 2011
@@ -51,17 +51,11 @@ public class IrcProducerTest {
         exchange = mock(Exchange.class);
         message = mock(Message.class);
 
-        List<String> channels = new ArrayList<String>();
-        List<String> keys = new ArrayList<String>();
-
-        channels.add("chan1");
-        channels.add("chan2");
-
-        keys.add("");
-        keys.add("chan2key");
+        List<IrcChannel> channels = new ArrayList<IrcChannel>();
+        channels.add(new IrcChannel("#chan1", null));
+        channels.add(new IrcChannel("#chan2", "chan2key"));
 
         when(configuration.getChannels()).thenReturn(channels);
-
         when(endpoint.getConfiguration()).thenReturn(configuration);
 
         producer = new IrcProducer(endpoint, connection);
@@ -71,8 +65,8 @@ public class IrcProducerTest {
     @Test
     public void doStopTest() throws Exception {
         producer.doStop();
-        verify(connection).doPart("chan1");
-        verify(connection).doPart("chan2");
+        verify(connection).doPart("#chan1");
+        verify(connection).doPart("#chan2");
         verify(connection).removeIRCEventListener(listener);
     }
 
@@ -103,8 +97,8 @@ public class IrcProducerTest {
         when(message.getHeader(IrcConstants.IRC_TARGET, String.class)).thenReturn(null);
 
         producer.process(exchange);
-        verify(connection).doPrivmsg("chan1", "foo");
-        verify(connection).doPrivmsg("chan2", "foo");
+        verify(connection).doPrivmsg("#chan1", "foo");
+        verify(connection).doPrivmsg("#chan2", "foo");
     }
 
     @Test (expected = RuntimeCamelException.class)