tsunami

log in
history

TIME Urls.cs

Luke Breuer
2008-01-13 05:30 UTC

using System;
using System.Web;
using System.Text.RegularExpressions;

namespace Time
{
    public class Url
    {
        private string _relative;
        private string _absolute;

        public string Absolute { get { return _absolute; } }

        public Url(string relativeUrl)
        {
            _relative = relativeUrl;
            _absolute = Urls.Root + relativeUrl;
        }

        public string RenderHyperlink(string innerHtml)
        {
            //Common.Debug(">>" + _absolute + "\n>>>" + innerHtml + "\n>>>>" + new System.Diagnostics.StackTrace().ToString());

            return string.Format("<a href='{0}'>{1}</a>",
                _absolute, innerHtml);
        }

        public string RenderHyperlink(string innerHtml, string style)
        {
            //Common.Debug(">>" + _absolute + "\n>>>" + innerHtml + "\n>>>>" + new System.Diagnostics.StackTrace().ToString());

            return string.Format("<a href='{0}' style='{1}'>{2}</a>",
                _absolute, style, innerHtml);
        }

        public override string ToString()
        {
            return this;
        }

        public static implicit operator string(Url u)
        {
            return u.Absolute;
        }
    }

    public static class Urls
    {
        public static readonly string Root;
        public const string ValidUrlPathCharacters =
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@$^()_-+=[]{};',. ";

        static Urls()
        {
            Root = HttpContext.Current.Request.ApplicationPath;
            
            if (!Root.EndsWith("/"))
                Root += "/";
        }

        public static string EncodeSearchString(string s)
        {
            // HACK: ASP.NET/IIS will only allow certain characters before ".aspx"
            return Regex.IsMatch(s, @"^[a-zA-Z_-/0-9. #~!$]*$")
                ? HttpUtility.UrlEncode(s) + ".aspx"
                : ".aspx?q=" + HttpUtility.UrlEncode(s);
        }

        public static Url Item(int pk, string name)
        {
            return Item(pk, name, AddRelationship.None, false);
        }
        private static Url Item(int pk, string name, AddRelationship add)
        {
            return Item(pk, name, add, false);
        }
        public static Url Item(int pk, string name, bool edit)
        {
            return Item(pk, name, AddRelationship.None, edit);
        }
        private static Url Item(int pk, string name, AddRelationship add, bool edit)
        {
            bool nameAndPkSpecified = !string.IsNullOrEmpty(name) && pk != -1;
            bool nameOrPkSpecified = !string.IsNullOrEmpty(name) || pk != -1;
            
            // HACK: for some reason, [#] in urls with a "/" (%23) after screw up ASP.NET
            // %3a == ':'
            string s = string.Format("item/{0}{1}{2}{3}{4}.aspx",
                name != null ? Regex.Replace(name, @"%23|%3a", "") : null,
                nameAndPkSpecified ? "/" : "",
                pk != -1 ? pk.ToString() : "",
                edit && nameOrPkSpecified ? "/" : "",
                edit ? "edit" : "" );

            switch (add)
            {
                case AddRelationship.None:
                    break;

                case AddRelationship.Object:
                    s += "?add=object";
                    break;

                case AddRelationship.Subject:
                    s += "?add=subject";
                    break;

                case AddRelationship.Predicate:
                    s += "?add=predicate";
                    break;
            }

            //Common.Debug(s);

            return new Url(s);
        }

        public static Url Forum(int forumPk)
        {
            return new Url(string.Format("forum/{0}.aspx", forumPk));
        }

        public static Url Thread(int forumPk, int threadPk)
        {
            return new Url(string.Format("forum/{0}/thread/{1}.aspx", forumPk, threadPk));
        }

        public static Url Tag(string tag)
        {
            return new Url(string.Format("tag/{0}", Urls.EncodeSearchString(tag)));
        }
    }
}