001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.url;
022
023 import java.util.HashMap;
024 import java.util.Map;
025
026 public class URLHelper
027 {
028 public static char DEFAULT_OPTION_SEPERATOR = '&';
029 public static char ALTERNATIVE_OPTION_SEPARATOR = ',';
030 public static char BROKER_SEPARATOR = ';';
031
032 public static void parseOptions(Map<String, String> optionMap, String options) throws URLSyntaxException
033 {
034 // options looks like this
035 // brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value''
036
037 if ((options == null) || (options.indexOf('=') == -1))
038 {
039 return;
040 }
041
042 int optionIndex = options.indexOf('=');
043
044 String option = options.substring(0, optionIndex);
045
046 int length = options.length();
047
048 int nestedQuotes = 0;
049
050 // to store index of final "'"
051 int valueIndex = optionIndex;
052
053 // Walk remainder of url.
054 while ((nestedQuotes > 0) || (valueIndex < length))
055 {
056 valueIndex++;
057
058 if (valueIndex >= length)
059 {
060 break;
061 }
062
063 if (options.charAt(valueIndex) == '\'')
064 {
065 if ((valueIndex + 1) < options.length())
066 {
067 if ((options.charAt(valueIndex + 1) == DEFAULT_OPTION_SEPERATOR)
068 || (options.charAt(valueIndex + 1) == ALTERNATIVE_OPTION_SEPARATOR)
069 || (options.charAt(valueIndex + 1) == BROKER_SEPARATOR)
070 || (options.charAt(valueIndex + 1) == '\''))
071 {
072 nestedQuotes--;
073
074 if (nestedQuotes == 0)
075 {
076 // We've found the value of an option
077 break;
078 }
079 }
080 else
081 {
082 nestedQuotes++;
083 }
084 }
085 else
086 {
087 // We are at the end of the string
088 // Check to see if we are corectly closing quotes
089 if (options.charAt(valueIndex) == '\'')
090 {
091 nestedQuotes--;
092 }
093
094 break;
095 }
096 }
097 }
098
099 if ((nestedQuotes != 0) || (valueIndex < (optionIndex + 2)))
100 {
101 int sepIndex = 0;
102
103 // Try and identify illegal separator character
104 if (nestedQuotes > 1)
105 {
106 for (int i = 0; i < nestedQuotes; i++)
107 {
108 sepIndex = options.indexOf('\'', sepIndex);
109 sepIndex++;
110 }
111 }
112
113 if ((sepIndex >= options.length()) || (sepIndex == 0))
114 {
115 throw parseError(valueIndex, "Unterminated option", options);
116 }
117 else
118 {
119 throw parseError(sepIndex, "Unterminated option. Possible illegal option separator:'"
120 + options.charAt(sepIndex) + "'", options);
121 }
122 }
123
124 // optionIndex +2 to skip "='"
125 String value = options.substring(optionIndex + 2, valueIndex);
126
127 optionMap.put(option, value);
128
129 if (valueIndex < (options.length() - 1))
130 {
131 // Recurse to get remaining options
132 parseOptions(optionMap, options.substring(valueIndex + 2));
133 }
134 }
135
136 public static URLSyntaxException parseError(int index, String error, String url)
137 {
138 return parseError(index, 1, error, url);
139 }
140
141 public static URLSyntaxException parseError(int index, int length, String error, String url)
142 {
143 return new URLSyntaxException(url, error, index, length);
144 }
145
146 public static String printOptions(Map<String, String> options)
147 {
148 if (options.isEmpty())
149 {
150 return "";
151 }
152 else
153 {
154 StringBuffer sb = new StringBuffer();
155 sb.append('?');
156 for (String key : options.keySet())
157 {
158 sb.append(key);
159
160 sb.append("='");
161
162 sb.append(options.get(key));
163
164 sb.append("'");
165 sb.append(DEFAULT_OPTION_SEPERATOR);
166 }
167
168 sb.deleteCharAt(sb.length() - 1);
169
170 return sb.toString();
171 }
172 }
173 }
|