diff options
Diffstat (limited to 'M4-RCs/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java')
-rw-r--r-- | M4-RCs/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java | 466 |
1 files changed, 0 insertions, 466 deletions
diff --git a/M4-RCs/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java b/M4-RCs/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java deleted file mode 100644 index f73ae9c232..0000000000 --- a/M4-RCs/qpid/java/common/src/main/java/org/apache/qpid/url/BindingURLParser.java +++ /dev/null @@ -1,466 +0,0 @@ -package org.apache.qpid.url; -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * 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 - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - - -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(BindingURLParser.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'", - "exchangeClass://exchangeName/Destination/?bindingkey='key1'&routingkey='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(); - } - } - -} |