Author: atsushi
Date: 2008-02-16 06:10:40 -0500 (Sat, 16 Feb 2008)
New Revision: 95858

Modified:
   trunk/olive/class/System.ServiceModel.Web/System/ChangeLog
   trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs
   trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog
   trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs
Log:
2008-02-16  Atsushi Enomoto  <[EMAIL PROTECTED]>

        * UriTemplate.cs : rewrote query parameter retrieval part. It did
          not match order-independent input and lack of parameters.

        * UriTemplateTest.cs : enable query parameter matching test.



Modified: trunk/olive/class/System.ServiceModel.Web/System/ChangeLog
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/ChangeLog  2008-02-16 
09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/System/ChangeLog  2008-02-16 
11:10:40 UTC (rev 95858)
@@ -1,3 +1,8 @@
+2008-02-16  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
+       * UriTemplate.cs : rewrote query parameter retrieval part. It did
+         not match order-independent input and lack of parameters.
+
 2008-02-15  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
        * UriTemplateMatch.cs : implement everything but WildcardPathSegments.

Modified: trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs     
2008-02-16 09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs     
2008-02-16 11:10:40 UTC (rev 95858)
@@ -40,6 +40,7 @@
 
                string template;
                ReadOnlyCollection<string> path, query;
+               Dictionary<string,string> query_params = new 
Dictionary<string,string> ();
 
                [MonoTODO ("It needs some rewrite: template bindings should be 
available only one per segment")]
                public UriTemplate (string template)
@@ -56,9 +57,9 @@
                                        p = template.Substring (idx);
                        }
                        int q = p.IndexOf ('?');
-                       path = ParseTemplate (p, 0, q >= 0 ? q : p.Length);
+                       path = ParsePathTemplate (p, 0, q >= 0 ? q : p.Length);
                        if (q >= 0)
-                               query = ParseTemplate (p, q, p.Length);
+                               ParseQueryTemplate (p, q, p.Length);
                        else
                                query = empty_strings;
                }
@@ -161,7 +162,7 @@
                        m.RequestUri = candidate;
                        var vc = m.BoundVariables;
 
-                       string cp = candidate.PathAndQuery;
+                       string cp = candidate.AbsolutePath;
 
                        if (template.Length > 0 && template [0] == '/')
                                i++;
@@ -182,24 +183,26 @@
                                m.RelativePathSegments.Add (value);
                                c += value.Length;
                        }
-                       foreach (string name in query) {
-                               int n = StringIndexOf (template, '{' + name + 
'}', i);
-                               if (String.CompareOrdinal (cp, c, template, i, 
n - i) != 0)
-                                       return null; // doesn't match before 
current template part.
-                               c += n - i;
-                               i = n + 2 + name.Length;
-                               int ce = cp.IndexOf ('&', c);
-                               if (ce < 0)
-                                       ce = cp.Length;
-                               string value = cp.Substring (c, ce - c);
-                               vc [name] = value;
-                               m.QueryParameters.Add (name, value);
-                               c += value.Length;
-                       }
-                       if ((cp.Length - c) != (template.Length - i) ||
-                           String.CompareOrdinal (cp, c, template, i, 
template.Length - i) != 0)
+                       int tEnd = template.IndexOf ('?');
+                       if (tEnd < 0)
+                               tEnd = template.Length;
+                       if ((cp.Length - c) != (tEnd - i) ||
+                           String.CompareOrdinal (cp, c, template, i, tEnd - 
i) != 0)
                                return null; // suffix doesn't match
+                       
+                       if (candidate.Query.Length == 0)
+                               return m;
 
+
+                       string [] parameters = candidate.Query.Substring 
(1).Split ('&'); // chop first '?'
+                       foreach (string parameter in parameters) {
+                               string [] pair = parameter.Split ('=');
+                               m.QueryParameters.Add (pair [0], pair [1]);
+                               if (!query.Contains (pair [0]))
+                                       continue;
+                               vc.Add (pair [0], pair [1]);
+                       }
+
                        return m;
                }
 
@@ -222,7 +225,7 @@
                        throw new ArgumentException ("baseAddress scheme must 
be either http or https.");
                }
 
-               ReadOnlyCollection<string> ParseTemplate (string template, int 
index, int end)
+               ReadOnlyCollection<string> ParsePathTemplate (string template, 
int index, int end)
                {
                        List<string> list = null;
                        for (int i = index; i <= end; ) {
@@ -244,5 +247,29 @@
                        }
                        return list != null ? new ReadOnlyCollection<string> 
(list) : empty_strings;
                }
+
+               void ParseQueryTemplate (string template, int index, int end)
+               {
+                       // template starts with '?'
+                       string [] parameters = template.Substring (index + 1, 
end - index - 1).Split ('&');
+                       List<string> list = null;
+                       foreach (string parameter in parameters) {
+                               string [] pair = parameter.Split ('=');
+                               if (pair.Length != 2)
+                                       throw new FormatException ("Invalid URI 
query string format");
+                               string pname = pair [0];
+                               string pvalue = pair [1];
+                               if (pvalue.Length >= 2 && pvalue [0] == '{' && 
pvalue [pvalue.Length - 1] == '}') {
+                                       string ptemplate = pvalue.Substring (1, 
pvalue.Length - 2).ToUpperInvariant ();
+                                       query_params.Add (pname, ptemplate);
+                                       if (list == null)
+                                               list = new List<string> ();
+                                       if (list.Contains (ptemplate) || (path 
!= null && path.Contains (ptemplate)))
+                                               throw new 
InvalidOperationException (String.Format ("The URI template string contains 
duplicate template item {{'{0}'}}", pvalue));
+                                       list.Add (ptemplate);
+                               }
+                       }
+                       query = list != null ? new ReadOnlyCollection<string> 
(list.ToArray ()) : empty_strings;
+               }
        }
 }

Modified: trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog     
2008-02-16 09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog     
2008-02-16 11:10:40 UTC (rev 95858)
@@ -1,3 +1,7 @@
+2008-02-16  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
+       * UriTemplateTest.cs : enable query parameter matching test.
+
 2008-02-15  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
        * UriTemplateTest.cs : added not-working case to be fixed.

Modified: 
trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs    
2008-02-16 09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs    
2008-02-16 11:10:40 UTC (rev 95858)
@@ -276,13 +276,18 @@
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void Match2 ()
                {
                        var t = new UriTemplate ("/{foo}/{bar}?p1={baz}");
                        var n = new NameValueCollection ();
                        Uri baseUri = new Uri ("http://localhost/";);
-                       Assert.IsNotNull (t.Match (baseUri, new Uri 
("http://localhost/X/Y";)));
+                       Assert.IsNotNull (t.Match (baseUri, new Uri 
("http://localhost/X/Y";)), "#1");
+                       UriTemplateMatch m = t.Match (baseUri, new Uri 
("http://localhost/X/Y?p2=v&p1=vv";));
+                       Assert.IsNotNull (m, "#2");
+                       // QueryParameters must contain non-template query 
parameters.
+                       Assert.AreEqual (2, m.QueryParameters.Count, "#3");
+                       Assert.AreEqual ("v", m.QueryParameters ["p2"], "#4");
+                       Assert.AreEqual ("vv", m.QueryParameters ["p1"], "#5");
                }
        }
 }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to