You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ra...@apache.org on 2008/02/27 06:17:09 UTC
svn commit: r631489 - in
/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url:
AMQBindingURL.java BindingURL.java BindingURLParser.java
Author: rajith
Date: Tue Feb 26 21:17:07 2008
New Revision: 631489
URL: http://svn.apache.org/viewvc?rev=631489&view=rev
Log:
Added a new parser for the BindingURL.
This allows adding multiple binding keys, using # and * in the URLs.
This is tracked via QPID-814
Added:
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java
Modified:
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURL.java
Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java?rev=631489&r1=631488&r2=631489&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java Tue Feb 26 21:17:07 2008
@@ -20,28 +20,29 @@
*/
package org.apache.qpid.url;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-
public class AMQBindingURL implements BindingURL
{
private static final Logger _logger = LoggerFactory.getLogger(AMQBindingURL.class);
String _url;
- AMQShortString _exchangeClass;
- AMQShortString _exchangeName;
- AMQShortString _destinationName;
- AMQShortString _queueName;
+ AMQShortString _exchangeClass = ExchangeDefaults.DIRECT_EXCHANGE_CLASS;
+ AMQShortString _exchangeName = new AMQShortString("");
+ AMQShortString _destinationName = new AMQShortString("");;
+ AMQShortString _queueName = new AMQShortString("");
+ AMQShortString[] _bindingKeys = new AMQShortString[0];
private HashMap<String, String> _options;
- public AMQBindingURL(String url) throws URLSyntaxException
+ public AMQBindingURL(String url) throws URISyntaxException
{
// format:
// <exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']*
@@ -52,116 +53,35 @@
parseBindingURL();
}
- private void parseBindingURL() throws URLSyntaxException
+ private void parseBindingURL() throws URISyntaxException
{
- try
- {
- URI connection = new URI(_url);
-
- String exchangeClass = connection.getScheme();
-
- if (exchangeClass == null)
- {
- _url = ExchangeDefaults.DIRECT_EXCHANGE_CLASS + "://" + "" + "//" + _url;
- // URLHelper.parseError(-1, "Exchange Class not specified.", _url);
- parseBindingURL();
-
- return;
- }
- else
- {
- setExchangeClass(exchangeClass);
- }
-
- String exchangeName = connection.getHost();
-
- if (exchangeName == null)
- {
- if (getExchangeClass().equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
- {
- setExchangeName("");
- }
- else
- {
- throw URLHelper.parseError(-1, "Exchange Name not specified.", _url);
- }
- }
- else
- {
- setExchangeName(exchangeName);
- }
-
- String queueName;
-
- if ((connection.getPath() == null) || connection.getPath().equals(""))
- {
- throw URLHelper.parseError(_url.indexOf(_exchangeName.toString()) + _exchangeName.length(),
- "Destination or Queue requried", _url);
- }
- else
- {
- int slash = connection.getPath().indexOf("/", 1);
- if (slash == -1)
- {
- throw URLHelper.parseError(_url.indexOf(_exchangeName.toString()) + _exchangeName.length(),
- "Destination requried", _url);
- }
- else
- {
- String path = connection.getPath();
- setDestinationName(path.substring(1, slash));
-
- // We don't set queueName yet as the actual value we use depends on options set
- // when we are dealing with durable subscriptions
-
- queueName = path.substring(slash + 1);
-
- }
- }
-
- URLHelper.parseOptions(_options, connection.getQuery());
-
- processOptions();
-
- // We can now call setQueueName as the URL is full parsed.
-
- setQueueName(queueName);
-
- // Fragment is #string (not used)
- _logger.debug("URL Parsed: " + this);
-
- }
- catch (URISyntaxException uris)
- {
-
- throw URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput());
-
- }
+ BindingURLParser parser = new BindingURLParser(_url,this);
+ processOptions();
+ _logger.debug("URL Parsed: " + this);
}
- private void setExchangeClass(String exchangeClass)
+ public void setExchangeClass(String exchangeClass)
{
setExchangeClass(new AMQShortString(exchangeClass));
}
- private void setQueueName(String name) throws URLSyntaxException
+ public void setQueueName(String name)
{
setQueueName(new AMQShortString(name));
}
- private void setDestinationName(String name)
+ public void setDestinationName(String name)
{
setDestinationName(new AMQShortString(name));
}
- private void setExchangeName(String exchangeName)
+ public void setExchangeName(String exchangeName)
{
setExchangeName(new AMQShortString(exchangeName));
}
- private void processOptions()
+ private void processOptions() throws URISyntaxException
{
- // this is where we would parse any options that needed more than just storage.
}
public String getURL()
@@ -210,34 +130,9 @@
return _queueName;
}
- public void setQueueName(AMQShortString name) throws URLSyntaxException
+ public void setQueueName(AMQShortString name)
{
- if (_exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS))
- {
- if (Boolean.parseBoolean(getOption(OPTION_DURABLE)))
- {
- if (containsOption(BindingURL.OPTION_CLIENTID) && containsOption(BindingURL.OPTION_SUBSCRIPTION))
- {
- _queueName =
- new AMQShortString(getOption(BindingURL.OPTION_CLIENTID + ":" + BindingURL.OPTION_SUBSCRIPTION));
- }
- else
- {
- throw URLHelper.parseError(-1, "Durable subscription must have values for " + BindingURL.OPTION_CLIENTID
- + " and " + BindingURL.OPTION_SUBSCRIPTION + ".", _url);
-
- }
- }
- else
- {
- _queueName = null;
- }
- }
- else
- {
- _queueName = name;
- }
-
+ _queueName = name;
}
public String getOption(String key)
@@ -261,7 +156,7 @@
{
if (containsOption(BindingURL.OPTION_ROUTING_KEY))
{
- return new AMQShortString(getOption(OPTION_ROUTING_KEY));
+ return new AMQShortString((String)getOption(OPTION_ROUTING_KEY));
}
else
{
@@ -271,12 +166,29 @@
if (containsOption(BindingURL.OPTION_ROUTING_KEY))
{
- return new AMQShortString(getOption(OPTION_ROUTING_KEY));
+ return new AMQShortString((String)getOption(OPTION_ROUTING_KEY));
}
return getDestinationName();
}
+ public AMQShortString[] getBindingKeys()
+ {
+ if (_bindingKeys != null && _bindingKeys.length>0)
+ {
+ return _bindingKeys;
+ }
+ else
+ {
+ return new AMQShortString[]{getRoutingKey()};
+ }
+ }
+
+ public void setBindingKeys(AMQShortString[] keys)
+ {
+ _bindingKeys = keys;
+ }
+
public void setRoutingKey(AMQShortString key)
{
setOption(OPTION_ROUTING_KEY, key.toString());
@@ -296,6 +208,21 @@
sb.append(URLHelper.printOptions(_options));
- return sb.toString();
+ // temp hack
+ if (sb.toString().indexOf("?") == -1)
+ {
+ sb.append("?");
+ }
+ else
+ {
+ sb.append("&");
+ }
+
+ for (AMQShortString key :_bindingKeys)
+ {
+ sb.append("bindingKey='").append(key.toString()).append("'&");
+ }
+
+ return sb.toString().substring(0,sb.toString().length()-1);
}
}
Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURL.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURL.java?rev=631489&r1=631488&r2=631489&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURL.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURL.java Tue Feb 26 21:17:07 2008
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -34,6 +34,7 @@
public static final String OPTION_CLIENTID = "clientid";
public static final String OPTION_SUBSCRIPTION = "subscription";
public static final String OPTION_ROUTING_KEY = "routingkey";
+ public static final String OPTION_BINDING_KEY = "bindingKey";
String getURL();
@@ -51,6 +52,8 @@
boolean containsOption(String key);
AMQShortString getRoutingKey();
+
+ AMQShortString[] getBindingKeys();
String toString();
}
Added: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java?rev=631489&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java (added)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java Tue Feb 26 21:17:07 2008
@@ -0,0 +1,444 @@
+package org.apache.qpid.url;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BindingURLParser
+{
+ private static final char PROPERTY_EQUALS_CHAR = '=';
+ private static final char PROPERTY_SEPARATOR_CHAR = '&';
+ private static final char ALTERNATIVE_PROPERTY_SEPARATOR_CHAR = ',';
+ private static final char FORWARD_SLASH_CHAR = '/';
+ private static final char QUESTION_MARK_CHAR = '?';
+ private static final char SINGLE_QUOTE_CHAR = '\'';
+ private static final char COLON_CHAR = ':';
+ private static final char END_OF_URL_MARKER_CHAR = '%';
+
+ private static final Logger _logger = LoggerFactory.getLogger(BindingURLImpl.class);
+
+ private char[] _url;
+ private AMQBindingURL _bindingURL;
+ private BindingURLParserState _currentParserState;
+ private String _error;
+ private int _index = 0;
+ private String _currentPropName;
+ private Map<String,Object> _options = new HashMap<String,Object>();
+
+ //<exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']*
+ public BindingURLParser(String url,AMQBindingURL bindingURL) throws URISyntaxException
+ {
+ _url = (url + END_OF_URL_MARKER_CHAR).toCharArray();
+ _bindingURL = bindingURL;
+ _currentParserState = BindingURLParserState.BINDING_URL_START;
+ BindingURLParserState prevState = _currentParserState;
+
+ try
+ {
+ while (_currentParserState != BindingURLParserState.ERROR && _currentParserState != BindingURLParserState.BINDING_URL_END)
+ {
+ prevState = _currentParserState;
+ _currentParserState = next();
+ }
+
+ if (_currentParserState == BindingURLParserState.ERROR)
+ {
+ _error =
+ "Invalid URL format [current_state = " + prevState + ", details parsed so far " + _bindingURL + " ] error at (" + _index + ") due to " + _error;
+ _logger.debug(_error);
+ URISyntaxException ex;
+ ex = new URISyntaxException(markErrorLocation(),"Error occured while parsing URL",_index);
+ throw ex;
+ }
+
+ processOptions();
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ _error = "Invalid URL format [current_state = " + prevState + ", details parsed so far " + _bindingURL + " ] error at (" + _index + ")";
+ URISyntaxException ex = new URISyntaxException(markErrorLocation(),"Error occured while parsing URL",_index);
+ ex.initCause(e);
+ throw ex;
+ }
+ }
+
+ enum BindingURLParserState
+ {
+ BINDING_URL_START,
+ EXCHANGE_CLASS,
+ COLON_CHAR,
+ DOUBLE_SEP,
+ EXCHANGE_NAME,
+ EXCHANGE_SEPERATOR_CHAR,
+ DESTINATION,
+ DESTINATION_SEPERATOR_CHAR,
+ QUEUE_NAME,
+ QUESTION_MARK_CHAR,
+ PROPERTY_NAME,
+ PROPERTY_EQUALS,
+ START_PROPERTY_VALUE,
+ PROPERTY_VALUE,
+ END_PROPERTY_VALUE,
+ PROPERTY_SEPARATOR,
+ BINDING_URL_END,
+ ERROR
+ }
+
+ /**
+ * I am fully ware that there are few optimizations
+ * that can speed up things a wee bit. But I have opted
+ * for readability and maintainability at the expense of
+ * speed, as speed is not a critical factor here.
+ *
+ * One can understand the full parse logic by just looking at this method.
+ */
+ private BindingURLParserState next()
+ {
+ switch (_currentParserState)
+ {
+ case BINDING_URL_START:
+ return extractExchangeClass();
+ case COLON_CHAR:
+ _index++; //skip ":"
+ return BindingURLParserState.DOUBLE_SEP;
+ case DOUBLE_SEP:
+ _index = _index + 2; //skip "//"
+ return BindingURLParserState.EXCHANGE_NAME;
+ case EXCHANGE_NAME:
+ return extractExchangeName();
+ case EXCHANGE_SEPERATOR_CHAR:
+ _index++; // skip '/'
+ return BindingURLParserState.DESTINATION;
+ case DESTINATION:
+ return extractDestination();
+ case DESTINATION_SEPERATOR_CHAR:
+ _index++; // skip '/'
+ return BindingURLParserState.QUEUE_NAME;
+ case QUEUE_NAME:
+ return extractQueueName();
+ case QUESTION_MARK_CHAR:
+ _index++; // skip '?'
+ return BindingURLParserState.PROPERTY_NAME;
+ case PROPERTY_NAME:
+ return extractPropertyName();
+ case PROPERTY_EQUALS:
+ _index++; // skip the equal sign
+ return BindingURLParserState.START_PROPERTY_VALUE;
+ case START_PROPERTY_VALUE:
+ _index++; // skip the '\''
+ return BindingURLParserState.PROPERTY_VALUE;
+ case PROPERTY_VALUE:
+ return extractPropertyValue();
+ case END_PROPERTY_VALUE:
+ _index ++;
+ return checkEndOfURL();
+ case PROPERTY_SEPARATOR:
+ _index++; // skip '&'
+ return BindingURLParserState.PROPERTY_NAME;
+ default:
+ return BindingURLParserState.ERROR;
+ }
+ }
+
+ private BindingURLParserState extractExchangeClass()
+ {
+ char nextChar = _url[_index];
+
+ // check for the following special cases.
+ // "myQueue?durable='true'" or just "myQueue";
+
+ StringBuilder builder = new StringBuilder();
+ while (nextChar != COLON_CHAR && nextChar != QUESTION_MARK_CHAR && nextChar != END_OF_URL_MARKER_CHAR)
+ {
+ builder.append(nextChar);
+ _index++;
+ nextChar = _url[_index];
+ }
+
+ // normal use case
+ if (nextChar == COLON_CHAR)
+ {
+ _bindingURL.setExchangeClass(builder.toString());
+ return BindingURLParserState.COLON_CHAR;
+ }
+ // "myQueue?durable='true'" use case
+ else if (nextChar == QUESTION_MARK_CHAR)
+ {
+ _bindingURL.setExchangeClass(ExchangeDefaults.DIRECT_EXCHANGE_CLASS.asString());
+ _bindingURL.setExchangeName("");
+ _bindingURL.setQueueName(builder.toString());
+ return BindingURLParserState.QUESTION_MARK_CHAR;
+ }
+ else
+ {
+ _bindingURL.setExchangeClass(ExchangeDefaults.DIRECT_EXCHANGE_CLASS.asString());
+ _bindingURL.setExchangeName("");
+ _bindingURL.setQueueName(builder.toString());
+ return BindingURLParserState.BINDING_URL_END;
+ }
+ }
+
+ private BindingURLParserState extractExchangeName()
+ {
+ char nextChar = _url[_index];
+ StringBuilder builder = new StringBuilder();
+ while (nextChar != FORWARD_SLASH_CHAR)
+ {
+ builder.append(nextChar);
+ _index++;
+ nextChar = _url[_index];
+ }
+
+ _bindingURL.setExchangeName(builder.toString());
+ return BindingURLParserState.EXCHANGE_SEPERATOR_CHAR;
+ }
+
+ private BindingURLParserState extractDestination()
+ {
+ char nextChar = _url[_index];
+
+ //The destination is and queue name are both optional
+ // This is checking for the case where both are not specified.
+ if (nextChar == QUESTION_MARK_CHAR)
+ {
+ return BindingURLParserState.QUESTION_MARK_CHAR;
+ }
+
+ StringBuilder builder = new StringBuilder();
+ while (nextChar != FORWARD_SLASH_CHAR && nextChar != QUESTION_MARK_CHAR)
+ {
+ builder.append(nextChar);
+ _index++;
+ nextChar = _url[_index];
+ }
+
+ // This is the case where the destination is explictily stated.
+ // ex direct://amq.direct/myDest/myQueue?option1='1' ... OR
+ // direct://amq.direct//myQueue?option1='1' ...
+ if (nextChar == FORWARD_SLASH_CHAR)
+ {
+ _bindingURL.setDestinationName(builder.toString());
+ return BindingURLParserState.DESTINATION_SEPERATOR_CHAR;
+ }
+ // This is the case where destination is not explictly stated.
+ // ex direct://amq.direct/myQueue?option1='1' ...
+ else
+ {
+ _bindingURL.setQueueName(builder.toString());
+ return BindingURLParserState.QUESTION_MARK_CHAR;
+ }
+ }
+
+ private BindingURLParserState extractQueueName()
+ {
+ char nextChar = _url[_index];
+ StringBuilder builder = new StringBuilder();
+ while (nextChar != QUESTION_MARK_CHAR && nextChar != END_OF_URL_MARKER_CHAR)
+ {
+ builder.append(nextChar);
+ nextChar = _url[++_index];
+ }
+ _bindingURL.setQueueName(builder.toString());
+
+ if(nextChar == QUESTION_MARK_CHAR)
+ {
+ return BindingURLParserState.QUESTION_MARK_CHAR;
+ }
+ else
+ {
+ return BindingURLParserState.BINDING_URL_END;
+ }
+ }
+
+ private BindingURLParserState extractPropertyName()
+ {
+ StringBuilder builder = new StringBuilder();
+ char next = _url[_index];
+ while (next != PROPERTY_EQUALS_CHAR)
+ {
+ builder.append(next);
+ next = _url[++_index];
+ }
+ _currentPropName = builder.toString();
+
+ if (_currentPropName.trim().equals(""))
+ {
+ _error = "Property name cannot be empty";
+ return BindingURLParserState.ERROR;
+ }
+
+ return BindingURLParserState.PROPERTY_EQUALS;
+ }
+
+ private BindingURLParserState extractPropertyValue()
+ {
+ StringBuilder builder = new StringBuilder();
+ char next = _url[_index];
+ while (next != SINGLE_QUOTE_CHAR)
+ {
+ builder.append(next);
+ next = _url[++_index];
+ }
+ String propValue = builder.toString();
+
+ if (propValue.trim().equals(""))
+ {
+ _error = "Property values cannot be empty";
+ return BindingURLParserState.ERROR;
+ }
+ else
+ {
+ if (_options.containsKey(_currentPropName))
+ {
+ Object obj = _options.get(_currentPropName);
+ if (obj instanceof List)
+ {
+ List list = (List)obj;
+ list.add(propValue);
+ }
+ else // it has to be a string
+ {
+ List<String> list = new ArrayList();
+ list.add((String)obj);
+ list.add(propValue);
+ _options.put(_currentPropName, list);
+ }
+ }
+ else
+ {
+ _options.put(_currentPropName, propValue);
+ }
+
+
+ return BindingURLParserState.END_PROPERTY_VALUE;
+ }
+ }
+
+ private BindingURLParserState checkEndOfURL()
+ {
+ char nextChar = _url[_index];
+ if ( nextChar == END_OF_URL_MARKER_CHAR)
+ {
+ return BindingURLParserState.BINDING_URL_END;
+ }
+ else if (nextChar == PROPERTY_SEPARATOR_CHAR || nextChar == ALTERNATIVE_PROPERTY_SEPARATOR_CHAR)
+ {
+ return BindingURLParserState.PROPERTY_SEPARATOR;
+ }
+ else
+ {
+ return BindingURLParserState.ERROR;
+ }
+ }
+
+ private String markErrorLocation()
+ {
+ String tmp = String.valueOf(_url);
+ // length -1 to remove ENDOF URL marker
+ return tmp.substring(0,_index) + "^" + tmp.substring(_index+1> tmp.length()-1?tmp.length()-1:_index+1,tmp.length()-1);
+ }
+
+ private void processOptions() throws URISyntaxException
+ {
+// check for bindingKey
+ if (_options.containsKey(BindingURL.OPTION_BINDING_KEY) && _options.get(BindingURL.OPTION_BINDING_KEY) != null)
+ {
+ Object obj = _options.get(BindingURL.OPTION_BINDING_KEY);
+
+ if (obj instanceof String)
+ {
+ AMQShortString[] bindingKeys = new AMQShortString[]{new AMQShortString((String)obj)};
+ _bindingURL.setBindingKeys(bindingKeys);
+ }
+ else // it would be a list
+ {
+ List list = (List)obj;
+ AMQShortString[] bindingKeys = new AMQShortString[list.size()];
+ int i=0;
+ for (Iterator it = list.iterator(); it.hasNext();)
+ {
+ bindingKeys[i] = new AMQShortString((String)it.next());
+ i++;
+ }
+ _bindingURL.setBindingKeys(bindingKeys);
+ }
+
+ }
+ for (String key: _options.keySet())
+ {
+ // We want to skip the bindingKey list
+ if (_options.get(key) instanceof String)
+ {
+ _bindingURL.setOption(key, (String)_options.get(key));
+ }
+ }
+
+
+ // check if both a binding key and a routing key is specified.
+ if (_options.containsKey(BindingURL.OPTION_BINDING_KEY) && _options.containsKey(BindingURL.OPTION_ROUTING_KEY))
+ {
+ throw new URISyntaxException(String.valueOf(_url),"It is illegal to specify both a routingKey and a bindingKey in the same URL",-1);
+ }
+
+ // check for durable subscriptions
+ if (_bindingURL.getExchangeClass().equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS))
+ {
+ String queueName = null;
+ if (Boolean.parseBoolean(_bindingURL.getOption(BindingURL.OPTION_DURABLE)))
+ {
+ if (_bindingURL.containsOption(BindingURL.OPTION_CLIENTID) && _bindingURL.containsOption(BindingURL.OPTION_SUBSCRIPTION))
+ {
+ queueName = _bindingURL.getOption(BindingURL.OPTION_CLIENTID + ":" + BindingURL.OPTION_SUBSCRIPTION);
+ }
+ else
+ {
+ throw new URISyntaxException(String.valueOf(_url),"Durable subscription must have values for " + BindingURL.OPTION_CLIENTID
+ + " and " + BindingURL.OPTION_SUBSCRIPTION , -1);
+
+ }
+ }
+ _bindingURL.setQueueName(queueName);
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ String[] urls = new String[]
+ {
+ "topic://amq.topic//myTopic?routingkey='stocks.#'",
+ "topic://amq.topic/message_queue?bindingKey='usa.*'&bindingKey='control',exclusive='true'",
+ "topic://amq.topic//?bindingKey='usa.*',bindingKey='control',exclusive='true'",
+ "direct://amq.direct/dummyDest/myQueue?routingKey='abc.*'",
+ "exchange.Class://exchangeName/Destination/Queue",
+ "exchangeClass://exchangeName/Destination/?option='value',option2='value2'",
+ "IBMPerfQueue1?durable='true'",
+ "exchangeClass://exchangeName/Destination/?bindingKey='key1',bindingKey='key2'"
+ };
+
+ try
+ {
+ for (String url: urls)
+ {
+ System.out.println("URL " + url);
+ AMQBindingURL bindingURL = new AMQBindingURL(url);
+ BindingURLParser parser = new BindingURLParser(url,bindingURL);
+ System.out.println("\nX " + bindingURL.toString() + " \n");
+
+ }
+
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+}