| /* |
| * |
| * 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.qpid.client.url; |
| |
| |
| import org.apache.qpid.client.BrokerDetails; |
| import org.apache.qpid.client.AMQConnectionFactory; |
| import org.apache.qpid.client.AMQConnectionURL; |
| import org.apache.qpid.url.URLHelper; |
| import org.apache.qpid.url.URLSyntaxException; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.StringTokenizer; |
| |
| public class URLParser |
| { |
| private AMQConnectionURL _url; |
| |
| public URLParser(AMQConnectionURL url)throws URLSyntaxException |
| { |
| _url = url; |
| parseURL(_url.getURL()); |
| } |
| |
| private void parseURL(String fullURL) throws URLSyntaxException |
| { |
| // Connection URL format |
| // amqp://[user:pass@][clientid]/[virtualhost]?brokerlist='tcp://host:port?option=\'value\',option=\'value\';tcp://host:port?option=\'value\'',failover='method?option=\'value\',option='value''" |
| // Options are of course optional except for requiring a single broker in the broker list. |
| try |
| { |
| URI connection = new URI(fullURL); |
| |
| if ((connection.getScheme() == null) || !(connection.getScheme().equalsIgnoreCase(AMQConnectionURL.AMQ_PROTOCOL))) |
| { |
| throw new URISyntaxException(fullURL, "Not an AMQP URL"); |
| } |
| |
| if ((connection.getHost() == null) || connection.getHost().equals("")) |
| { |
| String tmp = connection.getAuthority(); |
| // hack to read a clientid such as "my_clientID" |
| if (tmp != null && tmp.indexOf('@') < tmp.length()-1) |
| { |
| _url.setClientName(tmp.substring(tmp.indexOf('@')+1,tmp.length())); |
| } |
| else |
| { |
| String uid = AMQConnectionFactory.getUniqueClientID(); |
| if (uid == null) |
| { |
| throw URLHelper.parseError(-1, "Client Name not specified", fullURL); |
| } |
| else |
| { |
| _url.setClientName(uid); |
| } |
| } |
| |
| } |
| else |
| { |
| _url.setClientName(connection.getHost()); |
| } |
| |
| String userInfo = connection.getUserInfo(); |
| |
| if (userInfo == null) |
| { |
| // Fix for Java 1.5 which doesn't parse UserInfo for non http URIs |
| userInfo = connection.getAuthority(); |
| |
| if (userInfo != null) |
| { |
| int atIndex = userInfo.indexOf('@'); |
| |
| if (atIndex != -1) |
| { |
| userInfo = userInfo.substring(0, atIndex); |
| } |
| else |
| { |
| userInfo = null; |
| } |
| } |
| |
| } |
| |
| if (userInfo != null) |
| { |
| parseUserInfo(userInfo); |
| } |
| |
| String virtualHost = connection.getPath(); |
| |
| if ((virtualHost != null) && (!virtualHost.equals(""))) |
| { |
| _url.setVirtualHost(virtualHost); |
| } |
| else |
| { |
| int authLength = connection.getAuthority().length(); |
| int start = AMQConnectionURL.AMQ_PROTOCOL.length() + 3; |
| int testIndex = start + authLength; |
| if ((testIndex < fullURL.length()) && (fullURL.charAt(testIndex) == '?')) |
| { |
| throw URLHelper.parseError(start, testIndex - start, "Virtual host found", fullURL); |
| } |
| else |
| { |
| throw URLHelper.parseError(-1, "Virtual host not specified", fullURL); |
| } |
| |
| } |
| |
| URLHelper.parseOptions(_url.getOptions(), connection.getQuery()); |
| |
| processOptions(); |
| } |
| catch (URISyntaxException uris) |
| { |
| if (uris instanceof URLSyntaxException) |
| { |
| throw (URLSyntaxException) uris; |
| } |
| |
| int slash = fullURL.indexOf("\\"); |
| |
| if (slash == -1) |
| { |
| throw URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput()); |
| } |
| else |
| { |
| if ((slash != 0) && (fullURL.charAt(slash - 1) == ':')) |
| { |
| throw URLHelper.parseError(slash - 2, fullURL.indexOf('?') - slash + 2, |
| "Virtual host looks like a windows path, forward slash not allowed in URL", fullURL); |
| } |
| else |
| { |
| throw URLHelper.parseError(slash, "Forward slash not allowed in URL", fullURL); |
| } |
| } |
| |
| } |
| } |
| |
| private void parseUserInfo(String userinfo) throws URLSyntaxException |
| { |
| // user info = user:pass |
| |
| int colonIndex = userinfo.indexOf(':'); |
| |
| if (colonIndex == -1) |
| { |
| throw URLHelper.parseError(AMQConnectionURL.AMQ_PROTOCOL.length() + 3, userinfo.length(), |
| "Null password in user information not allowed.", _url.getURL()); |
| } |
| else |
| { |
| _url.setUsername(userinfo.substring(0, colonIndex)); |
| _url.setPassword(userinfo.substring(colonIndex + 1)); |
| } |
| |
| } |
| |
| private void processOptions() throws URLSyntaxException |
| { |
| if (_url.getOptions().containsKey(AMQConnectionURL.OPTIONS_BROKERLIST)) |
| { |
| String brokerlist = _url.getOptions().get(AMQConnectionURL.OPTIONS_BROKERLIST); |
| |
| // brokerlist tcp://host:port?option='value',option='value';tcp://host:port/virtualpath?option='value' |
| StringTokenizer st = new StringTokenizer(brokerlist, "" + URLHelper.BROKER_SEPARATOR); |
| |
| while (st.hasMoreTokens()) |
| { |
| String broker = st.nextToken(); |
| |
| final BrokerDetails brokerDetails = new BrokerDetails(broker); |
| brokerDetails.setConnectionUrl(_url); |
| _url.addBrokerDetails(brokerDetails); |
| } |
| |
| _url.getOptions().remove(AMQConnectionURL.OPTIONS_BROKERLIST); |
| } |
| |
| if (_url.getOptions().containsKey(AMQConnectionURL.OPTIONS_FAILOVER)) |
| { |
| String failover = _url.getOptions().get(AMQConnectionURL.OPTIONS_FAILOVER); |
| |
| // failover='method?option='value',option='value'' |
| |
| int methodIndex = failover.indexOf('?'); |
| |
| if (methodIndex > -1) |
| { |
| _url.setFailoverMethod(failover.substring(0, methodIndex)); |
| URLHelper.parseOptions(_url.getFailoverOptions(), failover.substring(methodIndex + 1)); |
| } |
| else |
| { |
| _url.setFailoverMethod(failover); |
| } |
| |
| _url.getOptions().remove(AMQConnectionURL.OPTIONS_FAILOVER); |
| } |
| |
| if (_url.getOptions().containsKey(AMQConnectionURL.OPTIONS_DEFAULT_TOPIC_EXCHANGE)) |
| { |
| _url.setDefaultTopicExchangeName(_url.getOptions().get(AMQConnectionURL.OPTIONS_DEFAULT_TOPIC_EXCHANGE)); |
| } |
| |
| if (_url.getOptions().containsKey(AMQConnectionURL.OPTIONS_DEFAULT_QUEUE_EXCHANGE)) |
| { |
| _url.setDefaultQueueExchangeName(_url.getOptions().get(AMQConnectionURL.OPTIONS_DEFAULT_QUEUE_EXCHANGE)); |
| } |
| |
| if (_url.getOptions().containsKey(AMQConnectionURL.OPTIONS_TEMPORARY_QUEUE_EXCHANGE)) |
| { |
| _url.setTemporaryQueueExchangeName(_url.getOptions().get(AMQConnectionURL.OPTIONS_TEMPORARY_QUEUE_EXCHANGE)); |
| } |
| |
| if (_url.getOptions().containsKey(AMQConnectionURL.OPTIONS_TEMPORARY_TOPIC_EXCHANGE)) |
| { |
| _url.setTemporaryTopicExchangeName(_url.getOptions().get(AMQConnectionURL.OPTIONS_TEMPORARY_TOPIC_EXCHANGE)); |
| } |
| } |
| |
| } |