Author: atsushi
Date: 2008-02-12 13:22:50 -0500 (Tue, 12 Feb 2008)
New Revision: 95540

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

        * UriTemplateMatch.cs : implemented some members.
        * UriTemplateTable.cs : implemented Match() and MatchSingle().
        * UriTemplate.cs : Do not expand template in non-path-query area.
          Implemented Match().

        * UriTemplateTest.cs : Added tests for Match() and more Binding tests.



Modified: trunk/olive/class/System.ServiceModel.Web/System/ChangeLog
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/ChangeLog  2008-02-12 
18:10:52 UTC (rev 95539)
+++ trunk/olive/class/System.ServiceModel.Web/System/ChangeLog  2008-02-12 
18:22:50 UTC (rev 95540)
@@ -1,5 +1,12 @@
 2008-02-12  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
+       * UriTemplateMatch.cs : implemented some members.
+       * UriTemplateTable.cs : implemented Match() and MatchSingle().
+       * UriTemplate.cs : Do not expand template in non-path-query area.
+         Implemented Match().
+
+2008-02-12  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
        * UriTemplateTable.cs, UriTemplateEquivalenceComparer.cs : new stubs.
        * UriTemplateMatchException.cs : new.
        * UriTemplate.cs : implemented .ctor(), BindByName() and

Modified: trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs     
2008-02-12 18:10:52 UTC (rev 95539)
+++ trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs     
2008-02-12 18:22:50 UTC (rev 95540)
@@ -39,19 +39,26 @@
                static readonly ReadOnlyCollection<string> empty_strings = new 
ReadOnlyCollection<string> (new string [0]);
 
                string template;
-               Uri uri;
                ReadOnlyCollection<string> path, query;
 
+               [MonoTODO ("It needs some rewrite: template bindings should be 
available only one per segment")]
                public UriTemplate (string template)
                {
                        if (template == null)
                                throw new ArgumentNullException ("template");
                        this.template = template;
 
-                       int q = template.IndexOf ('?');
-                       path = ParseTemplate (template, 0, q >= 0 ? q : 
template.Length);
+                       string p = template;
+                       // Trim scheme, host name and port if exist.
+                       if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix 
(template, "http")) {
+                               int idx = template.IndexOf ('/', 8); // after 
"http://x"; or "https://";
+                               if (idx > 0)
+                                       p = template.Substring (idx);
+                       }
+                       int q = p.IndexOf ('?');
+                       path = ParseTemplate (p, 0, q >= 0 ? q : p.Length);
                        if (q >= 0)
-                               query = ParseTemplate (template, q, 
template.Length);
+                               query = ParseTemplate (p, q, p.Length);
                        else
                                query = empty_strings;
                }
@@ -64,6 +71,13 @@
                        get { return query; }
                }
 
