[jboss-cvs] JBoss Messaging SVN: r4981 - in trunk: examples and 16 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Sep 18 09:22:51 EDT 2008


Author: ataylor
Date: 2008-09-18 09:22:51 -0400 (Thu, 18 Sep 2008)
New Revision: 4981

Added:
   trunk/examples/jms/src/org/jboss/jms/example/WildcardExample.java
   trunk/examples/messaging/config/
   trunk/examples/messaging/config/log4j.xml
   trunk/examples/messaging/src/org/jboss/messaging/example/WildCardClient.java
   trunk/src/main/org/jboss/messaging/core/postoffice/Address.java
   trunk/src/main/org/jboss/messaging/core/postoffice/AddressManager.java
   trunk/src/main/org/jboss/messaging/core/postoffice/impl/AddressImpl.java
   trunk/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java
   trunk/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplWildcardManagerTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/SimpleAddressManagerTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/WildcardAddressManagerTest.java
Modified:
   trunk/build-messaging.xml
   trunk/build.xml
   trunk/examples/build.properties
   trunk/examples/jms/build.xml
   trunk/examples/messaging/build.xml
   trunk/src/config/jbm-configuration.xml
   trunk/src/config/jbm-jndi.xml
   trunk/src/main/org/jboss/messaging/core/config/Configuration.java
   trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java
   trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java
   trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java
   trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java
   trunk/src/main/org/jboss/messaging/util/SimpleString.java
   trunk/tests/config/ConfigurationTest-config.xml
   trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/ConfigurationImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/FileConfigurationTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/util/SimpleStringTest.java
Log:
Wildcard subscription support

Modified: trunk/build-messaging.xml
===================================================================
--- trunk/build-messaging.xml	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/build-messaging.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -959,6 +959,10 @@
       <ant dir="${examples.dir}/jms" antfile="build.xml" target="durSubExample"/>
    </target>
 
+    <target name="wildcardExample" depends="client-jar">
+      <ant dir="${examples.dir}/jms" antfile="build.xml" target="wildcardExample"/>
+   </target>
+
    <target name="SimpleClient" depends="client-jar">
       <ant dir="${examples.dir}/messaging" antfile="build.xml" target="SimpleClient"/>
    </target>
@@ -971,6 +975,10 @@
       <ant dir="${examples.dir}/messaging" antfile="build.xml" target="SimpleExample"/>
    </target>
 
+   <target name="WildCardClient" depends="jar, client-jar">
+         <ant dir="${examples.dir}/messaging" antfile="build.xml" target="WildCardClient"/>
+      </target>
+
    <!-- Performance examples -->
 
    <target name="perfListener" depends="client-jar">

Modified: trunk/build.xml
===================================================================
--- trunk/build.xml	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/build.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -190,6 +190,10 @@
       <ant antfile="build-messaging.xml" target="durSubExample"/>
    </target>
 
+   <target name="wildcardExample" depends="createthirdparty">
+      <ant antfile="build-messaging.xml" target="wildcardExample"/>
+   </target>
+
    <target name="perfListener" depends="createthirdparty">
       <ant antfile="build-messaging.xml" target="perfListener"/>
    </target>
@@ -229,4 +233,8 @@
    <target name="SimpleExample" depends="createthirdparty">
       <ant antfile="build-messaging.xml" target="SimpleExample"/>
    </target>
+
+   <target name="WildCardClient" depends="createthirdparty">
+      <ant antfile="build-messaging.xml" target="WildCardClient"/>
+   </target>
 </project>

Modified: trunk/examples/build.properties
===================================================================
--- trunk/examples/build.properties	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/examples/build.properties	2008-09-18 13:22:51 UTC (rev 4981)
@@ -1,4 +1,3 @@
 lib.dir=../../thirdparty
 client.jar=../../build/jars/jboss-messaging-client.jar
 server.jar=../../build/jars/jboss-messaging.jar
-config.dir=../../tests/config/

Modified: trunk/examples/jms/build.xml
===================================================================
--- trunk/examples/jms/build.xml	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/examples/jms/build.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -120,6 +120,13 @@
       </java>
    </target>
 
+   <target name="wildcardExample" depends="compile"
+           description="-> publish/subscribe example using a topic and a durable subscriber">
+      <java classname="org.jboss.jms.example.WildcardExample" fork="true">
+         <classpath refid="runtime.classpath"/>
+      </java>
+   </target>
+
    <target name="echo-params">
       <echo>
 ***********************************************************************************

Added: trunk/examples/jms/src/org/jboss/jms/example/WildcardExample.java
===================================================================
--- trunk/examples/jms/src/org/jboss/jms/example/WildcardExample.java	                        (rev 0)
+++ trunk/examples/jms/src/org/jboss/jms/example/WildcardExample.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.example;
+
+import org.jboss.messaging.core.logging.Logger;
+
+import javax.jms.*;
+import javax.naming.InitialContext;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class WildcardExample
+{
+   final static Logger log = Logger.getLogger(WildcardExample.class);
+
+   public static void main(final String[] args)
+   {
+      Connection connection = null;
+      try
+      {
+         //create an initial context, env will be picked up from jndi.properties
+         InitialContext initialContext = new InitialContext();
+         Topic topicA = (Topic) initialContext.lookup("/topic/topicA");
+         Topic topicB = (Topic) initialContext.lookup("/topic/topicB");
+         ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");
+         connection = cf.createConnection();
+         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         MessageProducer messageProducerA = session.createProducer(topicA);
+         MessageProducer messageProducerB = session.createProducer(topicB);
+
+         Topic wildCardTopic = session.createTopic("topic.*");
+         //or alternatively new JBossTopic("topic.*");
+         MessageConsumer messageConsumer = session.createConsumer(wildCardTopic);
+         Message messageA = session.createTextMessage("This is a text message from TopicA!");
+         Message messageB = session.createTextMessage("This is a text message from TopicB!");
+         connection.start();
+
+         log.info("publishing message to topicA");
+         messageProducerA.send(messageA);
+         log.info("publishing message to topicB");
+         messageProducerB.send(messageB);
+
+         TextMessage msg1 = (TextMessage) messageConsumer.receive(5000);
+         log.info("received message = " + msg1.getText());
+         TextMessage msg2 = (TextMessage) messageConsumer.receive(5000);
+         log.info("received message = " + msg2.getText());
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+      }
+
+      finally
+      {
+         if (connection != null)
+         {
+            try
+            {
+               connection.close();
+            }
+            catch (JMSException e)
+            {
+               e.printStackTrace();
+            }
+         }
+      }
+   }
+}

Modified: trunk/examples/messaging/build.xml
===================================================================
--- trunk/examples/messaging/build.xml	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/examples/messaging/build.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -37,6 +37,7 @@
    <property file="../build.properties"/>
 
    <property name="src.dir" value="src"/>
+   <property name="config.dir" value="config"/>
    <property name="build.dir" value="build"/>
 
    <path id="compile.classpath">
@@ -96,4 +97,10 @@
       </java>
    </target>
 
+   <target name="WildCardClient" depends="compile">
+      <java classname="org.jboss.messaging.example.WildCardClient" fork="true">
+         <classpath refid="runtime.classpath"/>
+      </java>
+   </target>
+
 </project>
\ No newline at end of file

Copied: trunk/examples/messaging/config/log4j.xml (from rev 4980, trunk/examples/jms/config/log4j.xml)
===================================================================
--- trunk/examples/messaging/config/log4j.xml	                        (rev 0)
+++ trunk/examples/messaging/config/log4j.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- $Id: log4j.xml 2318 2007-02-15 02:11:43Z ovidiu.feodorov at jboss.com $ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+   <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+      <param name="Target" value="System.out"/>
+      <param name="Threshold" value="INFO"/>
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p @%t [%c{1}] %m%n"/>
+      </layout>
+   </appender>
+
+  <root>
+      <appender-ref ref="CONSOLE"/>
+   </root>
+
+</log4j:configuration>


Property changes on: trunk/examples/messaging/config/log4j.xml
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: trunk/examples/messaging/src/org/jboss/messaging/example/WildCardClient.java
===================================================================
--- trunk/examples/messaging/src/org/jboss/messaging/example/WildCardClient.java	                        (rev 0)
+++ trunk/examples/messaging/src/org/jboss/messaging/example/WildCardClient.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,104 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.example;
+
+import org.jboss.messaging.core.client.*;
+import org.jboss.messaging.core.client.impl.ClientSessionFactoryImpl;
+import org.jboss.messaging.core.config.TransportConfiguration;
+import org.jboss.messaging.core.exception.MessagingException;
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.jms.client.JBossTextMessage;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class WildCardClient
+{
+   final static Logger log = Logger.getLogger(WildCardClient.class);
+   public static void main(final String[] args)
+   {
+      ClientSession clientSession = null;
+      ClientConsumer clientConsumer = null;
+      SimpleString wildCardQ = new SimpleString("queuejms.#");
+      try
+      {
+         ClientSessionFactory sessionFactory =
+            new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.netty.NettyConnectorFactory"));
+         clientSession = sessionFactory.createSession(false, true, true, 1, false);
+         SimpleString queue = new SimpleString("queuejms.testQueue");
+         SimpleString queue2 = new SimpleString("queuejms.MyQueue");
+
+         ClientProducer clientProducer = clientSession.createProducer(queue);
+         ClientProducer clientProducer2 = clientSession.createProducer(queue2);
+         ClientMessage message = clientSession.createClientMessage(JBossTextMessage.TYPE, false, 0,
+                                                       System.currentTimeMillis(), (byte) 1);
+         message.getBody().putString("This is a message from queue " + queue);
+         ClientMessage message2 = clientSession.createClientMessage(JBossTextMessage.TYPE, false, 0,
+                                                       System.currentTimeMillis(), (byte) 1);
+         message2.getBody().putString("This is a message from queue " + queue2);
+
+
+         clientSession.createQueue(wildCardQ, wildCardQ, null, false, true);clientConsumer = clientSession.createConsumer(wildCardQ);
+         clientProducer.send(message);
+         log.info("message sent to " + queue);
+         clientProducer2.send(message2);
+         log.info("message sent to " + queue2);
+         clientSession.start();
+         Message msg = clientConsumer.receive(5000);
+         clientSession.acknowledge();
+         log.info("message received: " + msg.getBody().getString());
+         Message msg2 = clientConsumer.receive(5000);
+         clientSession.acknowledge();
+         log.info("message received: " + msg2.getBody().getString());
+      }
+      catch(Exception e)
+      {
+         e.printStackTrace();
+      }
+      finally
+      {
+         if(clientConsumer != null)
+         {
+            try
+            {
+               clientConsumer.close();
+            }
+            catch (MessagingException e)
+            {
+            }
+         }
+         if (clientSession != null)
+         {
+            try
+            {
+               clientSession.deleteQueue(wildCardQ);
+               clientSession.close();
+            }
+            catch (MessagingException ignore)
+            {
+            }
+         }
+      }
+   }
+}

