You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2012/07/13 22:10:34 UTC

svn commit: r1361369 - in /activemq/activemq-dotnet/Apache.NMS/branches/1.5.x: ./ nant.build src/main/csharp/Util/URISupport.cs src/test/csharp/URISupportTest.cs

Author: tabish
Date: Fri Jul 13 20:10:33 2012
New Revision: 1361369

URL: http://svn.apache.org/viewvc?rev=1361369&view=rev
Log:
fix for: https://issues.apache.org/jira/browse/AMQNET-393


Modified:
    activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/   (props changed)
    activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/nant.build
    activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/main/csharp/Util/URISupport.cs
    activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/test/csharp/URISupportTest.cs

Propchange: activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/
------------------------------------------------------------------------------
  Merged /activemq/activemq-dotnet/Apache.NMS/trunk:r1361367

Modified: activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/nant.build
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/nant.build?rev=1361369&r1=1361368&r2=1361369&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/nant.build (original)
+++ activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/nant.build Fri Jul 13 20:10:33 2012
@@ -88,6 +88,7 @@
             <include name="${current.build.framework.assembly.dir}/mscorlib.dll" />
             <include name="${current.build.framework.assembly.dir}/System.dll" />
             <include name="${current.build.framework.assembly.dir}/System.Xml.dll" />
+            <include name="${current.build.framework.assembly.dir}/System.Web.dll" />
             <include name="${build.bin.dir}/${project.name}.dll" />
             <include name="${nunit.dll}" />
         </assemblyfileset>

