Click here to Skip to main content
15,897,291 members
Articles / Web Development / ASP.NET

SharePoint CAML Query Builder Dialog for your Web Parts

Rate me:
Please Sign up or sign in to vote.
4.65/5 (9 votes)
24 Mar 2009CPOL7 min read 167.8K   847   34  
A SharePoint CAML query builder dialog for your Web Parts
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Threading;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Diagnostics;
using Mullivan.SharePoint.Remote.SharePointLists;
using Mullivan.SharePoint.Remote.SharePointSiteData;

namespace Mullivan.SharePoint.Remote
{
    public class SPRepositoryProvider
    {
        public SPRepositoryResponse GetRepository(SPRepositoryRequest request)
        {
            SPRepositoryResponse response = new SPRepositoryResponse();
            SPRepository repository = new SPRepository();
            Dictionary<string, SPList> libraries = new Dictionary<string, SPList>();
            ReaderWriterLock rwlLibraries = new ReaderWriterLock();
            ExceptionInfo exceptionInfo = new ExceptionInfo();
            XmlNode xnLists = null;

           
            using (Lists spLists = CreateListService(request.Uri, request.Credentials))
            {
                xnLists = spLists.GetListCollection();
            }

            int listCount = xnLists.ChildNodes.Count;

            foreach (XmlNode xnList in xnLists.ChildNodes)
            {
                WaitCallback wcb = new WaitCallback(GetListThreaded);
                ListRequest lr = new ListRequest();
                lr.RepositoryRequest = request;
                lr.ListId = xnList.Attributes["ID"].Value;
                lr.Lists = libraries;
                lr.ListNode = xnList;
                lr.Lock = rwlLibraries;
                lr.ExceptionInfo = exceptionInfo;

                ThreadPool.QueueUserWorkItem(wcb, lr);
            }

            while (true)
            {
                try
                {
                    rwlLibraries.AcquireReaderLock(100);
                    if (libraries.Count >= listCount || exceptionInfo.Exception != null)
                        break;
                }
                catch { } //It's ok if the reader lock expires
                finally
                {
                    if (rwlLibraries.IsReaderLockHeld)
                        rwlLibraries.ReleaseReaderLock();
                }
                Thread.Sleep(10);
            }

            if(exceptionInfo.Exception != null)
                throw new Exception(string.Format("An error occured while getting the schema for library {0}. {1} {1} Error: {1}{2}", exceptionInfo.ListName, Environment.NewLine, exceptionInfo.Exception.ToString()));

            repository.Uri = request.Uri;
            repository.Credential = request.Credentials;
            repository.Lists = libraries;
            response.Repository = repository;
            return response;
        }

        public SPGetListResponse GetList(SPGetListRequest request)
        {
            SPGetListResponse response = new SPGetListResponse();
            XmlNode xnContentTypes = null;
            XmlNode xnList = null;
            SPList list = new SPList(request.WebUri) { ContentTypes = new Dictionary<string, SPContentType>() };

            using (Lists spLists = CreateListService(request.WebUri, request.Credentials))
            {
                xnList = spLists.GetList(request.ListIdOrName);

                list.Id = xnList.Attributes["ID"].Value;
                list.DisplayName = xnList.Attributes["Title"].Value;
                list.WebUri = xnList.Attributes["WebFullUrl"].Value.Trim('/');
                list.RootFolder = xnList.Attributes["RootFolder"].Value.Trim('/');
                list.Description = xnList.Attributes["Description"].Value;
                list.Version = xnList.Attributes["Version"].Value;
                list.DefaultViewUri = xnList.Attributes["DefaultViewUrl"].Value.Trim('/');
                list.BaseType = (SPListBaseType)int.Parse(xnList.Attributes["BaseType"].Value);
                list.AllowDeletion = bool.Parse(xnList.Attributes["AllowDeletion"].Value);
                list.WebId = xnList.Attributes["WebId"].Value;
                list.EnableAttachments = bool.Parse(xnList.Attributes["EnableAttachments"].Value);
                list.EnableModeration = bool.Parse(xnList.Attributes["EnableModeration"].Value);
                list.EnableVersioning = bool.Parse(xnList.Attributes["EnableVersioning"].Value);
                list.Hidden = bool.Parse(xnList.Attributes["Hidden"].Value);
                list.AllowDeletion = bool.Parse(xnList.Attributes["AllowDeletion"].Value);
                list.ShowUser = bool.Parse(xnList.Attributes["ShowUser"].Value);
                list.RequireCheckout = bool.Parse(xnList.Attributes["RequireCheckout"].Value);
                list.ItemCount = int.Parse(xnList.Attributes["ItemCount"].Value);
                list.ServerTemplate = (SPListServerTemplate)int.Parse(xnList.Attributes["ServerTemplate"].Value);
                list.Modified = DateTime.ParseExact(xnList.Attributes["Modified"].Value, "yyyyMMdd HH:ss:mm", CultureInfo.CurrentCulture.DateTimeFormat);
                list.Created = DateTime.ParseExact(xnList.Attributes["Created"].Value, "yyyyMMdd HH:ss:mm", CultureInfo.CurrentCulture.DateTimeFormat);

                xnContentTypes = spLists.GetListContentTypes(list.Id, "");
                foreach (XmlNode xnContentType in xnContentTypes.ChildNodes)
                {
                    XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable());
                    xnm.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");

                    SPContentType ct = new SPContentType(list);
                    XmlNode contentType = null;

                    ct.Id = xnContentType.Attributes["ID"].Value;
                    ct.Name = ct.DisplayName = xnContentType.Attributes["Name"].Value;
                    ct.Description = xnContentType.Attributes["Description"].Value;
                    ct.Version = xnContentType.Attributes["Version"].Value;
                    ct.Scope = xnContentType.Attributes["Scope"].Value;

                    contentType = spLists.GetListContentType(list.Id, ct.Id);

                    XmlAttribute xaGroup = contentType.Attributes["Group"];
                    if (xaGroup == null ||
                        xaGroup.Value.Equals("Folder Content Types") ||
                        xaGroup.Value.Equals("_Hidden"))
                        continue;
                    else
                        ct.Group = xaGroup.Value;

                    ct.Columns = ConvertColumns(ct, contentType.SelectNodes("/sp:Fields/sp:Field", xnm), xnm);

                    list.ContentTypes.Add(new KeyValuePair<string, SPContentType>(ct.Id, ct));
                }
            }