Modified: trunk/src/config/jbm-configuration.xml
===================================================================
--- trunk/src/config/jbm-configuration.xml	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/config/jbm-configuration.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -11,16 +11,18 @@
       <security-enabled>true</security-enabled>
       
       <security-invalidation-interval>10000</security-invalidation-interval>
-      
+
+      <wild-card-routing-enabled>true</wild-card-routing-enabled>
+
       <!-- true to expose JBoss Messaging resources through JMX -->
       <jmx-management-enabled>true</jmx-management-enabled>
     
       <!--  call timeout in milliseconds -->
       <call-timeout>30000</call-timeout>
       
-      <packet-confirmation-batch-size>1000</packet-confirmation-batch-size>
+      <packet-confirmation-batch-size>10000</packet-confirmation-batch-size>
       
-      <connection-scan-period>1000</connection-scan-period>
+      <connection-scan-period>10000</connection-scan-period>
       
       <!-- Example interceptors 
       <remoting-interceptors>

Modified: trunk/src/config/jbm-jndi.xml
===================================================================
--- trunk/src/config/jbm-jndi.xml	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/config/jbm-jndi.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -103,6 +103,12 @@
    <topic name="testTopic">
       <entry name="/topic/testTopic"/>
    </topic>
+   <topic name="topic.A">
+      <entry name="/topic/topicA"/>
+   </topic>
+   <topic name="topic.B">
+      <entry name="/topic/topicB"/>
+   </topic>
    <topic name="securedTopic">
       <entry name="/topic/securedTopic"/>
    </topic>

Modified: trunk/src/main/org/jboss/messaging/core/config/Configuration.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/config/Configuration.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/main/org/jboss/messaging/core/config/Configuration.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,12 +22,12 @@
 
 package org.jboss.messaging.core.config;
 
+import org.jboss.messaging.core.server.JournalType;
+
 import java.io.Serializable;
 import java.util.List;
 import java.util.Set;
 