Modified: activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/main/csharp/Util/URISupport.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/main/csharp/Util/URISupport.cs?rev=1361369&r1=1361368&r2=1361369&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/main/csharp/Util/URISupport.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/main/csharp/Util/URISupport.cs Fri Jul 13 20:10:33 2012
@@ -1,639 +1,638 @@
-/*
- * 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.
- */
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Reflection;
-using System.Text;
-#if !NETCF
-using System.Web;
-#endif
-
-namespace Apache.NMS.Util
-{
-	/// <summary>
-	/// Class to provide support for Uri query parameters which uses .Net reflection
-	/// to identify and set properties.
-	/// </summary>
-	public class URISupport
-	{
-		/// <summary>
-		/// Given a string that could be a Composite Uri that uses syntax not compatible
-		/// with the .NET Uri class such as an ActiveMQ failover Uri formatted as
-		/// "failover://(tcp://localhost:61616)", the initial '://' must be changed
-		/// to ':(' so that the Uri class doesn't attempt to parse the '(tcp:' as
-		/// the Uri's Authority as that is not a valid host name.
-		/// </summary>
-		/// <param name="uriString">
-		/// A string that could be a Composite Uri that uses syntax not compatible
-		/// with the .NET Uri class
-		/// </param>
-		public static Uri CreateCompatibleUri(string uriString)
-		{
-			string sanitized = uriString.Replace("://(", ":(");
-			return new Uri(sanitized);
-		}
-
-		/// <summary>
-		/// Parse a Uri query string of the form ?x=y&amp;z=0
-		/// into a map of name/value pairs.
-		/// </summary>
-		/// <param name="query">The query string to parse. This string should not contain
-		/// Uri escape characters.</param>
-		public static StringDictionary ParseQuery(String query)
-		{
-			StringDictionary map = new StringDictionary();
-
-			if(String.IsNullOrEmpty(query))
-			{
-				return EmptyMap;
-			}
-
-			// strip the initial "?"
-			if(query.StartsWith("?"))
-			{
-				query = query.Substring(1);
-			}
-
-			// split the query into parameters
-			string[] parameters = query.Split('&');
-			foreach(string pair in parameters)
-			{
-				if(pair.Length > 0)
-				{
-					string[] nameValue = pair.Split('=');
-
-					if(nameValue.Length != 2)
-					{
-						throw new NMSException(string.Format("Invalid Uri parameter: {0}", query));
-					}
-
-					map[nameValue[0]] = nameValue[1];
-				}
-			}
-
-			return map;
-		}
-
-		public static StringDictionary ParseParameters(Uri uri)
-		{
-			return (uri.Query == null
-					? EmptyMap
-					: ParseQuery(StripPrefix(uri.Query, "?")));
-		}
-
-		/// <summary>
-		/// Sets the public properties of a target object using a string map.
-		/// This method uses .Net reflection to identify public properties of
-		/// the target object matching the keys from the passed map.
-		/// </summary>
-		/// <param name="target">The object whose properties will be set.</param>
-		/// <param name="map">Map of key/value pairs.</param>
-		public static void SetProperties(object target, StringDictionary map)
-		{
-			Type type = target.GetType();
-
-			foreach(string key in map.Keys)
-			{
-				PropertyInfo prop = type.GetProperty(key,
-														BindingFlags.FlattenHierarchy
-														| BindingFlags.Public
-														| BindingFlags.Instance
-														| BindingFlags.IgnoreCase);
-
-				if(null != prop)
-				{
-					prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
-				}
-				else
-				{
-					FieldInfo field = type.GetField(key,
-														BindingFlags.FlattenHierarchy
-														| BindingFlags.Public
-														| BindingFlags.Instance
-														| BindingFlags.IgnoreCase);
-					if(null != field)
-					{
-						field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
-					}
-					else
-					{
-						throw new NMSException(string.Format("No such property or field: {0} on class: {1}", key, target.GetType().Name));
-					}
-				}
-			}
-		}
-
-		/// <summary>
-		/// Sets the public properties of a target object using a string map.
-		/// This method uses .Net reflection to identify public properties of
-		/// the target object matching the keys from the passed map.
-		/// </summary>
-		/// <param name="target">The object whose properties will be set.</param>
-		/// <param name="map">Map of key/value pairs.</param>
-		/// <param name="prefix">Key value prefix.  This is prepended to the property name
-		/// before searching for a matching key value.</param>
-		public static void SetProperties(object target, StringDictionary map, string prefix)
-		{
-			Type type = target.GetType();
-
-			List<String> matches = new List<String>();
-
-			foreach(string key in map.Keys)
-			{
-				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-				{
-					string bareKey = key.Substring(prefix.Length);
-					PropertyInfo prop = type.GetProperty(bareKey,
-															BindingFlags.FlattenHierarchy
-															| BindingFlags.Public
-															| BindingFlags.Instance
-															| BindingFlags.IgnoreCase);
-
-					if(null != prop)
-					{
-						prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
-					}
-					else
-					{
-						FieldInfo field = type.GetField(bareKey,
-															BindingFlags.FlattenHierarchy
-															| BindingFlags.Public
-															| BindingFlags.Instance
-															| BindingFlags.IgnoreCase);
-						if(null != field)
-						{
-							field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
-						}
-						else
-						{
-							throw new NMSException(string.Format("No such property or field: {0} on class: {1}", bareKey, target.GetType().Name));
-						}
-					}
-
-					// store for later removal.
-					matches.Add(key);
-				}
-			}
-
-			// Remove all the properties we set so they are used again later.
-			foreach(string match in matches)
-			{
-				map.Remove(match);
-			}
-		}
-
-		public static StringDictionary GetProperties(StringDictionary props, string prefix)
-		{
-
-			if(props == null)
-			{
-				throw new Exception("Properties Object was null");
-			}
-
-			StringDictionary result = new StringDictionary();
-
-			foreach(string key in props.Keys)
-			{
-				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-				{
-					string bareKey = key.Substring(prefix.Length);
-					String value = props[key];
-					result[bareKey] = value;
-				}
-			}
-
-			return result;
-		}
-
-		public static StringDictionary ExtractProperties(StringDictionary props, string prefix)
-		{
-
-			if(props == null)
-			{
-				throw new Exception("Properties Object was null");
-			}
-
-			StringDictionary result = new StringDictionary();
-			List<String> matches = new List<String>();
-
-			foreach(string key in props.Keys)
-			{
-				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-				{
-					String value = props[key];
-					result[key] = value;
-					matches.Add(key);
-				}
-			}
-
-			foreach(string match in matches)
-			{
-				props.Remove(match);
-			}
-
-			return result;
-		}
-
-		public static String UrlDecode(String s)
-		{
-#if !NETCF
-			return HttpUtility.HtmlDecode(s);
-#else
-            return Uri.UnescapeDataString(s);
-#endif
-		}
-
-		public static String UrlEncode(String s)
-		{
-#if !NETCF
-			return HttpUtility.HtmlEncode(s);
-#else
-            return Uri.EscapeUriString(s);
-#endif
-		}
-
-		public static String CreateQueryString(StringDictionary options)
-		{
-			if(options != null && options.Count > 0)
-			{
-				StringBuilder rc = new StringBuilder();
-				bool first = true;
-
-				foreach(String key in options.Keys)
-				{
-					string value = options[key];
-
-					if(first)
-					{
-						first = false;
-					}
-					else
-					{
-						rc.Append("&");
-					}
-
-					rc.Append(UrlEncode(key));
-					rc.Append("=");
-					rc.Append(UrlEncode(value));
-				}
-
-				return rc.ToString();
-			}
-			else
-			{
-				return "";
-			}
-		}
-
-		public static Uri CreateRemainingUri(Uri originalUri, StringDictionary parameters)
-		{
-			string s = CreateQueryString(parameters);
-
-			if(String.IsNullOrEmpty(s))
-			{
-				s = null;
-			}
-
-			return CreateUriWithQuery(originalUri, s);
-		}
-
-		public class CompositeData
-		{
-			private String host;
-			private String scheme;
-			private String path;
-			private Uri[] components;
-			private StringDictionary parameters;
-			private String fragment;
-
-			public Uri[] Components
-			{
-				get { return components; }
-				set { components = value; }
-			}
-
-			public String Fragment
-			{
-				get { return fragment; }
-				set { fragment = value; }
-			}
-
-			public StringDictionary Parameters
-			{
-				get { return parameters; }
-				set { parameters = value; }
-			}
-
-			public String Scheme
-			{
-				get { return scheme; }
-				set { scheme = value; }
-			}
-
-			public String Path
-			{
-				get { return path; }
-				set { path = value; }
-			}
-
-			public String Host
-			{
-				get { return host; }
-				set { host = value; }
-			}
-
-			public Uri toUri()
-			{
-				StringBuilder sb = new StringBuilder();
-				if(scheme != null)
-				{
-					sb.Append(scheme);
-					sb.Append(':');
-				}
-
-				if(!string.IsNullOrEmpty(host))
-				{
-					sb.Append(host);
-				}
-				else
-				{
-					sb.Append('(');
-					for(int i = 0; i < components.Length; i++)
-					{
-						if(i != 0)
-						{
-							sb.Append(',');
-						}
-						sb.Append(components[i].ToString());
-					}
-					sb.Append(')');
-				}
-
-				if(path != null)
-				{
-					sb.Append('/');
-					sb.Append(path);
-				}
-
-				if(parameters.Count != 0)
-				{
-					sb.Append("?");
-					sb.Append(CreateQueryString(parameters));
-				}
-
-				if(fragment != null)
-				{
-					sb.Append("#");
-					sb.Append(fragment);
-				}
-
-				return new Uri(sb.ToString());
-			}
-		}
-
-		public static String StripPrefix(String value, String prefix)
-		{
-			if(value.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-			{
-				return value.Substring(prefix.Length);
-			}
-
-			return value;
-		}
-
-		public static Uri CreateUriWithQuery(Uri uri, string query)
-		{
-			if(!String.IsNullOrEmpty(query) && !query.StartsWith("?"))
-			{
-				query = "?" + query;
-			}
-
-			if(String.IsNullOrEmpty(uri.Query))
-			{
-				return new Uri(uri.OriginalString + query);
-			}
-			else
-			{
-				string originalUri = uri.OriginalString;
-
-				int queryDelimPos = originalUri.LastIndexOf('?');
-				int compositeDelimPos = originalUri.LastIndexOf(')');
-
-				if(queryDelimPos <= compositeDelimPos)
-				{
-					// No Query or the Query is part of an inner Composite.
-					return new Uri(originalUri + query);
-				}
-				else
-				{
-					// Outer Uri has a Query or not a Composite Uri with a Query
-					string strippedUri = originalUri.Substring(0, queryDelimPos);
-					return new Uri(strippedUri + query);
-				}
-			}
-		}
-
-		public static Uri RemoveQuery(Uri original)
-		{
-			return CreateUriWithQuery(original, null);
-		}
-
-		public static CompositeData ParseComposite(Uri uri)
-		{
-			CompositeData rc = new CompositeData();
-			rc.Scheme = uri.Scheme;
-
-			// Start with original URI
-			//String ssp = uri.Authority + uri.PathAndQuery;
-			String ssp = uri.OriginalString;
-
-			ssp = StripPrefix(ssp, rc.Scheme + ":");
-			ssp = StripPrefix(ssp, "//");
-
-			int lastPoundPos = ssp.LastIndexOf("#");
-			int lastParendPos = ssp.LastIndexOf(")");
-
-			// Only include a Fragment that's outside any Composte sections.
-			if(lastPoundPos > lastParendPos)
-			{
-				rc.Fragment = ssp.Substring(lastPoundPos);
-				ssp = ssp.Substring(0, lastPoundPos);
-			}
-
-			// Ensure any embedded URIs don't have malformed authority's by changing
-			// them from '://(' which would cause the .NET Uri class to attempt to validate
-			// the authority as a hostname with, ':(' which is valid.
-			ssp = ssp.Replace("://(", ":(");
-
-			// Handle the composite components
-			ParseComposite(uri, rc, ssp);
-			return rc;
-		}
-
-		/// <summary>
-		/// </summary>
-		/// <param name="uri"></param>
-		/// <param name="rc"></param>
-		/// <param name="ssp"></param>
-		private static void ParseComposite(Uri uri, CompositeData rc, String ssp)
-		{
-			String componentString;
-			String parms;
-
-			if(!CheckParenthesis(ssp))
-			{
-				throw new NMSException(uri.ToString() + ": Not a matching number of '(' and ')' parenthesis");
-			}
-
-			int p;
-			int intialParen = ssp.IndexOf("(");
-
-			if(intialParen >= 0)
-			{
-				rc.Host = ssp.Substring(0, intialParen);
-				p = rc.Host.IndexOf("/");
-				if(p >= 0)
-				{
-					rc.Path = rc.Host.Substring(p);
-					rc.Host = rc.Host.Substring(0, p);
-				}
-
-				p = ssp.LastIndexOf(")");
-				int start = intialParen + 1;
-				int len = p - start;
-				componentString = ssp.Substring(start, len);
-				parms = ssp.Substring(p + 1).Trim();
-			}
-			else
-			{
-				componentString = ssp;
-				parms = "";
-			}
-
-			String[] components = SplitComponents(componentString);
-			rc.Components = new Uri[components.Length];
-			for(int i = 0; i < components.Length; i++)
-			{
-				rc.Components[i] = new Uri(components[i].Trim());
-			}
-
-			p = parms.IndexOf("?");
-			if(p >= 0)
-			{
-				if(p > 0)
-				{
-					rc.Path = StripPrefix(parms.Substring(0, p), "/");
-				}
-
-				rc.Parameters = ParseQuery(parms.Substring(p + 1));
-			}
-			else
-			{
-				if(parms.Length > 0)
-				{
-					rc.Path = StripPrefix(parms, "/");
-				}
-
-				rc.Parameters = EmptyMap;
-			}
-		}
-
-		private static StringDictionary EmptyMap
-		{
-			get { return new StringDictionary(); }
-		}
-
-		/// <summary>
-		/// </summary>
-		/// <param name="componentString"></param>
-		private static String[] SplitComponents(String componentString)
-		{
-			ArrayList l = new ArrayList();
-
-			int last = 0;
-			int depth = 0;
-			char[] chars = componentString.ToCharArray();
-			for(int i = 0; i < chars.Length; i++)
-			{
-				switch(chars[i])
-				{
-				case '(':
-					depth++;
-					break;
-
-				case ')':
-					depth--;
-					break;
-
-				case ',':
-					if(depth == 0)
-					{
-						String s = componentString.Substring(last, i - last);
-						l.Add(s);
-						last = i + 1;
-					}
-					break;
-
-				default:
-					break;
-				}
-			}
-
-			String ending = componentString.Substring(last);
-			if(ending.Length != 0)
-			{
-				l.Add(ending);
-			}
-
-			String[] rc = new String[l.Count];
-			l.CopyTo(rc);
-			return rc;
-		}
-
-		public static bool CheckParenthesis(String str)
-		{
-			bool result = true;
-
-			if(str != null)
-			{
-				int open = 0;
-				int closed = 0;
-
-				int i = 0;
-				while((i = str.IndexOf('(', i)) >= 0)
-				{
-					i++;
-					open++;
-				}
-
-				i = 0;
-				while((i = str.IndexOf(')', i)) >= 0)
-				{
-					i++;
-					closed++;
-				}
-
-				result = (open == closed);
-			}
-
-			return result;
-		}
-	}
-}
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Reflection;
+using System.Text;
+#if !NETCF
+using System.Web;
+#endif
+
+namespace Apache.NMS.Util
+{
+	/// <summary>
+	/// Class to provide support for Uri query parameters which uses .Net reflection
+	/// to identify and set properties.
+	/// </summary>
+	public class URISupport
+	{
+		/// <summary>
+		/// Given a string that could be a Composite Uri that uses syntax not compatible
+		/// with the .NET Uri class such as an ActiveMQ failover Uri formatted as
+		/// "failover://(tcp://localhost:61616)", the initial '://' must be changed
+		/// to ':(' so that the Uri class doesn't attempt to parse the '(tcp:' as
+		/// the Uri's Authority as that is not a valid host name.
+		/// </summary>
+		/// <param name="uriString">
+		/// A string that could be a Composite Uri that uses syntax not compatible
+		/// with the .NET Uri class
+		/// </param>
+		public static Uri CreateCompatibleUri(string uriString)
+		{
+			string sanitized = uriString.Replace("://(", ":(");
+			return new Uri(sanitized);
+		}
+
+		/// <summary>
+		/// Parse a Uri query string of the form ?x=y&amp;z=0
+		/// into a map of name/value pairs.
+		/// </summary>
+		/// <param name="query">The query string to parse. This string should not contain
+		/// Uri escape characters.</param>
+		public static StringDictionary ParseQuery(String query)
+		{
+			StringDictionary map = new StringDictionary();
+
+			if(String.IsNullOrEmpty(query))
+			{
+				return EmptyMap;
+			}
+
+			// strip the initial "?"
+			if(query.StartsWith("?"))
+			{
+				query = query.Substring(1);
+			}
+
+			// split the query into parameters
+			string[] parameters = query.Split('&');
+			foreach(string pair in parameters)
+			{
+				if(pair.Length > 0)
+				{
+					string[] nameValue = pair.Split('=');
+
+					if(nameValue.Length != 2)
+					{
+						throw new NMSException(string.Format("Invalid Uri parameter: {0}", query));
+					}
+
+					map[UrlDecode(nameValue[0])] = UrlDecode(nameValue[1]);
+				}
+			}
+
+			return map;
+		}
+
+		public static StringDictionary ParseParameters(Uri uri)
+		{
+			return (uri.Query == null
+					? EmptyMap
+					: ParseQuery(StripPrefix(uri.Query, "?")));
+		}
+
+		/// <summary>
+		/// Sets the public properties of a target object using a string map.
+		/// This method uses .Net reflection to identify public properties of
+		/// the target object matching the keys from the passed map.
+		/// </summary>
+		/// <param name="target">The object whose properties will be set.</param>
+		/// <param name="map">Map of key/value pairs.</param>
+		public static void SetProperties(object target, StringDictionary map)
+		{
+			Type type = target.GetType();
+
+			foreach(string key in map.Keys)
+			{
+				PropertyInfo prop = type.GetProperty(key,
+														BindingFlags.FlattenHierarchy
+														| BindingFlags.Public
+														| BindingFlags.Instance
+														| BindingFlags.IgnoreCase);
+
+				if(null != prop)
+				{
+					prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
+				}
+				else
+				{
+					FieldInfo field = type.GetField(key,
+														BindingFlags.FlattenHierarchy
+														| BindingFlags.Public
+														| BindingFlags.Instance
+														| BindingFlags.IgnoreCase);
+					if(null != field)
+					{
+						field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
+					}
+					else
+					{
+						throw new NMSException(string.Format("No such property or field: {0} on class: {1}", key, target.GetType().Name));
+					}
+				}
+			}
+		}
+
+		/// <summary>
+		/// Sets the public properties of a target object using a string map.
+		/// This method uses .Net reflection to identify public properties of
+		/// the target object matching the keys from the passed map.
+		/// </summary>
+		/// <param name="target">The object whose properties will be set.</param>
+		/// <param name="map">Map of key/value pairs.</param>
+		/// <param name="prefix">Key value prefix.  This is prepended to the property name
+		/// before searching for a matching key value.</param>
+		public static void SetProperties(object target, StringDictionary map, string prefix)
+		{
+			Type type = target.GetType();
+
+			List<String> matches = new List<String>();
+
+			foreach(string key in map.Keys)
+			{
+				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+				{
+					string bareKey = key.Substring(prefix.Length);
+					PropertyInfo prop = type.GetProperty(bareKey,
+															BindingFlags.FlattenHierarchy
+															| BindingFlags.Public
+															| BindingFlags.Instance
+															| BindingFlags.IgnoreCase);
+
+					if(null != prop)
+					{
+						prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
+					}
+					else
+					{
+						FieldInfo field = type.GetField(bareKey,
+															BindingFlags.FlattenHierarchy
+															| BindingFlags.Public
+															| BindingFlags.Instance
+															| BindingFlags.IgnoreCase);
+						if(null != field)
+						{
+							field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
+						}
+						else
+						{
+							throw new NMSException(string.Format("No such property or field: {0} on class: {1}", bareKey, target.GetType().Name));
+						}
+					}
+
+					// store for later removal.
+					matches.Add(key);
+				}
+			}
+
+			// Remove all the properties we set so they are used again later.
+			foreach(string match in matches)
+			{
+				map.Remove(match);
+			}
+		}
+
+		public static StringDictionary GetProperties(StringDictionary props, string prefix)
+		{
+			if(props == null)
+			{
+				throw new Exception("Properties Object was null");
+			}
+
+			StringDictionary result = new StringDictionary();
+
+			foreach(string key in props.Keys)
+			{
+				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+				{
+					string bareKey = key.Substring(prefix.Length);
+					String value = props[key];
+					result[bareKey] = value;
+				}
+			}
+
+			return result;
+		}
+
+		public static StringDictionary ExtractProperties(StringDictionary props, string prefix)
+		{
+
+			if(props == null)
+			{
+				throw new Exception("Properties Object was null");
+			}
+
+			StringDictionary result = new StringDictionary();
+			List<String> matches = new List<String>();
+
+			foreach(string key in props.Keys)
+			{
+				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+				{
+					String value = props[key];
+					result[key] = value;
+					matches.Add(key);
+				}
+			}
+
+			foreach(string match in matches)
+			{
+				props.Remove(match);
+			}
+
+			return result;
+		}
+
+		public static String UrlDecode(String s)
+		{
+#if !NETCF
+			return HttpUtility.UrlDecode(s);
+#else
+            return Uri.UnescapeDataString(s);
+#endif
+		}
+
+		public static String UrlEncode(String s)
+		{
+#if !NETCF
+			return HttpUtility.UrlEncode(s);
+#else
+            return Uri.EscapeUriString(s);
+#endif
+		}
+
+		public static String CreateQueryString(StringDictionary options)
+		{
+			if(options != null && options.Count > 0)
+			{
+				StringBuilder rc = new StringBuilder();
+				bool first = true;
+
+				foreach(String key in options.Keys)
+				{
+					string value = options[key];
+
+					if(first)
+					{
+						first = false;
+					}
+					else
+					{
+						rc.Append("&");
+					}
+
+					rc.Append(UrlEncode(key));
+					rc.Append("=");
+					rc.Append(UrlEncode(value));
+				}
+
+				return rc.ToString();
+			}
+			else
+			{
+				return "";
+			}
+		}
+
+		public static Uri CreateRemainingUri(Uri originalUri, StringDictionary parameters)
+		{
+			string s = CreateQueryString(parameters);
+
+			if(String.IsNullOrEmpty(s))
+			{
+				s = null;
+			}
+
+			return CreateUriWithQuery(originalUri, s);
+		}
+
+		public class CompositeData
+		{
+			private String host;
+			private String scheme;
+			private String path;
+			private Uri[] components;
+			private StringDictionary parameters;
+			private String fragment;
+
+			public Uri[] Components
+			{
+				get { return components; }
+				set { components = value; }
+			}
+
+			public String Fragment
+			{
+				get { return fragment; }
+				set { fragment = value; }
+			}
+
+			public StringDictionary Parameters
+			{
+				get { return parameters; }
+				set { parameters = value; }
+			}
+
+			public String Scheme
+			{
+				get { return scheme; }
+				set { scheme = value; }
+			}
+
+			public String Path
+			{
+				get { return path; }
+				set { path = value; }
+			}
+
+			public String Host
+			{
+				get { return host; }
+				set { host = value; }
+			}
+
+			public Uri toUri()
+			{
+				StringBuilder sb = new StringBuilder();
+				if(scheme != null)
+				{
+					sb.Append(scheme);
+					sb.Append(':');
+				}
+
+				if(!string.IsNullOrEmpty(host))
+				{
+					sb.Append(host);
+				}
+				else
+				{
+					sb.Append('(');
+					for(int i = 0; i < components.Length; i++)
+					{
+						if(i != 0)
+						{
+							sb.Append(',');
+						}
+						sb.Append(components[i].ToString());
+					}
+					sb.Append(')');
+				}
+
+				if(path != null)
+				{
+					sb.Append('/');
+					sb.Append(path);
+				}
+
+				if(parameters.Count != 0)
+				{
+					sb.Append("?");
+					sb.Append(CreateQueryString(parameters));
+				}
+
+				if(fragment != null)
+				{
+					sb.Append("#");
+					sb.Append(fragment);
+				}
+
+				return new Uri(sb.ToString());
+			}
+		}
+
+		public static String StripPrefix(String value, String prefix)
+		{
+			if(value.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+			{
+				return value.Substring(prefix.Length);
+			}
+
+			return value;
+		}
+
+		public static Uri CreateUriWithQuery(Uri uri, string query)
+		{
+			if(!String.IsNullOrEmpty(query) && !query.StartsWith("?"))
+			{
+				query = "?" + query;
+			}
+
+			if(String.IsNullOrEmpty(uri.Query))
+			{
+				return new Uri(uri.OriginalString + query);
+			}
+			else
+			{
+				string originalUri = uri.OriginalString;
+
+				int queryDelimPos = originalUri.LastIndexOf('?');
+				int compositeDelimPos = originalUri.LastIndexOf(')');
+
+				if(queryDelimPos <= compositeDelimPos)
+				{
+					// No Query or the Query is part of an inner Composite.
+					return new Uri(originalUri + query);
+				}
+				else
+				{
+					// Outer Uri has a Query or not a Composite Uri with a Query
+					string strippedUri = originalUri.Substring(0, queryDelimPos);
+					return new Uri(strippedUri + query);
+				}
+			}
+		}
+
+		public static Uri RemoveQuery(Uri original)
+		{
+			return CreateUriWithQuery(original, null);
+		}
+
+		public static CompositeData ParseComposite(Uri uri)
+		{
+			CompositeData rc = new CompositeData();
+			rc.Scheme = uri.Scheme;
+
+			// Start with original URI
+			//String ssp = uri.Authority + uri.PathAndQuery;
+			String ssp = uri.OriginalString;
+
+			ssp = StripPrefix(ssp, rc.Scheme + ":");
+			ssp = StripPrefix(ssp, "//");
+
+			int lastPoundPos = ssp.LastIndexOf("#");
+			int lastParendPos = ssp.LastIndexOf(")");
+
+			// Only include a Fragment that's outside any Composte sections.
+			if(lastPoundPos > lastParendPos)
+			{
+				rc.Fragment = ssp.Substring(lastPoundPos);
+				ssp = ssp.Substring(0, lastPoundPos);
+			}
+
+			// Ensure any embedded URIs don't have malformed authority's by changing
+			// them from '://(' which would cause the .NET Uri class to attempt to validate
+			// the authority as a hostname with, ':(' which is valid.
+			ssp = ssp.Replace("://(", ":(");
+
+			// Handle the composite components
+			ParseComposite(uri, rc, ssp);
+			return rc;
+		}
+
+		/// <summary>
+		/// </summary>
+		/// <param name="uri"></param>
+		/// <param name="rc"></param>
+		/// <param name="ssp"></param>
+		private static void ParseComposite(Uri uri, CompositeData rc, String ssp)
+		{
+			String componentString;
+			String parms;
+
+			if(!CheckParenthesis(ssp))
+			{
+				throw new NMSException(uri.ToString() + ": Not a matching number of '(' and ')' parenthesis");
+			}
+
+			int p;
+			int intialParen = ssp.IndexOf("(");
+
+			if(intialParen >= 0)
+			{
+				rc.Host = ssp.Substring(0, intialParen);
+				p = rc.Host.IndexOf("/");
+				if(p >= 0)
+				{
+					rc.Path = rc.Host.Substring(p);
+					rc.Host = rc.Host.Substring(0, p);
+				}
+
+				p = ssp.LastIndexOf(")");
+				int start = intialParen + 1;
+				int len = p - start;
+				componentString = ssp.Substring(start, len);
+				parms = ssp.Substring(p + 1).Trim();
+			}
+			else
+			{
+				componentString = ssp;
+				parms = "";
+			}
+
+			String[] components = SplitComponents(componentString);
+			rc.Components = new Uri[components.Length];
+			for(int i = 0; i < components.Length; i++)
+			{
+				rc.Components[i] = new Uri(components[i].Trim());
+			}
+
+			p = parms.IndexOf("?");
+			if(p >= 0)
+			{
+				if(p > 0)
+				{
+					rc.Path = StripPrefix(parms.Substring(0, p), "/");
+				}
+
+				rc.Parameters = ParseQuery(parms.Substring(p + 1));
+			}
+			else
+			{
+				if(parms.Length > 0)
+				{
+					rc.Path = StripPrefix(parms, "/");
+				}
+
+				rc.Parameters = EmptyMap;
+			}
+		}
+
+		private static StringDictionary EmptyMap
+		{
+			get { return new StringDictionary(); }
+		}
+
+		/// <summary>
+		/// </summary>
+		/// <param name="componentString"></param>
+		private static String[] SplitComponents(String componentString)
+		{
+			ArrayList l = new ArrayList();
+
+			int last = 0;
+			int depth = 0;
+			char[] chars = componentString.ToCharArray();
+			for(int i = 0; i < chars.Length; i++)
+			{
+				switch(chars[i])
+				{
+				case '(':
+					depth++;
+					break;
+
+				case ')':
+					depth--;
+					break;
+
+				case ',':
+					if(depth == 0)
+					{
+						String s = componentString.Substring(last, i - last);
+						l.Add(s);
+						last = i + 1;
+					}
+					break;
+
+				default:
+					break;
+				}
+			}
+
+			String ending = componentString.Substring(last);
+			if(ending.Length != 0)
+			{
+				l.Add(ending);
+			}
+
+			String[] rc = new String[l.Count];
+			l.CopyTo(rc);
+			return rc;
+		}
+
+		public static bool CheckParenthesis(String str)
+		{
+			bool result = true;
+
+			if(str != null)
+			{
+				int open = 0;
+				int closed = 0;
+
+				int i = 0;
+				while((i = str.IndexOf('(', i)) >= 0)
+				{
+					i++;
+					open++;
+				}
+
+				i = 0;
+				while((i = str.IndexOf(')', i)) >= 0)
+				{
+					i++;
+					closed++;
+				}
+
+				result = (open == closed);
+			}
+
+			return result;
+		}
+	}
+}

Modified: activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/test/csharp/URISupportTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/test/csharp/URISupportTest.cs?rev=1361369&r1=1361368&r2=1361369&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/test/csharp/URISupportTest.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS/branches/1.5.x/src/test/csharp/URISupportTest.cs Fri Jul 13 20:10:33 2012
@@ -21,6 +21,9 @@ using System.Collections.Specialized;
 using Apache.NMS.Util;
 
 using NUnit.Framework;
+#if !NETCF
+using System.Web;
+#endif
 
 namespace Apache.NMS.Test
 {
@@ -266,6 +269,28 @@ namespace Apache.NMS.Test
 	        Assert.IsFalse(dest.Query.Equals(source.Query), "same uri, ssp");
 	    }
 
+
+#if !NETCF
+		[Test]
+        public void TestParseQueryEncoding() {
+
+			String paramName = "name";
+            String paramValue = "CN=Test, OU=bla, ..&%/§()%3q743847)/(&%/.. hjUIFHUFH";
+
+            String uriString = "http://someserver.com:1234/?";
+
+            //encoding the param with url encode
+            uriString += paramName + "=" + HttpUtility.UrlEncode(paramValue);
+
+            Uri uri = new Uri(uriString);
+
+            StringDictionary dictionary = URISupport.ParseQuery(uri.Query);
+
+            String value = dictionary[paramName];
+
+            NUnit.Framework.Assert.AreEqual(paramValue, value);
+        }
+#endif
 	}
 }