diff options
| author | Arnaud Simon <arnaudsimon@apache.org> | 2007-08-06 10:32:50 +0000 |
|---|---|---|
| committer | Arnaud Simon <arnaudsimon@apache.org> | 2007-08-06 10:32:50 +0000 |
| commit | 999b19703dca14e7209230e07ea145ee084e528f (patch) | |
| tree | 35ebea9194398d37a606f8a9b238df2658c66725 /qpid/java/common/src | |
| parent | 27ed31a51bae606bf4d32d75770bbb8c3ff75687 (diff) | |
| download | qpid-python-999b19703dca14e7209230e07ea145ee084e528f.tar.gz | |
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@563097 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/common/src')
4 files changed, 577 insertions, 0 deletions
diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/url/AMQBindingURL.java b/qpid/java/common/src/main/java/org/apache/qpidity/url/AMQBindingURL.java new file mode 100644 index 0000000000..0edf9ac21b --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpidity/url/AMQBindingURL.java @@ -0,0 +1,261 @@ +/* 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. + */ +package org.apache.qpidity.url; + +import org.apache.qpidity.exchange.ExchangeDefaults; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; + +import java.util.HashMap; +import java.net.URI; +import java.net.URISyntaxException; + +public class AMQBindingURL implements BindingURL +{ + private static final Logger _logger = LoggerFactory.getLogger(AMQBindingURL.class); + + String _url; + String _exchangeClass; + String _exchangeName; + String _destinationName; + String _queueName; + private HashMap<String, String> _options; + + public AMQBindingURL(String url) throws URLSyntaxException + { + // format: + // <exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']* + if (_logger.isDebugEnabled()) + { + _logger.debug("Parsing URL: " + url); + } + _url = url; + _options = new HashMap<String, String>(); + parseBindingURL(); + } + + private void parseBindingURL() throws URLSyntaxException + { + 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) + _exchangeName.length(), + "Destination or Queue requried", _url); + } + else + { + int slash = connection.getPath().indexOf("/", 1); + if (slash == -1) + { + throw URLHelper.parseError(_url.indexOf(_exchangeName) + _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) + if (_logger.isDebugEnabled()) + { + _logger.debug("URL Parsed: " + this); + } + } + catch (URISyntaxException uris) + { + throw URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput()); + } + } + + + private void processOptions() + { + // this is where we would parse any options that needed more than just storage. + } + + public String getURL() + { + return _url; + } + + public String getExchangeClass() + { + return _exchangeClass; + } + + private void setExchangeClass(String exchangeClass) + { + + _exchangeClass = exchangeClass; + if (exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS)) + { + setOption(BindingURL.OPTION_EXCLUSIVE, "true"); + } + + } + + public String getExchangeName() + { + return _exchangeName; + } + + private void setExchangeName(String name) + { + _exchangeName = name; + } + + public String getDestinationName() + { + return _destinationName; + } + + private void setDestinationName(String name) + { + _destinationName = name; + } + + public String getQueueName() + { + return _queueName; + } + + public void setQueueName(String name) throws URLSyntaxException + { + if (_exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS)) + { + if (Boolean.parseBoolean(getOption(OPTION_DURABLE))) + { + if (containsOption(BindingURL.OPTION_CLIENTID) && containsOption(BindingURL.OPTION_SUBSCRIPTION)) + { + _queueName = 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; + } + + } + + public String getOption(String key) + { + return _options.get(key); + } + + public void setOption(String key, String value) + { + _options.put(key, value); + } + + public boolean containsOption(String key) + { + return _options.containsKey(key); + } + + public String getRoutingKey() + { + if (_exchangeClass.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS)) + { + return getQueueName(); + } + + if (containsOption(BindingURL.OPTION_ROUTING_KEY)) + { + return getOption(OPTION_ROUTING_KEY); + } + + return getDestinationName(); + } + + public void setRoutingKey(String key) + { + setOption(OPTION_ROUTING_KEY, key); + } + + public String toString() + { + StringBuffer sb = new StringBuffer(); + + sb.append(_exchangeClass); + sb.append("://"); + sb.append(_exchangeName); + sb.append('/'); + sb.append(_destinationName); + sb.append('/'); + sb.append(_queueName); + + sb.append(URLHelper.printOptions(_options)); + + return sb.toString(); + } +} diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/url/BindingURL.java b/qpid/java/common/src/main/java/org/apache/qpidity/url/BindingURL.java new file mode 100644 index 0000000000..a795b05b22 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpidity/url/BindingURL.java @@ -0,0 +1,53 @@ +/* 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. + */ +package org.apache.qpidity.url; + +import org.apache.qpid.framing.AMQShortString; + +/* + Binding URL format: + <exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']* +*/ +public interface BindingURL +{ + public static final String OPTION_EXCLUSIVE = "exclusive"; + public static final String OPTION_AUTODELETE = "autodelete"; + public static final String OPTION_DURABLE = "durable"; + public static final String OPTION_CLIENTID = "clientid"; + public static final String OPTION_SUBSCRIPTION = "subscription"; + public static final String OPTION_ROUTING_KEY = "routingkey"; + + + String getURL(); + + String getExchangeClass(); + + String getExchangeName(); + + String getDestinationName(); + + String getQueueName(); + + String getOption(String key); + + boolean containsOption(String key); + + String getRoutingKey(); + + String toString(); +} diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/url/URLHelper.java b/qpid/java/common/src/main/java/org/apache/qpidity/url/URLHelper.java new file mode 100644 index 0000000000..eba1b0bbeb --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpidity/url/URLHelper.java @@ -0,0 +1,169 @@ +/* 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. + */ +package org.apache.qpidity.url; + +import java.util.HashMap; + +public class URLHelper +{ + public static char DEFAULT_OPTION_SEPERATOR = '&'; + public static char ALTERNATIVE_OPTION_SEPARATOR = ','; + public static char BROKER_SEPARATOR = ';'; + + public static void parseOptions(HashMap<String, String> optionMap, String options) throws URLSyntaxException + { + // options looks like this + // brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value'' + + if ((options == null) || (options.indexOf('=') == -1)) + { + return; + } + + int optionIndex = options.indexOf('='); + + String option = options.substring(0, optionIndex); + + int length = options.length(); + + int nestedQuotes = 0; + + // to store index of final "'" + int valueIndex = optionIndex; + + // Walk remainder of url. + while ((nestedQuotes > 0) || (valueIndex < length)) + { + valueIndex++; + + if (valueIndex >= length) + { + break; + } + + if (options.charAt(valueIndex) == '\'') + { + if ((valueIndex + 1) < options.length()) + { + if ((options.charAt(valueIndex + 1) == DEFAULT_OPTION_SEPERATOR) + || (options.charAt(valueIndex + 1) == ALTERNATIVE_OPTION_SEPARATOR) + || (options.charAt(valueIndex + 1) == BROKER_SEPARATOR) + || (options.charAt(valueIndex + 1) == '\'')) + { + nestedQuotes--; + + if (nestedQuotes == 0) + { + // We've found the value of an option + break; + } + } + else + { + nestedQuotes++; + } + } + else + { + // We are at the end of the string + // Check to see if we are corectly closing quotes + if (options.charAt(valueIndex) == '\'') + { + nestedQuotes--; + } + + break; + } + } + } + + if ((nestedQuotes != 0) || (valueIndex < (optionIndex + 2))) + { + int sepIndex = 0; + + // Try and identify illegal separator character + if (nestedQuotes > 1) + { + for (int i = 0; i < nestedQuotes; i++) + { + sepIndex = options.indexOf('\'', sepIndex); + sepIndex++; + } + } + + if ((sepIndex >= options.length()) || (sepIndex == 0)) + { + throw parseError(valueIndex, "Unterminated option", options); + } + else + { + throw parseError(sepIndex, "Unterminated option. Possible illegal option separator:'" + + options.charAt(sepIndex) + "'", options); + } + } + + // optionIndex +2 to skip "='" + String value = options.substring(optionIndex + 2, valueIndex); + + optionMap.put(option, value); + + if (valueIndex < (options.length() - 1)) + { + // Recurse to get remaining options + parseOptions(optionMap, options.substring(valueIndex + 2)); + } + } + + public static URLSyntaxException parseError(int index, String error, String url) + { + return parseError(index, 1, error, url); + } + + public static URLSyntaxException parseError(int index, int length, String error, String url) + { + return new URLSyntaxException(url, error, index, length); + } + + public static String printOptions(HashMap<String, String> options) + { + if (options.isEmpty()) + { + return ""; + } + else + { + StringBuffer sb = new StringBuffer(); + sb.append('?'); + for (String key : options.keySet()) + { + sb.append(key); + + sb.append("='"); + + sb.append(options.get(key)); + + sb.append("'"); + sb.append(DEFAULT_OPTION_SEPERATOR); + } + + sb.deleteCharAt(sb.length() - 1); + + return sb.toString(); + } + } +} diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/url/URLSyntaxException.java b/qpid/java/common/src/main/java/org/apache/qpidity/url/URLSyntaxException.java new file mode 100644 index 0000000000..bc65b70d14 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpidity/url/URLSyntaxException.java @@ -0,0 +1,94 @@ +/* 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. + */ +package org.apache.qpidity.url; + +import java.net.URISyntaxException; + +public class URLSyntaxException extends URISyntaxException +{ + private int _length; + + public URLSyntaxException(String url, String error, int index, int length) + { + super(url, error, index); + + _length = length; + } + + private static String getPositionString(int index, int length) + { + StringBuffer sb = new StringBuffer(index + 1); + + for (int i = 0; i < index; i++) + { + sb.append(" "); + } + + if (length > -1) + { + for (int i = 0; i < length; i++) + { + sb.append('^'); + } + } + + return sb.toString(); + } + + + public String toString() + { + StringBuffer sb = new StringBuffer(); + + sb.append(getReason()); + + if (getIndex() > -1) + { + if (_length != -1) + { + sb.append(" between indicies "); + sb.append(getIndex()); + sb.append(" and "); + sb.append(_length); + } + else + { + sb.append(" at index "); + sb.append(getIndex()); + } + } + + sb.append(" "); + if (getIndex() != -1) + { + sb.append("\n"); + } + + sb.append(getInput()); + + if (getIndex() != -1) + { + sb.append("\n"); + sb.append(getPositionString(getIndex(), _length)); + } + + return sb.toString(); + } + + +} |