-import org.jboss.messaging.core.server.JournalType;
-
 /**
  * 
  * A Configuration
@@ -145,4 +145,5 @@
    
    void setPagingMaxGlobalSizeBytes(long maxGlobalSize);
 
+   boolean isWildcardRoutingEnabled();
 }

Modified: trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,15 +22,15 @@
 
 package org.jboss.messaging.core.config.impl;
 
+import org.jboss.messaging.core.config.Configuration;
+import org.jboss.messaging.core.config.TransportConfiguration;
+import org.jboss.messaging.core.server.JournalType;
+
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import org.jboss.messaging.core.config.TransportConfiguration;
-import org.jboss.messaging.core.config.Configuration;
-import org.jboss.messaging.core.server.JournalType;
-
 /**
  * @author <a href="mailto:ataylor at redhat.com>Andy Taylor</a>
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
@@ -83,7 +83,9 @@
    
    public static final int DEFAULT_JOURNAL_MAX_AIO = 5000;
    
-   public static final int DEFAULT_JOURNAL_REUSE_BUFFER_SIZE = -1;   
+   public static final int DEFAULT_JOURNAL_REUSE_BUFFER_SIZE = -1;
+
+   public static final boolean DEFAULT_WILDCARD_ROUTING_ENABLED = false;
    
    
    // Attributes -----------------------------------------------------------------------------
@@ -143,8 +145,10 @@
    protected int journalMaxAIO = DEFAULT_JOURNAL_MAX_AIO;
    
    protected int journalBufferReuseSize = DEFAULT_JOURNAL_REUSE_BUFFER_SIZE;
-   
-   
+
+   protected boolean wildcardRoutingEnabled = DEFAULT_WILDCARD_ROUTING_ENABLED;
+
+
    public boolean isClustered()
    {
       return clustered;
@@ -366,7 +370,12 @@
       this.createJournalDir = create;
    }
 
-	public boolean isSecurityEnabled()
+   public boolean isWildcardRoutingEnabled()
+   {
+      return wildcardRoutingEnabled;
+   }
+
+   public boolean isSecurityEnabled()
 	{
 	   return securityEnabled;
 	}
@@ -429,6 +438,7 @@
              cother.isJournalSyncTransactional() == this.isJournalSyncTransactional() &&
              cother.isRequireDestinations() == this.isRequireDestinations() &&
              cother.isSecurityEnabled() == this.isSecurityEnabled() &&
+             cother.isWildcardRoutingEnabled() == this.isWildcardRoutingEnabled() &&
              cother.getBindingsDirectory().equals(this.getBindingsDirectory()) &&
              cother.getJournalDirectory().equals(this.getJournalDirectory()) &&
              cother.getJournalFileSize() == this.getJournalFileSize() &&

Modified: trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,13 +22,6 @@
 
 package org.jboss.messaging.core.config.impl;
 
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
 import org.jboss.messaging.core.config.TransportConfiguration;
 import org.jboss.messaging.core.logging.Logger;
 import org.jboss.messaging.core.server.JournalType;
@@ -38,6 +31,13 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * ConfigurationImpl
  * This class allows the Configuration class to be configured via a config file.
@@ -349,8 +349,8 @@
       journalMinFiles = getInteger(e, "journal-min-files", journalMinFiles);
 
       journalMaxAIO = getInteger(e, "journal-max-aio", journalMaxAIO);
-      
-      
+
+      wildcardRoutingEnabled = getBoolean(e, "wild-card-routing-enabled", wildcardRoutingEnabled);
    }
 
    public String getConfigurationUrl()

Added: trunk/src/main/org/jboss/messaging/core/postoffice/Address.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/Address.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/Address.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.postoffice;
+
+import org.jboss.messaging.util.SimpleString;
+
+import java.util.List;
+
+/**
+ * USed to hold a hierarchichal style address, delimited by a '.'.
+ *
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public interface Address
+{
+   SimpleString getAddress();
+
+   SimpleString[] getAddressParts();
+
+   boolean containsWildCard();
+
+   List<Address> getLinkedAddresses();
+
+   void addLinkedAddress(Address address);
+
+   void removLinkedAddress(Address actualAddress);
+
+   void removeAddressPart(int pos);
+}

Added: trunk/src/main/org/jboss/messaging/core/postoffice/AddressManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/AddressManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/AddressManager.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.postoffice;
+
+import org.jboss.messaging.util.SimpleString;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Used to maintain addresses and Bindings.
+ * 
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public interface AddressManager
+{
+   void addBinding(Binding binding);
+
+   boolean addMapping(SimpleString address, Binding binding);
+
+   List<Binding> getBindings(SimpleString address);
+
+   void clear();
+
+   Map<SimpleString, List<Binding>> getMappings();
+
+   Binding removeBinding(SimpleString queueName);
+
+   boolean removeMapping(SimpleString address, SimpleString queueName);
+
+   boolean addDestination(SimpleString address);
+
+   boolean removeDestination(SimpleString address);
+
+   boolean containsDestination(SimpleString address);
+
+   Set<SimpleString> getDestinations();
+
+   Binding getBinding(SimpleString queueName);
+
+   Map<SimpleString, Binding> getBindings();
+}

Added: trunk/src/main/org/jboss/messaging/core/postoffice/impl/AddressImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/impl/AddressImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/impl/AddressImpl.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,119 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.postoffice.impl;
+
+import org.jboss.messaging.core.postoffice.Address;
+import static org.jboss.messaging.core.postoffice.impl.WildcardAddressManager.DELIM;
+import static org.jboss.messaging.core.postoffice.impl.WildcardAddressManager.SINGLE_WORD;
+import org.jboss.messaging.util.SimpleString;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**splits an address string into its hierarchical parts split by '.'
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class AddressImpl implements Address
+{
+   private SimpleString address;
+
+   private SimpleString[] addressParts;
+
+   private boolean containsWildCard;
+   private List<Address> linkedAddresses = new ArrayList<Address>();
+
+   public AddressImpl(final SimpleString address)
+   {
+      this.address = address;
+      this.addressParts = address.split(DELIM);
+      containsWildCard = address.contains(SINGLE_WORD);
+   }
+
+   public SimpleString getAddress()
+   {
+      return address;
+   }
+
+   public SimpleString[] getAddressParts()
+   {
+      return addressParts;
+   }
+
+   public boolean containsWildCard()
+   {
+      return containsWildCard;
+   }
+
+   public List<Address> getLinkedAddresses()
+   {
+      return linkedAddresses;
+   }
+
+   public void addLinkedAddress(Address address)
+   {
+      linkedAddresses.add(address);
+   }
+
+   public void removLinkedAddress(Address actualAddress)
+   {
+      linkedAddresses.remove(actualAddress);
+   }
+
+   public void removeAddressPart(final int pos)
+   {
+      SimpleString newAddress = new SimpleString("");
+      boolean started=false;
+      for (int i = 0; i < addressParts.length; i++)
+      {
+         SimpleString addressPart = addressParts[i];
+         if(i != pos)
+         {
+            if(started)
+            {
+               newAddress = newAddress.concat('.');
+            }
+            newAddress = newAddress.concat(addressPart);
+            started=true;
+         }
+      }
+      this.address = newAddress;
+      this.addressParts = address.split(DELIM);
+      containsWildCard = address.contains(SINGLE_WORD);
+   }
+
+   public boolean equals(Object o)
+   {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      AddressImpl address1 = (AddressImpl) o;
+
+      if (!address.equals(address1.address)) return false;
+
+      return true;
+   }
+
+   public int hashCode()
+   {
+      return address.hashCode();
+   }
+}

Modified: trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -29,6 +29,7 @@
 import org.jboss.messaging.core.paging.PagingManager;
 import org.jboss.messaging.core.paging.PagingStore;
 import org.jboss.messaging.core.persistence.StorageManager;
+import org.jboss.messaging.core.postoffice.AddressManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.FlowController;
 import org.jboss.messaging.core.postoffice.PostOffice;
@@ -37,14 +38,11 @@
 import org.jboss.messaging.core.server.QueueFactory;
 import org.jboss.messaging.core.server.ServerMessage;
 import org.jboss.messaging.core.transaction.ResourceManager;
-import org.jboss.messaging.util.ConcurrentHashSet;
-import org.jboss.messaging.util.ConcurrentSet;
 import org.jboss.messaging.util.SimpleString;
 
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * 
@@ -58,12 +56,8 @@
 {  
    private static final Logger log = Logger.getLogger(PostOfficeImpl.class);
    
-   private final ConcurrentMap<SimpleString, List<Binding>> mappings = new ConcurrentHashMap<SimpleString, List<Binding>>();
+   private final AddressManager addressManager;
    
-   private final ConcurrentSet<SimpleString> destinations = new ConcurrentHashSet<SimpleString>();
-   
-   private final ConcurrentMap<SimpleString, Binding> nameMap = new ConcurrentHashMap<SimpleString, Binding>();
-   
    private final ConcurrentMap<SimpleString, FlowController> flowControllers = new ConcurrentHashMap<SimpleString, FlowController>();
    
    private final QueueFactory queueFactory;
@@ -84,7 +78,7 @@
 
    public PostOfficeImpl(final StorageManager storageManager, final PagingManager pagingManager,
    		                final QueueFactory queueFactory, final ManagementService managementService, final boolean checkAllowable,
-                         final ResourceManager resourceManager)
+                         final ResourceManager resourceManager, boolean enableWildCardRouting)
    {
       this.storageManager = storageManager;
 
@@ -97,6 +91,15 @@
       this.pagingManager = pagingManager;
 
       this.resourceManager = resourceManager;
+
+      if(enableWildCardRouting)
+      {
+         addressManager = new WildcardAddressManager();
+      }
+      else
+      {
+         addressManager = new SimpleAddressManager();
+      }
    }
       
    // MessagingComponent implementation ---------------------------------------
@@ -122,12 +125,8 @@
    {
       pagingManager.stop();
       
-      mappings.clear();
+      addressManager.clear();
       
-      destinations.clear();
-
-      nameMap.clear();
-      
       started = false;
    }
    
@@ -140,7 +139,7 @@
 
    public boolean addDestination(final SimpleString address, final boolean durable) throws Exception
    {      
-   	boolean added = destinations.addIfAbsent(address);
+   	boolean added = addressManager.addDestination(address);// destinations.addIfAbsent(address);
    	
    	if (added)
    	{   	
@@ -158,7 +157,7 @@
    
    public boolean removeDestination(final SimpleString address, final boolean durable) throws Exception
    {      
-      boolean removed = destinations.remove(address);
+      boolean removed = addressManager.removeDestination(address);
       
       if (removed)
       {
@@ -176,12 +175,12 @@
    
    public boolean containsDestination(final SimpleString address)
    {
-      return destinations.contains(address);
+      return addressManager.containsDestination(address);
    }
 
    public Set<SimpleString> listAllDestinations()
    {
-      return destinations;
+      return addressManager.getDestinations();
    }
 
    public Binding addBinding(final SimpleString address, final SimpleString queueName, final Filter filter, 
@@ -215,7 +214,7 @@
    
    public List<Binding> getBindingsForAddress(final SimpleString address)
    {
-      List<Binding> bindings = mappings.get(address);
+      List<Binding> bindings = addressManager.getBindings(address);
       
       if (bindings != null)
       {
@@ -229,7 +228,7 @@
    
    public Binding getBinding(final SimpleString queueName)
    {
-      return nameMap.get(queueName);
+      return addressManager.getBinding(queueName);
    }
    
    public List<MessageReference> route(final ServerMessage message) throws Exception
@@ -247,14 +246,14 @@
              
          if (checkAllowable)
          {
-            if (!destinations.contains(address))
+            if (!addressManager.containsDestination(address))
             {
                throw new MessagingException(MessagingException.ADDRESS_DOES_NOT_EXIST,
                                             "Cannot route to address " + address);
             }
          }
               
-         List<Binding> bindings = mappings.get(address);
+         List<Binding> bindings = addressManager.getBindings(address);
          
          List<MessageReference> refs = new ArrayList<MessageReference>();
          
@@ -310,7 +309,7 @@
 
    public Map<SimpleString, List<Binding>> getMappings()
    {
-      return mappings;
+      return addressManager.getMappings();
    }
 
    public FlowController getFlowController(SimpleString address)
@@ -323,7 +322,9 @@
       if (this.backup != backup)
       {
          this.backup = backup;
-         
+
+         Map<SimpleString, Binding> nameMap = addressManager.getBindings();
+
          for (Binding binding: nameMap.values())
          {
             binding.getQueue().setBackup(backup);
@@ -346,27 +347,16 @@
    }
    
    private void addBindingInMemory(final Binding binding) throws Exception
-   {              
-      List<Binding> bindings = new CopyOnWriteArrayList<Binding>();
-      
-      List<Binding> prevBindings = mappings.putIfAbsent(binding.getAddress(), bindings);
-      
-      if (prevBindings != null)
+   {
+      boolean exists = addressManager.addMapping(binding.getAddress(), binding);
+      if (!exists)
       {
-         bindings = prevBindings;
-      } else
-      {
          managementService.registerAddress(binding.getAddress());
       }
                      
       managementService.registerQueue(binding.getQueue(), binding.getAddress(), storageManager);
 
-      bindings.add(binding);  
-
-      if (nameMap.putIfAbsent(binding.getQueue().getName(), binding) != null)
-      {
-         throw new IllegalStateException("Binding already exists " + binding);
-      }     
+      addressManager.addBinding(binding);
       
       FlowController flowController = flowControllers.get(binding.getAddress());
                     
@@ -375,38 +365,10 @@
    
    private Binding removeQueueInMemory(final SimpleString queueName) throws Exception
    {
-      Binding binding = nameMap.remove(queueName);
-      
-      if (binding == null)
-      {
-         throw new IllegalStateException("Queue is not bound " + queueName);
-      }
-                  
-      List<Binding> bindings = mappings.get(binding.getAddress());
-                  
-      for (Iterator<Binding> iter = bindings.iterator(); iter.hasNext();)
-      {
-         Binding b = iter.next();
-         
-         if (b.getQueue().getName().equals(queueName))
-         {
-            binding = b;
-                                          
-            break;
-         }
-      }
-      
-      if (binding == null)
-      {
-         throw new IllegalStateException("Cannot find binding " + queueName);
-      }
-      
-      bindings.remove(binding);      
-      
-      if (bindings.isEmpty())
-      {
-         mappings.remove(binding.getAddress());
-                           
+      Binding binding = addressManager.removeBinding(queueName);
+
+      if (addressManager.removeMapping(binding.getAddress(), queueName))
+      {         
          managementService.unregisterAddress(binding.getAddress());
          
          binding.getQueue().setFlowController(null);

Added: trunk/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.postoffice.impl;
+
+import org.jboss.messaging.core.postoffice.AddressManager;
+import org.jboss.messaging.core.postoffice.Binding;
+import org.jboss.messaging.util.ConcurrentHashSet;
+import org.jboss.messaging.util.ConcurrentSet;
+import org.jboss.messaging.util.SimpleString;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A simple address manager that maintains the addresses and bindings.
+ *
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public  class SimpleAddressManager implements AddressManager
+{
+   private final ConcurrentMap<SimpleString, List<Binding>> mappings = new ConcurrentHashMap<SimpleString, List<Binding>>();
+
+   private final ConcurrentSet<SimpleString> destinations = new ConcurrentHashSet<SimpleString>();
+
+   private final ConcurrentMap<SimpleString, Binding> nameMap = new ConcurrentHashMap<SimpleString, Binding>();
+
+   public void addBinding(Binding binding)
+   {
+      if (nameMap.putIfAbsent(binding.getQueue().getName(), binding) != null)
+      {
+         throw new IllegalStateException("Binding already exists " + binding);
+      }
+   }
+
+   public boolean addMapping(final SimpleString address, final Binding binding)
+   {
+      List<Binding> bindings = new CopyOnWriteArrayList<Binding>();
+      List<Binding> prevBindings = mappings.putIfAbsent(address, bindings);
+
+      if (prevBindings != null)
+      {
+         bindings = prevBindings;
+      }
+
+      bindings.add(binding);
+      return prevBindings != null;
+   }
+   public List<Binding> getBindings(final SimpleString address)
+   {
+      return mappings.get(address);
+   }
+
+   public boolean addDestination(final SimpleString address)
+   {
+      return destinations.addIfAbsent(address);
+   }
+
+   public boolean removeDestination(final SimpleString address)
+   {
+      return destinations.remove(address);
+   }
+
+   public boolean containsDestination(final SimpleString address)
+   {
+      return destinations.contains(address);
+   }
+
+   public Set<SimpleString> getDestinations()
+   {
+      return destinations;
+   }
+
+   public Binding getBinding(final SimpleString queueName)
+   {
+      return nameMap.get(queueName);
+   }
+
+   public Map<SimpleString, Binding> getBindings()
+   {
+      return nameMap;
+   }
+
+   public void clear()
+   {
+      destinations.clear();
+      nameMap.clear();
+      mappings.clear();
+   }
+
+   public Map<SimpleString, List<Binding>> getMappings()
+   {
+      return mappings;
+   }
+
+
+   public Binding removeBinding(final SimpleString queueName)
+   {
+      Binding binding = nameMap.remove(queueName);
+
+      if (binding == null)
+      {
+         throw new IllegalStateException("Queue is not bound " + queueName);
+      }
+      return binding;
+   }
+
+   public boolean removeMapping(final SimpleString address, final SimpleString queueName)
+   {
+      List<Binding> bindings = mappings.get(address);
+      Binding binding = removeMapping(queueName, bindings);
+
+      if(bindings.isEmpty())
+      {
+         mappings.remove(binding.getAddress());
+      }
+      return bindings.isEmpty();
+   }
+
+   protected Binding removeMapping(final SimpleString queueName, final List<Binding> bindings)
+   {
+      Binding binding = null;
+      for (Iterator<Binding> iter = bindings.iterator(); iter.hasNext();)
+      {
+         Binding b = iter.next();
+
+         if (b.getQueue().getName().equals(queueName))
+         {
+            binding = b;
+
+            break;
+         }
+      }
+
+      if (binding == null)
+      {
+         throw new IllegalStateException("Cannot find binding " + queueName);
+      }
+
+      bindings.remove(binding);
+      return binding;
+   }
+
+}

Added: trunk/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,306 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.postoffice.impl;
+
+import org.jboss.messaging.core.postoffice.Address;
+import org.jboss.messaging.core.postoffice.Binding;
+import org.jboss.messaging.util.SimpleString;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * extends the simple manager to allow wilcard addresses to be used.
+ *
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class WildcardAddressManager extends SimpleAddressManager
+{
+   static final char SINGLE_WORD = '*';
+   static final char ANY_WORDS = '#';
+   static final char DELIM = '.';
+   static final SimpleString SINGLE_WORD_SIMPLESTRING = new SimpleString("*");
+   static final SimpleString ANY_WORDS_SIMPLESTRING = new SimpleString("#");
+   /**
+    * This is the actual wild card binding, for every binding added here 1 or more actual bindings will be added.
+    * i.e. A binding for A.* will bind the same queue to A.B and A.C if they are its linked addresses
+    */
+   private final ConcurrentMap<SimpleString, List<Binding>> wildcardBindings = new ConcurrentHashMap<SimpleString, List<Binding>>();
+
+   /**
+    * All the wild card destinations. So if A.B is added to the actual destinations we add A.*, *.B, *.* etc.
+    */
+   private final ConcurrentMap<SimpleString, Address> wildcardDestinations = new ConcurrentHashMap<SimpleString, Address>();
+
+   /**
+    * This is all the actual destinations, we use this so we can link back from the actual address to its linked wilcard addresses
+    */
+   private final ConcurrentMap<SimpleString, Address> actualDestinations = new ConcurrentHashMap<SimpleString, Address>();
+
+   /**
+    * If the address to add the binding to contains a wildcard then a copy of the binding (with the same underlying queue)
+    * will be added to the actual mappings. Otherwise the binding is added as normal.
+    *
+    * @param address the address to add the mapping to
+    * @param binding the binding to add
+    * @return true if the address was a new mapping
+    */
+   public boolean addMapping(final SimpleString address, final Binding binding)
+   {
+      Address add = wildcardDestinations.get(address);
+      //if this isnt a wildcard destination then just add normally
+      if (add == null)
+      {
+         return super.addMapping(address, binding);
+      }
+      else
+      {
+         //add this as a wildcard binding and add a new binding to any linked addresses.
+         for (Address destination : add.getLinkedAddresses())
+         {
+            BindingImpl binding1 = new BindingImpl(destination.getAddress(), binding.getQueue());
+            super.addMapping(destination.getAddress(), binding1);
+         }
+         List<Binding> bindings = new CopyOnWriteArrayList<Binding>();
+         List<Binding> prevBindings = wildcardBindings.putIfAbsent(address, bindings);
+
+         if (prevBindings != null)
+         {
+            bindings = prevBindings;
+         }
+
+         bindings.add(binding);
+         return prevBindings != null;
+      }
+   }
+
+   /**
+    * If the address is a wild card then the binding will be removed from the actual mappings for any linked address.
+    * otherwise it will be removed as normal.
+    *
+    * @param address   the address to remove the binding from
+    * @param queueName the name of the queue for the binding to remove
+    * @return true if this was the last mapping for a specific address
+    */
+   public boolean removeMapping(final SimpleString address, final SimpleString queueName)
+   {
+      Address add = wildcardDestinations.get(address);
+      //if this isnt a wildcard binding just remove normally
+      if (add == null)
+      {
+         return super.removeMapping(address, queueName);
+      }
+      else
+      {
+         for (Address destination : add.getLinkedAddresses())
+         {
+            super.removeMapping(destination.getAddress(), queueName);
+         }
+         List<Binding> bindings = wildcardBindings.get(address);
+         Binding binding = removeMapping(queueName, bindings);
+
+         if (bindings.isEmpty())
+         {
+            wildcardBindings.remove(binding.getAddress());
+         }
+         return bindings.isEmpty();
+      }
+   }
+
+   public void clear()
+   {
+      super.clear();
+      wildcardBindings.clear();
+      wildcardDestinations.clear();
+   }
+
+   /**
+    * When we add a new destination we calculate all its corresponding wild card matches and add those. We also link the
+    * wild card address added to the actual address.
+    *
+    * @param address the address to add
+    * @return true if it didn't already exist
+    */
+   public boolean addDestination(final SimpleString address)
+   {
+      boolean added = super.addDestination(address);
+      //if this is a new destination we compute any wilcard addresses that would match and add if necessary
+      synchronized (actualDestinations)
+      {
+         if (added)
+         {
+            Address add = new AddressImpl(address);
+            Address prevAddress = actualDestinations.putIfAbsent(address, add);
+            if(prevAddress != null)
+            {
+               add = prevAddress;
+            }
+            List<SimpleString> adds = getAddresses(add);
+            for (SimpleString simpleString : adds)
+            {
+               Address addressToAdd = new AddressImpl(simpleString);
+               Address prev = wildcardDestinations.putIfAbsent(simpleString, addressToAdd);
+               if (prev != null)
+               {
+                  addressToAdd = prev;
+               }
+               addressToAdd.addLinkedAddress(add);
+               add.addLinkedAddress(addressToAdd);
+            }
+         }
+      }
+      return added;
+   }
+
+   /**
+    * If the address is removed then we need to de-link it from its wildcard addresses.
+    * If the wildcard address is then empty then we can remove it completely
+    *
+    * @param address the address to remove
+    * @return if the address was removed
+    */
+   public boolean removeDestination(final SimpleString address)
+   {
+      boolean removed = super.removeDestination(address);
+      synchronized (actualDestinations)
+      {
+         if (removed)
+         {
+            Address actualAddress = actualDestinations.remove(address);
+            List<Address> addresses = actualAddress.getLinkedAddresses();
+            for (Address address1 : addresses)
+            {
+               address1.removLinkedAddress(actualAddress);
+               if (address1.getLinkedAddresses().size() == 0)
+               {
+                  wildcardDestinations.remove(address1.getAddress());
+               }
+            }
+         }
+      }
+      return removed;
+   }
+
+   /**
+    * @param address the address to check
+    * @return true if the address exists or if a wildcard address exists
+    */
+   public boolean containsDestination(final SimpleString address)
+   {
+      return super.containsDestination(address) || wildcardDestinations.keySet().contains(address);
+   }
+
+   private List<SimpleString> getAddresses(final Address address)
+   {
+      List<SimpleString> addresses = new ArrayList<SimpleString>();
+      SimpleString[] parts = address.getAddressParts();
+
+      addresses.add(parts[0]);
+      addresses.add(SINGLE_WORD_SIMPLESTRING);
+      addresses.add(ANY_WORDS_SIMPLESTRING);
+      if (address.getAddressParts().length > 1)
+      {
+         addresses = addPart(addresses, address, 1);
+      }
+      addresses.remove(address.getAddress());
+      return addresses;
+   }
+
+   private List<SimpleString> addPart(final List<SimpleString> addresses, final Address address, final int pos)
+   {
+      List<SimpleString> newAddresses = new ArrayList<SimpleString>();
+      for (SimpleString add : addresses)
+      {
+         newAddresses.add(add.concat(DELIM).concat(SINGLE_WORD));
+         newAddresses.add(add.concat(DELIM).concat(ANY_WORDS));
+         newAddresses.add(add.concat(DELIM).concat(address.getAddressParts()[pos]));
+      }
+      if (pos + 1 < address.getAddressParts().length)
+      {
+         return addPart(newAddresses, address, pos+1);
+      }
+      else
+      {
+         return mergeAddresses(newAddresses);
+      }
+   }
+
+   private List<SimpleString> mergeAddresses(final List<SimpleString> adds)
+   {
+      List<SimpleString> newAddresses = new ArrayList<SimpleString>();
+      for (int j = 0; j < adds.size(); j++)
+      {
+         SimpleString add = adds.get(j);
+         Address address = new AddressImpl(add);
+         SimpleString prev = null;
+         SimpleString next;
+         for (int i = 0; i < address.getAddressParts().length; i++)
+         {
+            SimpleString current = address.getAddressParts()[i];
+            if(i < address.getAddressParts().length-1)
+            {
+               next = address.getAddressParts()[i+1];
+            }
+            else
+            {
+               next = null;
+            }
+            if (current.equals(SINGLE_WORD_SIMPLESTRING) && (ANY_WORDS_SIMPLESTRING.equals(next)))
+            {
+               address.removeAddressPart(i);
+               prev=null;
+               i=-1;
+            }
+            else if (current.equals(ANY_WORDS_SIMPLESTRING) && (ANY_WORDS_SIMPLESTRING.equals(next)))
+            {
+               address.removeAddressPart(i);
+               prev=null;
+               i=-1;
+            }
+            else if (current.equals(ANY_WORDS_SIMPLESTRING) && (SINGLE_WORD_SIMPLESTRING.equals(next)))
+            {
+               address.removeAddressPart(i+1);
+               prev=null;
+               i=-1;
+            }
+            else if (current.equals(ANY_WORDS_SIMPLESTRING) && (ANY_WORDS_SIMPLESTRING.equals(prev)))
+            {
+               address.removeAddressPart(i+1);
+               prev=null;
+               i=-1;
+            }
+            else
+            {
+               prev = current;
+            }
+         }
+         if(!newAddresses.contains(address.getAddress()))
+         {
+            newAddresses.add(address.getAddress());
+         }
+      }
+      return newAddresses;
+   }
+}

