blob: 219cccd2799b52aaa1f842032d7c990b1bc33e72 [file] [log] [blame]
/*
*
* 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.url;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
public class URLHelper
{
public static final char DEFAULT_OPTION_SEPERATOR = '&';
public static final char ALTERNATIVE_OPTION_SEPARATOR = ',';
public static final char BROKER_SEPARATOR = ';';
private URLHelper()
{
}
public static void parseOptions(Map<String, String> optionMap, String options) throws URLSyntaxException
{
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(Map<String, String> options)
{
return printOptions(options, Collections.<String>emptySet());
}
public static String printOptions(Map<String, String> options, Set<String> optionNamesToMask)
{
if (options.isEmpty())
{
return "";
}
else
{
StringBuilder sb = new StringBuilder();
sb.append('?');
for (Map.Entry<String,String> entry : options.entrySet())
{
sb.append(entry.getKey());
sb.append("='");
if (optionNamesToMask.contains(entry.getKey()))
{
sb.append("********");
}
else
{
sb.append(entry.getValue());
}
sb.append("'");
sb.append(DEFAULT_OPTION_SEPERATOR);
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
}
}