+               public override string ToString ()
+               {
+                       return template;
+               }
+
+               // Bind
+
                public Uri BindByName (Uri baseAddress, NameValueCollection 
parameters)
                {
                        CheckBaseAddress (baseAddress);
@@ -107,7 +121,7 @@
 
                void BindByPosition (ref int src, StringBuilder sb, 
ReadOnlyCollection<string> names, string [] values, ref int index)
                {
-                       foreach (string name in names) {
+                       for (int i = 0; i < names.Count; i++) {
                                int s = template.IndexOf ('{', src);
                                int e = template.IndexOf ('}', s + 1);
                                sb.Append (template.Substring (src, s - src));
@@ -119,29 +133,80 @@
                        }
                }
 
+               // Compare
+
                [MonoTODO]
                public bool IsEquivalentTo (UriTemplate other)
                {
-                       throw new NotImplementedException ();
+                       if (other == null)
+                               throw new ArgumentNullException ("other");
+                       return new UriTemplateEquivalenceComparer ().Equals 
(this, other);
                }
 
-               [MonoTODO]
+               // Match
+
                public UriTemplateMatch Match (Uri baseAddress, Uri candidate)
                {
-                       throw new NotImplementedException ();
+                       CheckBaseAddress (baseAddress);
+                       if (candidate == null)
+                               throw new ArgumentNullException ("candidate");
+
+                       if (Uri.Compare (baseAddress, candidate, 
UriComponents.StrongAuthority, UriFormat.SafeUnescaped, 
StringComparison.Ordinal) != 0)
+                               return null;
+
+                       int i = 0, c = 0;
+                       UriTemplateMatch m = new UriTemplateMatch ();
+                       m.BaseUri = baseAddress;
+                       m.Template = this;
+                       var vc = m.BoundVariables;
+
+                       string cp = candidate.PathAndQuery;
+                       foreach (string name in path) {
+                               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;
+                               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;
+                               c += value.Length;
+                       }
+                       if ((cp.Length - c) != (template.Length - i) ||
+                           String.CompareOrdinal (cp, c, template, i, 
template.Length - i) != 0)
+                               return null; // suffix doesn't match
+
+                       return m;
                }
 
-               public override string ToString ()
+               int StringIndexOf (string s, string pattern, int idx)
                {
-                       return template;
+                       return CultureInfo.InvariantCulture.CompareInfo.IndexOf 
(s, pattern, idx, CompareOptions.OrdinalIgnoreCase);
                }
 
+               // Helpers
+
                void CheckBaseAddress (Uri baseAddress)
                {
                        if (baseAddress == null)
                                throw new ArgumentNullException ("baseAddress");
                        if (!baseAddress.IsAbsoluteUri)
-                       throw new ArgumentException ("baseAddress must be an 
absolute URI.");
+                               throw new ArgumentException ("baseAddress must 
be an absolute URI.");
                        if (baseAddress.Scheme == Uri.UriSchemeHttp ||
                            baseAddress.Scheme == Uri.UriSchemeHttps)
                                return;

Modified: trunk/olive/class/System.ServiceModel.Web/System/UriTemplateMatch.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/UriTemplateMatch.cs        
2008-02-12 18:10:52 UTC (rev 95539)
+++ trunk/olive/class/System.ServiceModel.Web/System/UriTemplateMatch.cs        
2008-02-12 18:22:50 UTC (rev 95540)
@@ -37,20 +37,27 @@
                {
                }
 
-               [MonoTODO]
+               Uri base_uri;
+               NameValueCollection nvc;
+               object data;
+               UriTemplate template;
+
                public Uri BaseUri {
-                       get { throw new NotImplementedException (); }
-                       set { throw new NotImplementedException (); }
+                       get { return base_uri; }
+                       set { base_uri = value; }
                }
 
-               [MonoTODO]
                public NameValueCollection BoundVariables {
-                       get { throw new NotImplementedException (); }
+                       get {
+                               if (nvc == null)
+                                       nvc = new NameValueCollection ();
+                               return nvc;
+                       }
                }
 
                public object Data {
-                       get { throw new NotImplementedException (); }
-                       set { throw new NotImplementedException (); }
+                       get { return data; }
+                       set { data = value; }
                }
 
                [MonoTODO]
@@ -69,10 +76,9 @@
                        set { throw new NotImplementedException (); }
                }
 
-               [MonoTODO]
                public UriTemplate Template {
-                       get { throw new NotImplementedException (); }
-                       set { throw new NotImplementedException (); }
+                       get { return template; }
+                       set { template = value; }
                }
 
                public Collection<string> WildcardPathSegments {

Modified: trunk/olive/class/System.ServiceModel.Web/System/UriTemplateTable.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/UriTemplateTable.cs        
2008-02-12 18:10:52 UTC (rev 95539)
+++ trunk/olive/class/System.ServiceModel.Web/System/UriTemplateTable.cs        
2008-02-12 18:22:50 UTC (rev 95540)
@@ -93,13 +93,26 @@
                [MonoTODO]
                public Collection<UriTemplateMatch> Match (Uri uri)
                {
-                       throw new NotImplementedException ();
+                       var c = new Collection<UriTemplateMatch> ();
+                       UriTemplateMatch ret = null;
+                       foreach (Pair p in key_value_pairs) {
+                               ret = p.Key.Match (base_address, uri);
+                               if (ret != null)
+                                       c.Add (ret);
+                       }
+                       return c;
                }
 
                [MonoTODO]
                public UriTemplateMatch MatchSingle (Uri uri)
                {
-                       throw new NotImplementedException ();
+                       UriTemplateMatch ret = null;
+                       foreach (Pair p in key_value_pairs) {
+                               ret = p.Key.Match (base_address, uri);
+                               if (ret != null)
+                                       return ret;
+                       }
+                       throw new UriTemplateMatchException (String.Format ("No 
template matched for Uri '{0}'", uri));
                }
        }
 }

Modified: trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog     
2008-02-12 18:10:52 UTC (rev 95539)
+++ trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog     
2008-02-12 18:22:50 UTC (rev 95540)
@@ -1,4 +1,8 @@
 2008-02-12  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
+       * UriTemplateTest.cs : Added tests for Match() and more Binding tests.
+
+2008-02-12  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
        * UriTemplateTest.cs : new. Test .ctor(), BindByName() and 
          BindByPosition().

Modified: 
trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs    
2008-02-12 18:10:52 UTC (rev 95539)
+++ trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs    
2008-02-12 18:22:50 UTC (rev 95540)
@@ -69,20 +69,25 @@
                        var t = new UriTemplate ("urn:foo");
                        Assert.AreEqual (0, t.PathSegmentVariableNames.Count, 
"#1a");
                        Assert.AreEqual (0, t.QueryValueVariableNames.Count, 
"#1b");
+
                        t = new UriTemplate ("http://localhost:8080/";);
                        Assert.AreEqual (0, t.PathSegmentVariableNames.Count, 
"#2a");
                        Assert.AreEqual (0, t.QueryValueVariableNames.Count, 
"#2b");
+
                        t = new UriTemplate ("http://localhost:8080/foo/";);
                        Assert.AreEqual (0, t.PathSegmentVariableNames.Count, 
"#3a");
                        Assert.AreEqual (0, t.QueryValueVariableNames.Count, 
"#3b");
+
                        t = new UriTemplate ("http://localhost:8080/{foo}";);
                        Assert.AreEqual (1, t.PathSegmentVariableNames.Count, 
"#4a");
                        Assert.AreEqual ("FOO", t.PathSegmentVariableNames [0], 
"#4b");
                        Assert.AreEqual (0, t.QueryValueVariableNames.Count, 
"#4c");
+
                        t = new UriTemplate ("http://localhost:8080/{foo}/{";);
                        Assert.AreEqual (1, t.PathSegmentVariableNames.Count, 
"#5a");
                        Assert.AreEqual ("FOO", t.PathSegmentVariableNames [0], 
"#5b");
                        Assert.AreEqual (0, t.QueryValueVariableNames.Count, 
"#5c");
+
                        t = new UriTemplate 
("http://localhost:8080/hoge?test={foo}&test2={bar}";);
                        Assert.AreEqual (0, t.PathSegmentVariableNames.Count, 
"#6a");
                        Assert.AreEqual (2, t.QueryValueVariableNames.Count, 
"#6b");
@@ -91,6 +96,25 @@
                }
 
                [Test]
+               [Category ("NotWorking")]
+               public void VariablesInSameSegment ()
+               {
+                       var t = new UriTemplate 
("http://localhost:8080/{foo}{bar}";);
+                       Assert.AreEqual (1, t.PathSegmentVariableNames.Count, 
"#7a");
+                       // wow.
+                       Assert.AreEqual ("FOO}{BAR", t.PathSegmentVariableNames 
[0], "#7b");
+                       Assert.AreEqual (0, t.QueryValueVariableNames.Count, 
"#7c");
+               }
+
+               [Test]
+               public void VariablesInNonPathQuery ()
+               {
+                       var t = new UriTemplate ("http://localhost:{foo}/";);
+                       Assert.AreEqual (0, t.PathSegmentVariableNames.Count, 
"#8a");
+                       Assert.AreEqual (0, t.QueryValueVariableNames.Count, 
"#8b");
+               }
+
+               [Test]
                [ExpectedException (typeof (InvalidOperationException))]
                public void DuplicateNameInTemplate ()
                {
@@ -148,6 +172,12 @@
                }
 
                [Test]
+               public void BindInSameSegment ()
+               {
+                       new UriTemplate ("/hoo/{foo}{bar}");
+               }
+
+               [Test]
                public void BindByName ()
                {
                        var t = new UriTemplate ("/{foo}/{bar}/");
@@ -205,5 +235,43 @@
                        var u = t.BindByPosition (new Uri 
("http://localhost/";), "value1", "value2");
                        Assert.AreEqual ("http://localhost/value1/value2/";, 
u.ToString ());
                }
+
+               [Test]
+               public void MatchNoTemplateItem ()
+               {
+                       var t = new UriTemplate ("/hooray");
+                       var n = new NameValueCollection ();
+                       Assert.IsNotNull (t.Match (new Uri 
("http://localhost/";), new Uri ("http://localhost/hooray";)), "#1");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/foobar";)), "#2");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/hooray/foobar";)), "#3");
+               }
+
+               [Test]
+               public void MatchWrongTemplate ()
+               {
+                       var t = new UriTemplate ("/hoo{foo}");
+                       var n = new NameValueCollection ();
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/hooray";)), "#1");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/foobar";)), "#2");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/hooray/foobar";)), "#3");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/hoo/ray";)), "#4");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/hoo";)), "#5");
+                       // this matches (as if there were no template).
+                       Assert.IsNotNull (t.Match (new Uri 
("http://localhost/";), new Uri ("http://localhost/hoo{foo}";)), "#6");
+               }
+
+               [Test]
+               public void Match ()
+               {
+                       var t = new UriTemplate ("/{foo}/{bar}");
+                       var n = new NameValueCollection ();
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/hooray";)), "#1");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/v1/v2/extra";)), "#2");
+                       Assert.IsNull (t.Match (new Uri ("http://localhost/";), 
new Uri ("http://localhost/1/2/";)), "#3");
+                       UriTemplateMatch m = t.Match (new Uri 
("http://localhost/";), new Uri ("http://localhost/foooo/baaar";));
+                       Assert.IsNotNull (m, "#4");
+                       Assert.AreEqual ("foooo", m.BoundVariables ["foo"], 
"#5");
+                       Assert.AreEqual ("baaar", m.BoundVariables ["bar"], 
"#6");
+               }
        }
 }

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

Reply via email to