Modified: trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,17 +22,6 @@
 
 package org.jboss.messaging.core.server.impl;
 
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
 import org.jboss.messaging.core.config.Configuration;
 import org.jboss.messaging.core.config.TransportConfiguration;
 import org.jboss.messaging.core.exception.MessagingException;
@@ -72,6 +61,11 @@
 import org.jboss.messaging.util.OrderedExecutorFactory;
 import org.jboss.messaging.util.VersionLoader;
 
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.*;
+
 /**
  * The messaging server implementation
  *
@@ -229,7 +223,8 @@
                                       queueFactory,
                                       managementService,
                                       configuration.isRequireDestinations(),
-                                      resourceManager);
+                                      resourceManager,
+                                      configuration.isWildcardRoutingEnabled());
 
       securityRepository = new HierarchicalObjectRepository<Set<Role>>();
       securityRepository.setDefault(new HashSet<Role>());

Modified: trunk/src/main/org/jboss/messaging/util/SimpleString.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/SimpleString.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/src/main/org/jboss/messaging/util/SimpleString.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,13 +22,14 @@
 
 package org.jboss.messaging.util;
 
+import org.jboss.messaging.core.logging.Logger;
 import static org.jboss.messaging.util.DataConstants.SIZE_INT;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 
-import org.jboss.messaging.core.logging.Logger;
 
-
 /**
  * 
  * A SimpleString
@@ -217,8 +218,70 @@
 		
 		return hash;
 	}
-	
-	public static int sizeofString(final SimpleString str)
+
+   public SimpleString[] split(char delim)
+   {
+      if(!contains(delim))
+      {
+         return new SimpleString[]{this};
+      }
+      else
+      {
+         List<SimpleString> all = new ArrayList<SimpleString>();
+         int lasPos = 0;
+         for (int i = 0; i < data.length; i+=2)
+         {
+            byte low = (byte)(delim & 0xFF);  // low byte
+            byte high = (byte)(delim >> 8 & 0xFF);  // high byte
+            if (data[i] == low && data[i+1] == high)
+            {
+               byte[] bytes = new byte[i - lasPos];
+               System.arraycopy(data, lasPos, bytes, 0, bytes.length);
+               lasPos = i + 2;
+               all.add(new SimpleString(bytes));
+            }
+         }
+         byte[] bytes = new byte[data.length - lasPos];
+         System.arraycopy(data, lasPos, bytes, 0, bytes.length);
+         all.add(new SimpleString(bytes));
+         SimpleString[] parts = new SimpleString[all.size()];
+         return all.toArray(parts);
+      }
+   }
+
+
+   public boolean contains(char c)
+   {
+      for (int i = 0; i < data.length; i+=2)
+      {
+         byte low = (byte)(c & 0xFF);  // low byte
+			byte high = (byte)(c >> 8 & 0xFF);  // high byte
+         if (data[i] == low && data[i+1] == high)
+         {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   public SimpleString concat(SimpleString toAdd)
+   {
+      byte[] bytes = new byte[data.length + toAdd.getData().length];
+      System.arraycopy(data, 0, bytes, 0, data.length);
+      System.arraycopy(toAdd.getData(), 0, bytes, data.length, toAdd.getData().length);
+      return new SimpleString(bytes);
+   }
+
+   public SimpleString concat(char c)
+   {
+      byte[] bytes = new byte[data.length + 2];
+      System.arraycopy(data, 0, bytes, 0, data.length);
+      bytes[data.length] = (byte)(c & 0xFF);
+      bytes[data.length+1] = (byte)(c >> 8 & 0xFF);
+      return new SimpleString(bytes);
+   }
+
+   public static int sizeofString(final SimpleString str)
 	{
 	   if (str == null)
 	   {
@@ -226,4 +289,6 @@
 	   }
 		return SIZE_INT + str.data.length;
 	}
+
+
 }
\ No newline at end of file

Modified: trunk/tests/config/ConfigurationTest-config.xml
===================================================================
--- trunk/tests/config/ConfigurationTest-config.xml	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/tests/config/ConfigurationTest-config.xml	2008-09-18 13:22:51 UTC (rev 4981)
@@ -5,7 +5,8 @@
       <scheduled-max-pool-size>12345</scheduled-max-pool-size>        
       <require-destinations>false</require-destinations>
       <security-enabled>false</security-enabled>
-      <security-invalidation-interval>5423</security-invalidation-interval>  
+      <security-invalidation-interval>5423</security-invalidation-interval>
+       <wild-card-routing-enabled>true</wild-card-routing-enabled>
       <call-timeout>7654</call-timeout>    
       <packet-confirmation-batch-size>543</packet-confirmation-batch-size>
       <connection-scan-period>6543</connection-scan-period>

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/ConfigurationImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/ConfigurationImplTest.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/ConfigurationImplTest.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,10 +22,11 @@
 
 package org.jboss.messaging.tests.unit.core.config.impl;
 
-import static org.jboss.messaging.tests.util.RandomUtil.randomBoolean;
-import static org.jboss.messaging.tests.util.RandomUtil.randomInt;
-import static org.jboss.messaging.tests.util.RandomUtil.randomLong;
-import static org.jboss.messaging.tests.util.RandomUtil.randomString;
+import junit.framework.TestCase;
+import org.jboss.messaging.core.config.Configuration;
+import org.jboss.messaging.core.config.impl.ConfigurationImpl;
+import org.jboss.messaging.core.server.JournalType;
+import static org.jboss.messaging.tests.util.RandomUtil.*;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -33,12 +34,6 @@
 import java.io.ObjectOutputStream;
 import java.util.List;
 
-import junit.framework.TestCase;
-
-import org.jboss.messaging.core.config.Configuration;
-import org.jboss.messaging.core.config.impl.ConfigurationImpl;
-import org.jboss.messaging.core.server.JournalType;
-
 /**
  * 
  * A ConfigurationImplTest
@@ -71,6 +66,7 @@
       assertEquals(ConfigurationImpl.DEFAULT_JOURNAL_FILE_SIZE, conf.getJournalFileSize());
       assertEquals(ConfigurationImpl.DEFAULT_JOURNAL_MIN_FILES, conf.getJournalMinFiles());      
       assertEquals(ConfigurationImpl.DEFAULT_JOURNAL_MAX_AIO, conf.getJournalMaxAIO());
+      assertEquals(ConfigurationImpl.DEFAULT_WILDCARD_ROUTING_ENABLED, conf.isWildcardRoutingEnabled());
    }
    
    public void testSetGetAttributes()

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/FileConfigurationTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/FileConfigurationTest.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/config/impl/FileConfigurationTest.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,12 +22,12 @@
 
 package org.jboss.messaging.tests.unit.core.config.impl;
 
-import java.util.Map;
-
+import org.jboss.messaging.core.config.Configuration;
 import org.jboss.messaging.core.config.TransportConfiguration;
-import org.jboss.messaging.core.config.Configuration;
 import org.jboss.messaging.core.config.impl.FileConfiguration;
 
+import java.util.Map;
+
 /**
  * @author <a href="ataylor at redhat.com">Andy Taylor</a>
  * @author <a href="tim.fox at jboss.com">Tim Fox</a>
@@ -56,6 +56,7 @@
       assertEquals(12345678, conf.getJournalFileSize());
       assertEquals(100, conf.getJournalMinFiles());      
       assertEquals(56546, conf.getJournalMaxAIO());
+      assertEquals(true, conf.isWildcardRoutingEnabled());
       
       assertEquals(2, conf.getInterceptorClassNames().size());
       assertTrue(conf.getInterceptorClassNames().contains("org.jboss.messaging.tests.unit.core.config.impl.TestInterceptor1"));

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -59,6 +59,7 @@
 {
    private QueueFactory queueFactory = new FakeQueueFactory();
 
+   protected boolean wildCardRoutingEnabled = false;
    public void testPostOfficeStart() throws Exception
    {
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
@@ -66,7 +67,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
       
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -85,7 +86,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
 
@@ -118,7 +119,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
       
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -166,7 +167,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -212,7 +213,7 @@
 
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
       
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -264,7 +265,7 @@
 
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -310,7 +311,7 @@
       PagingStore store = EasyMock.createNiceMock(PagingStore.class);
       EasyMock.expect(pgm.getPageStore(address1)).andReturn(store);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -342,7 +343,7 @@
       
       PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
       
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -405,7 +406,7 @@
       PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
       
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -465,7 +466,7 @@
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
       PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -527,7 +528,7 @@
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
       PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -586,7 +587,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
  
-      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
 
       final long id = 324;
       final SimpleString name = new SimpleString("wibb22");
@@ -628,7 +629,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
 
       final long id = 324;
       final SimpleString name = new SimpleString("wibb22");
@@ -679,7 +680,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
 
       final SimpleString condition1 = new SimpleString("queue.wibble");
 
@@ -767,7 +768,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -793,7 +794,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -825,7 +826,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -854,7 +855,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -898,7 +899,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -931,7 +932,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -974,7 +975,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -1006,7 +1007,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -1046,7 +1047,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -1086,7 +1087,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -1123,7 +1124,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -1174,7 +1175,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
 
@@ -1209,7 +1210,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1255,7 +1256,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1287,7 +1288,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1318,7 +1319,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1345,7 +1346,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1392,7 +1393,7 @@
 
       EasyMock.expect(pgm.addSize(EasyMock.isA(ServerMessage.class))).andReturn(-1l);
       
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
 
       qf.setPostOffice(postOffice);
       
@@ -1432,7 +1433,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1469,7 +1470,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1509,7 +1510,7 @@
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
       PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
       
       qf.setPostOffice(postOffice);
       
@@ -1568,7 +1569,7 @@
          ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
          PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-         PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null);
+         PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false, null, wildCardRoutingEnabled);
          
          qf.setPostOffice(postOffice);
          

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplWildcardManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplWildcardManagerTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplWildcardManagerTest.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,177 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.tests.unit.core.postoffice.impl;
+
+import org.easymock.EasyMock;
+import org.jboss.messaging.core.management.ManagementService;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.persistence.StorageManager;
+import org.jboss.messaging.core.postoffice.Binding;
+import org.jboss.messaging.core.postoffice.PostOffice;
+import org.jboss.messaging.core.postoffice.impl.PostOfficeImpl;
+import org.jboss.messaging.core.server.MessageReference;
+import org.jboss.messaging.core.server.Queue;
+import org.jboss.messaging.core.server.QueueFactory;
+import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.transaction.ResourceManager;
+import org.jboss.messaging.util.SimpleString;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class PostOfficeImplWildcardManagerTest extends PostOfficeImplTest
+{
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      wildCardRoutingEnabled = true;
+   }
+
+   public void testPostOfficeRouteToWildcardBinding() throws Exception
+   {
+      SimpleString queueName = new SimpleString("testQ");
+      ServerMessage message = EasyMock.createStrictMock(ServerMessage.class);
+      ServerMessage message2 = EasyMock.createStrictMock(ServerMessage.class);
+      ServerMessage message3 = EasyMock.createStrictMock(ServerMessage.class);
+      MessageReference messageReference = EasyMock.createStrictMock(MessageReference.class);
+      MessageReference messageReference2 = EasyMock.createStrictMock(MessageReference.class);
+      MessageReference messageReference3 = EasyMock.createStrictMock(MessageReference.class);
+      SimpleString address = new SimpleString("test.testAddress");
+      SimpleString address2 = new SimpleString("test.testAddress2");
+      SimpleString address3 = new SimpleString("test.testAddress3");
+      Queue queue = EasyMock.createStrictMock(Queue.class);
+      StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
+      QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
+      ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
+
+      qf.setPostOffice(postOffice);
+
+      pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
+      pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject(), (ResourceManager) EasyMock.anyObject());
+      EasyMock.expect(pm.addDestination(address)).andReturn(true);
+      EasyMock.expect(pm.addDestination(address2)).andReturn(true);
+      EasyMock.expect(pm.addDestination(address3)).andReturn(true);
+      EasyMock.expect(message.getDestination()).andStubReturn(address);
+      EasyMock.expect(message2.getDestination()).andStubReturn(address2);
+      EasyMock.expect(message3.getDestination()).andStubReturn(address3);
+      EasyMock.expect(qf.createQueue(-1, queueName, null, false)).andReturn(queue);
+      EasyMock.expect(queue.getName()).andStubReturn(queueName);
+      queue.setBackup(false);
+      queue.setFlowController(null);
+      EasyMock.expect(queue.getFilter()).andStubReturn(null);
+      EasyMock.expect(pgm.addSize(message)).andStubReturn(1000l);
+      //this bit is the test itself, if the reference is created for each queue thenwe know that they have been routed via all 3 queues
+      EasyMock.expect(message.createReference(queue)).andReturn(messageReference);
+      EasyMock.expect(message2.createReference(queue)).andReturn(messageReference2);
+      EasyMock.expect(message3.createReference(queue)).andReturn(messageReference3);
+      EasyMock.replay(pgm,pm, qf, message, message2, message3, queue);
+      postOffice.start();
+      assertTrue(postOffice.addDestination(address, true));
+      assertTrue(postOffice.addDestination(address2, true));
+      assertTrue(postOffice.addDestination(address3, true));
+      assertNotNull(postOffice.getFlowController(address));
+      assertNotNull(postOffice.getFlowController(address2));
+      assertNotNull(postOffice.getFlowController(address3));
+      assertTrue(postOffice.containsDestination(address));
+      assertTrue(postOffice.containsDestination(address2));
+      assertTrue(postOffice.containsDestination(address3));
+      postOffice.addBinding(new SimpleString("test.*"), queueName, null, false);
+      postOffice.route(message);
+      postOffice.route(message2);
+      postOffice.route(message3);
+      EasyMock.verify(pgm, pm, qf, message, message2, message3, queue);
+   }
+
+   public void testPostOfficeRouteToMultipleWildcardBinding() throws Exception
+   {
+      SimpleString queueName = new SimpleString("testQ");
+      SimpleString queueName2 = new SimpleString("testQ2");
+      ServerMessage message = EasyMock.createStrictMock(ServerMessage.class);
+      ServerMessage message2 = EasyMock.createStrictMock(ServerMessage.class);
+      ServerMessage message3 = EasyMock.createStrictMock(ServerMessage.class);
+      ServerMessage message4 = EasyMock.createStrictMock(ServerMessage.class);
+      MessageReference messageReference = EasyMock.createStrictMock(MessageReference.class);
+      MessageReference messageReference2 = EasyMock.createStrictMock(MessageReference.class);
+      MessageReference messageReference3 = EasyMock.createStrictMock(MessageReference.class);
+      MessageReference messageReference4 = EasyMock.createStrictMock(MessageReference.class);
+      SimpleString address = new SimpleString("test.testAddress");
+      SimpleString address2 = new SimpleString("test2.testAddress2");
+      SimpleString address3 = new SimpleString("test.testAddress3");
+      SimpleString address4 = new SimpleString("test2.testAddress3");
+      Queue queue = EasyMock.createStrictMock(Queue.class);
+      Queue queue2 = EasyMock.createStrictMock(Queue.class);
+      StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
+      QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
+      ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true, null, wildCardRoutingEnabled);
+
+      qf.setPostOffice(postOffice);
+
+      pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
+      pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject(), (ResourceManager) EasyMock.anyObject());
+      EasyMock.expect(pm.addDestination(address)).andReturn(true);
+      EasyMock.expect(pm.addDestination(address2)).andReturn(true);
+      EasyMock.expect(pm.addDestination(address3)).andReturn(true);
+      EasyMock.expect(pm.addDestination(address4)).andReturn(true);
+      EasyMock.expect(message.getDestination()).andStubReturn(address);
+      EasyMock.expect(message2.getDestination()).andStubReturn(address2);
+      EasyMock.expect(message3.getDestination()).andStubReturn(address3);
+      EasyMock.expect(message4.getDestination()).andStubReturn(address4);
+      EasyMock.expect(qf.createQueue(-1, queueName, null, false)).andReturn(queue);
+      EasyMock.expect(qf.createQueue(-1, queueName2, null, false)).andReturn(queue2);
+      EasyMock.expect(queue.getName()).andStubReturn(queueName);
+      EasyMock.expect(queue2.getName()).andStubReturn(queueName2);
+      queue.setBackup(false);
+      queue2.setBackup(false);
+      queue.setFlowController(null);
+      queue2.setFlowController(null);
+      EasyMock.expect(queue.getFilter()).andStubReturn(null);
+      EasyMock.expect(queue2.getFilter()).andStubReturn(null);
+      EasyMock.expect(pgm.addSize(message)).andStubReturn(1000l);
+      //this bit is the test itself, if the reference is created for each queue thenwe know that they have been routed via all 3 queues
+      EasyMock.expect(message.createReference(queue)).andReturn(messageReference);
+      EasyMock.expect(message2.createReference(queue2)).andReturn(messageReference2);
+      EasyMock.expect(message3.createReference(queue)).andReturn(messageReference3);
+      EasyMock.expect(message4.createReference(queue2)).andReturn(messageReference4);
+      EasyMock.replay(pgm,pm, qf, message, message2, message3, message4, queue, queue2);
+      postOffice.start();
+      postOffice.addDestination(address, true);
+      postOffice.addDestination(address2, true);
+      postOffice.addDestination(address3, true);
+      postOffice.addDestination(address4, true);
+      postOffice.addBinding(new SimpleString("test.*"), queueName, null, false);
+      postOffice.addBinding(new SimpleString("test2.*"), queueName2, null, false);
+      postOffice.route(message);
+      postOffice.route(message2);
+      postOffice.route(message3);
+      postOffice.route(message4);
+      EasyMock.verify(pgm, pm, qf, message, message2, message3, message4,queue, queue2);
+   }
+}

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/SimpleAddressManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/SimpleAddressManagerTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/SimpleAddressManagerTest.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,633 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.tests.unit.core.postoffice.impl;
+
+import org.easymock.EasyMock;
+import org.jboss.messaging.core.postoffice.AddressManager;
+import org.jboss.messaging.core.postoffice.impl.BindingImpl;
+import org.jboss.messaging.core.postoffice.impl.SimpleAddressManager;
+import org.jboss.messaging.core.server.Queue;
+import org.jboss.messaging.tests.unit.core.server.impl.fakes.FakeQueueFactory;
+import org.jboss.messaging.tests.util.UnitTestCase;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class SimpleAddressManagerTest extends UnitTestCase
+{
+   AddressManager sam;
+   FakeQueueFactory fqf = new FakeQueueFactory();
+
+   protected void setUp() throws Exception
+   {
+      sam = new SimpleAddressManager();
+   }
+
+   public void testAddDestinations()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      sam.addDestination(address);
+      sam.addDestination(address2);
+      sam.addDestination(address3);
+      sam.addDestination(address4);
+      sam.addDestination(address5);
+      assertTrue(sam.containsDestination(address));
+      assertTrue(sam.containsDestination(address2));
+      assertTrue(sam.containsDestination(address3));
+      assertTrue(sam.containsDestination(address4));
+      assertTrue(sam.containsDestination(address5));
+      assertEquals(sam.getDestinations().size(), 5);
+   }
+
+   public void testAddSameDestination()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add4");
+      sam.addDestination(address);
+      sam.addDestination(address2);
+      sam.addDestination(address3);
+      sam.addDestination(address4);
+      sam.addDestination(address5);
+      assertTrue(sam.containsDestination(address));
+      assertTrue(sam.containsDestination(address2));
+      assertTrue(sam.containsDestination(address3));
+      assertTrue(sam.containsDestination(address4));
+      assertTrue(sam.containsDestination(address5));
+      assertEquals(sam.getDestinations().size(), 4);
+   }
+
+   public void testRemoveDestinations()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      sam.addDestination(address);
+      sam.addDestination(address2);
+      sam.addDestination(address3);
+      sam.addDestination(address4);
+      sam.addDestination(address5);
+      assertTrue(sam.containsDestination(address));
+      assertTrue(sam.containsDestination(address2));
+      assertTrue(sam.containsDestination(address3));
+      assertTrue(sam.containsDestination(address4));
+      assertTrue(sam.containsDestination(address5));
+      assertEquals(sam.getDestinations().size(), 5);
+      sam.removeDestination(address2);
+      sam.removeDestination(address4);
+      assertTrue(sam.containsDestination(address));
+      assertFalse(sam.containsDestination(address2));
+      assertTrue(sam.containsDestination(address3));
+      assertFalse(sam.containsDestination(address4));
+      assertTrue(sam.containsDestination(address5));
+      assertEquals(sam.getDestinations().size(), 3);
+   }
+
+   public void testAddBinding()
+   {
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      EasyMock.replay(q, q2, q3, q4, q5);
+      BindingImpl b1 = new BindingImpl(address, q);
+      sam.addBinding(b1);
+      BindingImpl b2 = new BindingImpl(address2, q2);
+      sam.addBinding(b2);
+      BindingImpl b3 = new BindingImpl(address3, q3);
+      sam.addBinding(b3);
+      BindingImpl b4 = new BindingImpl(address4, q4);
+      sam.addBinding(b4);
+      BindingImpl b5 = new BindingImpl(address5, q5);
+      sam.addBinding(b5);
+      assertEquals(sam.getBinding(qName), b1);
+      assertEquals(sam.getBinding(qName2), b2);
+      assertEquals(sam.getBinding(qName3), b3);
+      assertEquals(sam.getBinding(qName4), b4);
+      assertEquals(sam.getBinding(qName5), b5);
+      assertEquals(sam.getBindings().size(), 5);
+      EasyMock.verify(q, q2, q3, q4, q5);
+   }
+
+   public void testRemoveBinding()
+   {
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      EasyMock.replay(q, q2, q3, q4, q5);
+      BindingImpl b1 = new BindingImpl(address, q);
+      sam.addBinding(b1);
+      BindingImpl b2 = new BindingImpl(address2, q2);
+      sam.addBinding(b2);
+      BindingImpl b3 = new BindingImpl(address3, q3);
+      sam.addBinding(b3);
+      BindingImpl b4 = new BindingImpl(address4, q4);
+      sam.addBinding(b4);
+      BindingImpl b5 = new BindingImpl(address5, q5);
+      sam.addBinding(b5);
+      assertEquals(sam.getBinding(qName), b1);
+      assertEquals(sam.getBinding(qName2), b2);
+      assertEquals(sam.getBinding(qName3), b3);
+      assertEquals(sam.getBinding(qName4), b4);
+      assertEquals(sam.getBinding(qName5), b5);
+      assertEquals(sam.getBindings().size(), 5);
+      sam.removeBinding(qName2);
+      sam.removeBinding(qName4);
+      assertEquals(sam.getBinding(qName), b1);
+      assertNull(sam.getBinding(qName2));
+      assertEquals(sam.getBinding(qName3), b3);
+      assertNull(sam.getBinding(qName4));
+      assertEquals(sam.getBinding(qName5), b5);
+      assertEquals(sam.getBindings().size(), 3);
+      EasyMock.verify(q, q2, q3, q4, q5);
+   }
+
+   public void testAddBindingAlreadyExists()
+   {
+      SimpleString qName = new SimpleString("q1");
+      SimpleString address = new SimpleString("add1");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      EasyMock.replay(q);
+      BindingImpl b1 = new BindingImpl(address, q);
+      sam.addBinding(b1);
+      try
+      {
+         sam.addBinding(b1);
+         fail("should throw IllegalStateException");
+      }
+      catch (IllegalStateException e)
+      {
+         //pass
+      }
+      assertEquals(sam.getBinding(qName), b1);
+      EasyMock.verify(q);
+   }
+
+   public void testAddMapping()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString qName = new SimpleString("q1");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      BindingImpl b1 = new BindingImpl(address, q);
+      EasyMock.replay(q);
+      sam.addMapping(address, b1);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 1);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      EasyMock.verify(q);
+   }
+
+   public void testRemoveMapping()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString qName = new SimpleString("q1");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      BindingImpl b1 = new BindingImpl(address, q);
+      EasyMock.replay(q);
+      sam.addMapping(address, b1);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 1);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      sam.removeMapping(address, qName);
+      assertNull(sam.getBindings(address));
+      assertNull(sam.getBindings(address));
+      EasyMock.verify(q);
+   }
+
+   public void testAddMultipleBindingsToMapping()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      BindingImpl b1 = new BindingImpl(address, q);
+      BindingImpl b2 = new BindingImpl(address, q2);
+      BindingImpl b3 = new BindingImpl(address, q3);
+      BindingImpl b4 = new BindingImpl(address, q4);
+      BindingImpl b5 = new BindingImpl(address, q5);
+      EasyMock.replay(q, q2, q3, q4, q5);
+      sam.addMapping(address, b1);
+      sam.addMapping(address, b2);
+      sam.addMapping(address, b3);
+      sam.addMapping(address, b4);
+      sam.addMapping(address, b5);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 5);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertEquals(sam.getBindings(address).get(1), b2);
+      assertEquals(sam.getBindings(address).get(2), b3);
+      assertEquals(sam.getBindings(address).get(3), b4);
+      assertEquals(sam.getBindings(address).get(4), b5);
+      EasyMock.verify(q, q2, q3, q4, q5);
+   }
+
+   public void testRemoveMultipleBindingsFromMapping()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      BindingImpl b1 = new BindingImpl(address, q);
+      BindingImpl b2 = new BindingImpl(address, q2);
+      BindingImpl b3 = new BindingImpl(address, q3);
+      BindingImpl b4 = new BindingImpl(address, q4);
+      BindingImpl b5 = new BindingImpl(address, q5);
+      EasyMock.replay(q, q2, q3, q4, q5);
+      sam.addMapping(address, b1);
+      sam.addMapping(address, b2);
+      sam.addMapping(address, b3);
+      sam.addMapping(address, b4);
+      sam.addMapping(address, b5);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 5);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertEquals(sam.getBindings(address).get(1), b2);
+      assertEquals(sam.getBindings(address).get(2), b3);
+      assertEquals(sam.getBindings(address).get(3), b4);
+      assertEquals(sam.getBindings(address).get(4), b5);
+      sam.removeMapping(address, qName2);
+      sam.removeMapping(address, qName4);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 3);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertEquals(sam.getBindings(address).get(1), b3);
+      assertEquals(sam.getBindings(address).get(2), b5);
+      EasyMock.verify(q, q2, q3, q4, q5);
+   }
+
+   public void testAddBindingsToMultipleMappings()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      BindingImpl b1 = new BindingImpl(address, q);
+      BindingImpl b2 = new BindingImpl(address2, q2);
+      BindingImpl b3 = new BindingImpl(address3, q3);
+      BindingImpl b4 = new BindingImpl(address4, q4);
+      BindingImpl b5 = new BindingImpl(address5, q5);
+      EasyMock.replay(q, q2, q3, q4, q5);
+      sam.addMapping(address, b1);
+      sam.addMapping(address2, b2);
+      sam.addMapping(address3, b3);
+      sam.addMapping(address4, b4);
+      sam.addMapping(address5, b5);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 1);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertNotNull(sam.getBindings(address2));
+      assertEquals(sam.getBindings(address2).size(), 1);
+      assertEquals(sam.getBindings(address2).get(0), b2);
+      assertNotNull(sam.getBindings(address3));
+      assertEquals(sam.getBindings(address3).size(), 1);
+      assertEquals(sam.getBindings(address3).get(0), b3);
+      assertNotNull(sam.getBindings(address4));
+      assertEquals(sam.getBindings(address4).size(), 1);
+      assertEquals(sam.getBindings(address4).get(0), b4);
+      assertNotNull(sam.getBindings(address5));
+      assertEquals(sam.getBindings(address5).size(), 1);
+      assertEquals(sam.getBindings(address5).get(0), b5);
+      EasyMock.verify(q, q2, q3, q4, q5);
+   }
+
+   public void testRemoveBindingsFromMultipleMappings()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      BindingImpl b1 = new BindingImpl(address, q);
+      BindingImpl b2 = new BindingImpl(address2, q2);
+      BindingImpl b3 = new BindingImpl(address3, q3);
+      BindingImpl b4 = new BindingImpl(address4, q4);
+      BindingImpl b5 = new BindingImpl(address5, q5);
+      EasyMock.replay(q, q2, q3, q4, q5);
+      sam.addMapping(address, b1);
+      sam.addMapping(address2, b2);
+      sam.addMapping(address3, b3);
+      sam.addMapping(address4, b4);
+      sam.addMapping(address5, b5);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 1);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertNotNull(sam.getBindings(address2));
+      assertEquals(sam.getBindings(address2).size(), 1);
+      assertEquals(sam.getBindings(address2).get(0), b2);
+      assertNotNull(sam.getBindings(address3));
+      assertEquals(sam.getBindings(address3).size(), 1);
+      assertEquals(sam.getBindings(address3).get(0), b3);
+      assertNotNull(sam.getBindings(address4));
+      assertEquals(sam.getBindings(address4).size(), 1);
+      assertEquals(sam.getBindings(address4).get(0), b4);
+      assertNotNull(sam.getBindings(address5));
+      assertEquals(sam.getBindings(address5).size(), 1);
+      assertEquals(sam.getBindings(address5).get(0), b5);
+      sam.removeMapping(address2, qName2);
+      sam.removeMapping(address4, qName4);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 1);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertNull(sam.getBindings(address2));
+      assertEquals(sam.getBindings(address3).size(), 1);
+      assertEquals(sam.getBindings(address3).get(0), b3);
+      assertNull(sam.getBindings(address4));
+      assertEquals(sam.getBindings(address5).size(), 1);
+      assertEquals(sam.getBindings(address5).get(0), b5);
+      EasyMock.verify(q, q2, q3, q4, q5);
+   }
+
+   public void testAddMultipleBindingsToMultipleMappings()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      SimpleString address6 = new SimpleString("add6");
+      SimpleString address7 = new SimpleString("add7");
+      SimpleString address8 = new SimpleString("add8");
+      SimpleString address9 = new SimpleString("add9");
+      SimpleString address10 = new SimpleString("add105");
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      SimpleString qName6 = new SimpleString("q6");
+      SimpleString qName7 = new SimpleString("q7");
+      SimpleString qName8 = new SimpleString("q8");
+      SimpleString qName9 = new SimpleString("q9");
+      SimpleString qName10 = new SimpleString("q10");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      Queue q6 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q6.getName()).andStubReturn(qName6);
+      Queue q7 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q7.getName()).andStubReturn(qName7);
+      Queue q8 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q8.getName()).andStubReturn(qName8);
+      Queue q9 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q9.getName()).andStubReturn(qName9);
+      Queue q10 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q10.getName()).andStubReturn(qName10);
+      BindingImpl b1 = new BindingImpl(address, q);
+      BindingImpl b2 = new BindingImpl(address2, q2);
+      BindingImpl b3 = new BindingImpl(address3, q3);
+      BindingImpl b4 = new BindingImpl(address4, q4);
+      BindingImpl b5 = new BindingImpl(address5, q5);
+      BindingImpl b6 = new BindingImpl(address6, q6);
+      BindingImpl b7 = new BindingImpl(address7, q7);
+      BindingImpl b8 = new BindingImpl(address8, q8);
+      BindingImpl b9 = new BindingImpl(address9, q9);
+      BindingImpl b10 = new BindingImpl(address10, q10);
+      EasyMock.replay(q);
+      sam.addMapping(address, b1);
+      sam.addMapping(address2, b2);
+      sam.addMapping(address, b3);
+      sam.addMapping(address2, b4);
+      sam.addMapping(address, b5);
+      sam.addMapping(address2, b6);
+      sam.addMapping(address, b7);
+      sam.addMapping(address2, b8);
+      sam.addMapping(address, b9);
+      sam.addMapping(address2, b10);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 5);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertEquals(sam.getBindings(address).get(1), b3);
+      assertEquals(sam.getBindings(address).get(2), b5);
+      assertEquals(sam.getBindings(address).get(3), b7);
+      assertEquals(sam.getBindings(address).get(4), b9);
+      assertNotNull(sam.getBindings(address2));
+      assertEquals(sam.getBindings(address2).size(), 5);
+      assertEquals(sam.getBindings(address2).get(0), b2);
+      assertEquals(sam.getBindings(address2).get(1), b4);
+      assertEquals(sam.getBindings(address2).get(2), b6);
+      assertEquals(sam.getBindings(address2).get(3), b8);
+      assertEquals(sam.getBindings(address2).get(4), b10);
+      EasyMock.verify(q);
+   }
+
+   public void testRemoveMultipleBindingsTFromMultipleMappings()
+   {
+      SimpleString address = new SimpleString("add1");
+      SimpleString address2 = new SimpleString("add2");
+      SimpleString address3 = new SimpleString("add3");
+      SimpleString address4 = new SimpleString("add4");
+      SimpleString address5 = new SimpleString("add5");
+      SimpleString address6 = new SimpleString("add6");
+      SimpleString address7 = new SimpleString("add7");
+      SimpleString address8 = new SimpleString("add8");
+      SimpleString address9 = new SimpleString("add9");
+      SimpleString address10 = new SimpleString("add105");
+      SimpleString qName = new SimpleString("q1");
+      SimpleString qName2 = new SimpleString("q2");
+      SimpleString qName3 = new SimpleString("q3");
+      SimpleString qName4 = new SimpleString("q4");
+      SimpleString qName5 = new SimpleString("q5");
+      SimpleString qName6 = new SimpleString("q6");
+      SimpleString qName7 = new SimpleString("q7");
+      SimpleString qName8 = new SimpleString("q8");
+      SimpleString qName9 = new SimpleString("q9");
+      SimpleString qName10 = new SimpleString("q10");
+      Queue q = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q.getName()).andStubReturn(qName);
+      Queue q2 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q2.getName()).andStubReturn(qName2);
+      Queue q3 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q3.getName()).andStubReturn(qName3);
+      Queue q4 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q4.getName()).andStubReturn(qName4);
+      Queue q5 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q5.getName()).andStubReturn(qName5);
+      Queue q6 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q6.getName()).andStubReturn(qName6);
+      Queue q7 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q7.getName()).andStubReturn(qName7);
+      Queue q8 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q8.getName()).andStubReturn(qName8);
+      Queue q9 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q9.getName()).andStubReturn(qName9);
+      Queue q10 = EasyMock.createStrictMock(Queue.class);
+      EasyMock.expect(q10.getName()).andStubReturn(qName10);
+      BindingImpl b1 = new BindingImpl(address, q);
+      BindingImpl b2 = new BindingImpl(address2, q2);
+      BindingImpl b3 = new BindingImpl(address3, q3);
+      BindingImpl b4 = new BindingImpl(address4, q4);
+      BindingImpl b5 = new BindingImpl(address5, q5);
+      BindingImpl b6 = new BindingImpl(address6, q6);
+      BindingImpl b7 = new BindingImpl(address7, q7);
+      BindingImpl b8 = new BindingImpl(address8, q8);
+      BindingImpl b9 = new BindingImpl(address9, q9);
+      BindingImpl b10 = new BindingImpl(address10, q10);
+      EasyMock.replay(q, q2, q3, q4, q5);
+      sam.addMapping(address, b1);
+      sam.addMapping(address2, b2);
+      sam.addMapping(address, b3);
+      sam.addMapping(address2, b4);
+      sam.addMapping(address, b5);
+      sam.addMapping(address2, b6);
+      sam.addMapping(address, b7);
+      sam.addMapping(address2, b8);
+      sam.addMapping(address, b9);
+      sam.addMapping(address2, b10);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 5);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertEquals(sam.getBindings(address).get(1), b3);
+      assertEquals(sam.getBindings(address).get(2), b5);
+      assertEquals(sam.getBindings(address).get(3), b7);
+      assertEquals(sam.getBindings(address).get(4), b9);
+      assertNotNull(sam.getBindings(address2));
+      assertEquals(sam.getBindings(address2).size(), 5);
+      assertEquals(sam.getBindings(address2).get(0), b2);
+      assertEquals(sam.getBindings(address2).get(1), b4);
+      assertEquals(sam.getBindings(address2).get(2), b6);
+      assertEquals(sam.getBindings(address2).get(3), b8);
+      assertEquals(sam.getBindings(address2).get(4), b10);
+
+      sam.removeMapping(address, qName3);
+      sam.removeMapping(address, qName5);
+      sam.removeMapping(address2, qName2);
+      sam.removeMapping(address2, qName4);
+      assertNotNull(sam.getBindings(address));
+      assertEquals(sam.getBindings(address).size(), 3);
+      assertEquals(sam.getBindings(address).get(0), b1);
+      assertEquals(sam.getBindings(address).get(1), b7);
+      assertEquals(sam.getBindings(address).get(2), b9);
+      assertNotNull(sam.getBindings(address2));
+      assertEquals(sam.getBindings(address2).size(), 3);
+      assertEquals(sam.getBindings(address2).get(0), b6);
+      assertEquals(sam.getBindings(address2).get(1), b8);
+      assertEquals(sam.getBindings(address2).get(2), b10);
+      EasyMock.verify(q, q2, q3, q4, q5);
+   }
+}

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/WildcardAddressManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/WildcardAddressManagerTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/WildcardAddressManagerTest.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.tests.unit.core.postoffice.impl;
+
+import org.jboss.messaging.core.postoffice.impl.WildcardAddressManager;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class WildcardAddressManagerTest extends SimpleAddressManagerTest
+{
+   protected void setUp() throws Exception
+   {
+      sam = new WildcardAddressManager();
+   }
+
+   public void testAddDestinations()
+   {
+      SimpleString address = new SimpleString("test.add1");
+      SimpleString address2 = new SimpleString("test.add2");
+      SimpleString address3 = new SimpleString("test.add3");
+      SimpleString address4 = new SimpleString("test.add4");
+      SimpleString address5 = new SimpleString("test.add5");
+      sam.addDestination(address);
+      sam.addDestination(address2);
+      sam.addDestination(address3);
+      sam.addDestination(address4);
+      sam.addDestination(address5);
+      assertTrue(sam.containsDestination(address));
+      assertTrue(sam.containsDestination(address2));
+      assertTrue(sam.containsDestination(address3));
+      assertTrue(sam.containsDestination(address4));
+      assertTrue(sam.containsDestination(address5));
+      assertTrue(sam.containsDestination(new SimpleString("test.*")));
+      assertTrue(sam.containsDestination(new SimpleString("*.*")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add1")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add2")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add3")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add4")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("test.#")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add1")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add2")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add3")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add4")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("#")));
+      assertEquals(sam.getDestinations().size(), 5);
+   }
+
+   public void testRemoveDestinations()
+   {
+      SimpleString address = new SimpleString("test.add1");
+      SimpleString address2 = new SimpleString("test2.add2");
+      SimpleString address3 = new SimpleString("test.add3");
+      SimpleString address4 = new SimpleString("test2.add4");
+      SimpleString address5 = new SimpleString("test.add5");
+      sam.addDestination(address);
+      sam.addDestination(address2);
+      sam.addDestination(address3);
+      sam.addDestination(address4);
+      sam.addDestination(address5);
+      assertTrue(sam.containsDestination(address));
+      assertTrue(sam.containsDestination(address2));
+      assertTrue(sam.containsDestination(address3));
+      assertTrue(sam.containsDestination(address4));
+      assertTrue(sam.containsDestination(address5));
+      assertTrue(sam.containsDestination(new SimpleString("test.*")));
+      assertTrue(sam.containsDestination(new SimpleString("test2.*")));
+      assertTrue(sam.containsDestination(new SimpleString("*.*")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add1")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add2")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add3")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add4")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("test.#")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add1")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add2")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add3")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add4")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("#")));
+      assertEquals(sam.getDestinations().size(), 5);
+
+      sam.removeDestination(address2);
+      sam.removeDestination(address4);
+
+      assertTrue(sam.containsDestination(address));
+      assertFalse(sam.containsDestination(address2));
+      assertTrue(sam.containsDestination(address3));
+      assertFalse(sam.containsDestination(address4));
+      assertTrue(sam.containsDestination(address5));
+      assertTrue(sam.containsDestination(new SimpleString("test.*")));
+      assertFalse(sam.containsDestination(new SimpleString("test2.*")));
+      assertTrue(sam.containsDestination(new SimpleString("*.*")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add1")));
+      assertFalse(sam.containsDestination(new SimpleString("*.add2")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add3")));
+      assertFalse(sam.containsDestination(new SimpleString("*.add4")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("*.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("test.#")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add1")));
+      assertFalse(sam.containsDestination(new SimpleString("#.add2")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add3")));
+      assertFalse(sam.containsDestination(new SimpleString("#.add4")));
+      assertTrue(sam.containsDestination(new SimpleString("#.add5")));
+      assertTrue(sam.containsDestination(new SimpleString("#")));
+      assertEquals(sam.getDestinations().size(), 3);
+   }
+}

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/util/SimpleStringTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/util/SimpleStringTest.java	2008-09-18 03:09:43 UTC (rev 4980)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/util/SimpleStringTest.java	2008-09-18 13:22:51 UTC (rev 4981)
@@ -22,9 +22,8 @@
 
 package org.jboss.messaging.tests.unit.util;
 
+import junit.framework.TestCase;
 import static org.jboss.messaging.tests.util.RandomUtil.randomString;
-import junit.framework.TestCase;
-
 import org.jboss.messaging.util.DataConstants;
 import org.jboss.messaging.util.SimpleString;
 
@@ -239,4 +238,74 @@
 	   assertEquals(DataConstants.SIZE_INT + str.getData().length, SimpleString.sizeofString(str));
       
    }
+
+   public void testSplitNoDelimeter() throws Exception
+   {
+      SimpleString s = new SimpleString("abcdefghi");
+      SimpleString[] strings = s.split('.');
+      assertNotNull(strings);
+      assertEquals(strings.length, 1);
+      assertEquals(strings[0], s);
+   }
+
+   public void testSplit1Delimeter() throws Exception
+   {
+      SimpleString s = new SimpleString("abcd.efghi");
+      SimpleString[] strings = s.split('.');
+      assertNotNull(strings);
+      assertEquals(strings.length, 2);
+      assertEquals(strings[0], new SimpleString("abcd"));
+      assertEquals(strings[1], new SimpleString("efghi"));
+   }
+   public void testSplitmanyDelimeters() throws Exception
+   {
+      SimpleString s = new SimpleString("abcd.efghi.jklmn.opqrs.tuvw.xyz");
+      SimpleString[] strings = s.split('.');
+      assertNotNull(strings);
+      assertEquals(strings.length, 6);
+      assertEquals(strings[0], new SimpleString("abcd"));
+      assertEquals(strings[1], new SimpleString("efghi"));
+      assertEquals(strings[2], new SimpleString("jklmn"));
+      assertEquals(strings[3], new SimpleString("opqrs"));
+      assertEquals(strings[4], new SimpleString("tuvw"));
+      assertEquals(strings[5], new SimpleString("xyz"));
+   }
+
+   public void testContains()
+   {
+      SimpleString simpleString = new SimpleString("abcdefghijklmnopqrst");
+      assertFalse(simpleString.contains('.'));
+      assertFalse(simpleString.contains('%'));
+      assertFalse(simpleString.contains('8'));
+      assertFalse(simpleString.contains('.'));
+      assertTrue(simpleString.contains('a'));
+      assertTrue(simpleString.contains('b'));
+      assertTrue(simpleString.contains('c'));
+      assertTrue(simpleString.contains('d'));
+      assertTrue(simpleString.contains('e'));
+      assertTrue(simpleString.contains('f'));
+      assertTrue(simpleString.contains('g'));
+      assertTrue(simpleString.contains('h'));
+      assertTrue(simpleString.contains('i'));
+      assertTrue(simpleString.contains('j'));
+      assertTrue(simpleString.contains('k'));
+      assertTrue(simpleString.contains('l'));
+      assertTrue(simpleString.contains('m'));
+      assertTrue(simpleString.contains('n'));
+      assertTrue(simpleString.contains('o'));
+      assertTrue(simpleString.contains('p'));
+      assertTrue(simpleString.contains('q'));
+      assertTrue(simpleString.contains('r'));
+      assertTrue(simpleString.contains('s'));
+      assertTrue(simpleString.contains('t'));
+   }
+
+   public void testConcat()
+   {
+      SimpleString start = new SimpleString("abcdefg");
+      SimpleString middle = new SimpleString("hijklmnop");
+      SimpleString end = new SimpleString("qrstuvwxyz");
+      assertEquals(start.concat(middle).concat(end), new SimpleString("abcdefghijklmnopqrstuvwxyz"));
+      assertEquals(start.concat('.').concat(end), new SimpleString("abcdefg.qrstuvwxyz"));
+   }
 }




More information about the jboss-cvs-commits mailing list