Sunday, October 3, 2010

Making your SharePoint 2010 applications ECM aware (Part 5 – Hold and Discovery)

Well I thought I had completed this series a month ago. However, when doing more research into the new features of SP2010, I discovered the “Hold and Discovery” site feature. This is a new and interesting feature in SP2010 and should be part of any ECM solution. My last post talked about the KnowledgeLake Viewer and stressed the importance of having the right tools to manage an “eDiscovery” process. In the last ten years “eDiiscovery” has become more important with many companies dealing with litigation. Courts can require companies to search and discover evidence within electronic documents. It is the responsibility of the company to put these documents on “hold”. “Holding” a document basically locks the document, preventing it from being edited, moved, checked out, or deleted. It is very similar to declaring a document as a record. Records and Holds are just about the same, except records can have different types of restrictions applied to them, for example, a record can be edited but not deleted. Also, it is easier to release holds than it is to un-declare documents as records. Declaring a record is more permanent, whereas, holding document by its nature is temporary.

A great blog post about the “Hold and Discover” feature in SP2010 describes the process.

Microsoft Enterprise Content Management Team Blog

SharePoint’s has expanded its “eDiscovery” capabilities in 2010, while it is now easier to search and manage documents to hold, there is still room for solution architects to enhance this feature. For instance, it would be nice to be able to put a whole document set on hold with one menu click. Possibly a new event handler could be added so that any new documents added to a document set are automatically put on hold. The discovery process could be substantially improved by providing better solutions for searching for documents, compared to the limited keyword searching currently available. For example,leveraging the richer FAST searching syntax to find documents . Another enhancement would be to enable record managers to refine search results and put the refined results on hold using KnowledgeLake Search.

Putting a document on hold

In order to allow your application to put a document on  hold, you will need to allow users to select from the available hold definitions. A SharePoint site is subject to not only the holds defined in it own site, but also its parent site. So when presenting this to the user you must give them a drop down list of available holds. The code in this post uses the Microsoft.Office.Policy assembly located in the 14 hive\ISAPI folder and the Microsoft.Office.Policy.RecordsManagement.Holds.Hold static class.

The following code builds a list of SPListItems that represent the hold definitions available to the a site. This is needed because both the SPListItem you want to hold and the SPListItem representing the hold you want to associate it with are needed.

public static List<SPListItem> GetAvailableHolds(string url)
{

    List<SPListItem> holdListItems = new List<SPListItem>();
    List<SPList> holdList = null;

    using (SPSite site = new SPSite(url))
    {
        using (SPWeb web = site.OpenWeb())
        {
            holdList = Hold.GetApplicableHoldsLists(web);
        }

        foreach (SPList l  in holdList)
        {
            foreach (SPListItem i in l.Items)
            { holdListItems.Add(i); }
        }

    }

    return holdListItems;

}

It is very simple to put a document on hold. All you need is the SPListItem of the document and the SPListItem of the hold. You can also set a comment.

public static void PutOnHold(SPListItem item, SPListItem hold, string comments)
{
    Hold.SetHold(item, hold, comments);      
}

 

Releasing a document from a hold

Of course if your application can put a document on hold you will want to have the ability to remove the hold. Very simple, basically the same as putting a document on hold but a different method.

public static void RemoveFromHold(SPListItem item, SPListItem hold, string comments)
{
    Hold.RemoveHold(item, hold, comments);
}

Determine if a document is on hold

It is very easy to determine if a document is on hold.

public static bool IsOnHold(SPListItem item)
{
    return Hold.IsItemOnHold(item);
}

When a document is put on hold you will notice a lock icon next to the document icon displayed in the document library. Putting a document on hold or declaring it a record has an immediate effect. However, in the SharePoint UI you cannot tell whether the document is on hold, a record or both. You must select the “Compliance Details” context menu item to see the hold and record status of a document.

 

When a user clicks on one of these links, SharePoint internally sets a  bit field value of a built in field of the item. The bit field can be combined by using a bitwise OR operation so that the item can be both set as a hold or a record. The following code shows how this works.

public static void GetHoldRecordStatus(SPListItem item)
{
    bool record;
    bool hold;
    int result;

    try
    {
        object obj = item[Microsoft.SharePoint.Publishing.FieldId.HoldRecordStatus];

        if ((obj != null) && !int.TryParse(obj.ToString(), out result))
        {
            record = (result | 273) == 273;
            hold = (result | 4353) == 4353;
        }
    }
    catch (ArgumentException)
    {
        result = 0;
    }
}

 

The ability to hold and release documents is an essential feature that any ECM application should have. The Microsoft.Office.RecordsManagement.Holds.Hold class enables developer to accomplish this. This class has other methods to hold or release SPListItemCollections  which you can use in scenarios where batch holds are required. You cannot accomplish the same functionality with the Client Object Model. If you wish to call this code remotely you have to wrap the code within a web service deployed to the SharePoint farm.

I will be posting more about enhancing the identification process of “eDiscovery” in SP2010. This will take advantage of KnowledgeLake Search and Fast SharePoint Search.