            response.List = list;
            return response;
        }

        private void GetListThreaded(Object stateInfo)
        {
            ListRequest lr = (ListRequest)stateInfo;

            //Set Initial list incase an exception is thrown
            SPList list = new SPList(lr.RepositoryRequest.Uri) { ContentTypes = new Dictionary<string, SPContentType>() };
            list.Id = lr.ListId;

            try
            {
                SPGetListRequest listRequest = new SPGetListRequest();
                listRequest.WebUri = lr.RepositoryRequest.Uri;
                listRequest.ListIdOrName = lr.ListId;
                listRequest.Credentials = lr.RepositoryRequest.Credentials;

                SPGetListResponse response = GetList(listRequest);
                list = response.List;
            }
            catch (Exception ex)
            {
                try
                {
                    lr.Lock.AcquireWriterLock(Timeout.Infinite);
                    lr.ExceptionInfo.Exception = ex;
                }
                finally
                {
                    if (lr.Lock.IsWriterLockHeld)
                        lr.Lock.ReleaseWriterLock();
                }
                return;
            }

            try
            {
                lr.Lock.AcquireWriterLock(Timeout.Infinite);
                //If an exception has occured on another thread then don't modify anything
                if(lr.ExceptionInfo.Exception == null)
                    lr.Lists.Add(list.Id, list);
            }
            finally
            {
                if(lr.Lock.IsWriterLockHeld)
                    lr.Lock.ReleaseWriterLock();
            }
        }

        private IDictionary<string, SPColumn> ConvertColumns(SPContentType contentType, XmlNodeList xnlColumns, XmlNamespaceManager xnm)
        {
            Dictionary<string, SPColumn> columns = new Dictionary<string, SPColumn>();
            XmlAttribute xa = null;
            foreach (XmlNode xnColumn in xnlColumns)
            {
                SPColumn column = new SPColumn(contentType);
                column.Id = xnColumn.Attributes["ID"].Value;
                column.Name = xnColumn.Attributes["Name"].Value;
                column.RpcName = GetRpcName(column.Name);

                xa = xnColumn.Attributes["DisplayName"];
                if (xa != null)
                    column.DisplayName = xa.Value;
                else
                    column.DisplayName = column.Name;
                try
                {
                    column.DataType = (SPColumnType)Enum.Parse(typeof(SPColumnType), xnColumn.Attributes["Type"].Value);
                }
                catch(Exception ex)//Unknown Type
                {
                    column.DataType = SPColumnType.Custom;
                    Trace.Write(ex.ToString(), "Mullivan.SharePoint");
                }

                xa = xnColumn.Attributes["Required"];
                if (xa != null)
                    column.IsRequired = bool.Parse(xa.Value);
                xa = xnColumn.Attributes["Description"];
                if (xa != null)
                    column.Description = xa.Value;
                xa = xnColumn.Attributes["ReadOnly"];
                if (xa != null)
                    column.IsReadOnly = bool.Parse(xa.Value);
                xa = xnColumn.Attributes["Min"];
                if (xa != null)
                    column.MinimumValue = double.Parse(xa.Value);
                xa = xnColumn.Attributes["Max"];
                if (xa != null)
                    column.MaximumValue = double.Parse(xa.Value);
                xa = xnColumn.Attributes["MaxLength"];
                if (xa != null)
                    column.MaxLength = int.Parse(xa.Value);
                else
                {
                    if(column.DataType == SPColumnType.Text)
                        column.MaxLength = 255;
                }
                xa = xnColumn.Attributes["NumLines"];
                if (xa != null)
                    column.NumberOfLines = int.Parse(xa.Value);
                xa = xnColumn.Attributes["Decimals"];
                if (xa != null)
                    column.DecimalPlaces = int.Parse(xa.Value);
                xa = xnColumn.Attributes["Percentage"];
                if (xa != null)
                    column.IsPercentage = bool.Parse(xa.Value);
                xa = xnColumn.Attributes["FillInChoice"];
                if (xa != null)
                    column.AllowFillIns = bool.Parse(xa.Value);
                xa = xnColumn.Attributes["Format"];
                if (xa != null)
                    column.DisplayFormat = xa.Value;

                if (column.DataType == SPColumnType.Lookup)
                {
                    SPLookupInfo lInfo = new SPLookupInfo(column);

                    xa = xnColumn.Attributes["List"];
                    if (xa != null)
                        lInfo.List = xa.Value;
                    xa = xnColumn.Attributes["ShowField"];
                    if (xa != null)
                        lInfo.DisplayField = xa.Value;

                    if (lInfo.List.Equals("Self"))
                        lInfo.List = column.ContentType.List.Id;

                    column.LookupInfo = lInfo;
                }

                XmlNode xnDefault = xnColumn.SelectSingleNode("sp:Default", xnm);
                if (xnDefault != null)
                    column.DefaultValue = xnDefault.InnerXml;

                XmlNodeList xnlChoices = xnColumn.SelectNodes("sp:CHOICES/sp:CHOICE", xnm);
                if (xnlChoices != null && xnlChoices.Count > 0)
                {
                    column.Choices = new List<string>();
                    foreach (XmlNode xnChoice in xnlChoices)
                        column.Choices.Add(xnChoice.InnerXml);
                }

                columns.Add(column.Id, column);
            }

            return columns;
        }

        private string GetRpcName(string name)
        {
            if (name.Equals("Title"))
                return "vti_title";
            if (name.Equals("Modified"))
                return "vti_modified";
            if (name.Equals("Modified_x0020_By"))
                return "vti_modifiedby";
            if (name.Equals("Created"))
                return "vti_timecreated";
            if (name.Equals("Created_x0020_By"))
                return "vti_author";

            Match match = null;
            while ((match = Regex.Match(name, @"_x[A-Fa-f0-9]{4}_")).Success)
            {
                string value = match.Value.Trim('_').TrimStart('x');

                int i = int.Parse(value, NumberStyles.AllowHexSpecifier);
                value = ((char)i).ToString();
                name = name.Replace(match.Value, value);
            }

            return name;
        }

        private Lists CreateListService(string uri, NetworkCredential creds)
        {
            Lists spLists = new Lists();
            spLists.Url = uri.TrimEnd('/') + "/_vti_bin/lists.asmx";
            spLists.Credentials = creds;
            spLists.UseDefaultCredentials = (creds == null);
            return spLists;
        }

        private SiteData CreateSiteDataService(string uri, NetworkCredential creds)
        {
            SiteData spSiteData = new SiteData();
            spSiteData.Url = uri.TrimEnd('/') + "/_vti_bin/sitedata.asmx";
            spSiteData.Credentials = creds;
            spSiteData.UseDefaultCredentials = (creds == null);
            return spSiteData;
        }
    }

    internal class ListRequest
    {
        public SPRepositoryRequest RepositoryRequest
        {
            get;
            set;
        }

        public string ListId
        {
            get;
            set;
        }

        public XmlNode ListNode
        {
            get;
            set;
        }

        public Dictionary<string, SPList> Lists
        {
            get;
            set;
        }

        public ReaderWriterLock Lock
        {
            get;
            set;
        }

        public ExceptionInfo ExceptionInfo
        {
            get;
            set;
        }
    }

    internal class ExceptionInfo
    {
        public Exception Exception
        {
            get;
            set;
        }

        public string ListName
        { get; set; }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions