using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using System.Diagnostics;
using System.Net;
using System.Collections.Specialized;
using System.Data;
using System.Configuration;
using System.Web;
using System.Runtime.Serialization;
using System.IO;
using System.Text;
using System.Xml;
using System.Security.Cryptography;
namespace UCOP.Custom.RPACEventReceiver.MemoEventReceiver
{
/// <summary>
/// Document Library Item Events
/// </summary>
public class MemoEventReceiver : SPItemEventReceiver
{
public static string DRAFT_MEMOS_LIBRARY_TITLE = "Draft Memos";
public static string PUBLISHED_MEMOS_LIBRARY_TITLE = "Published Memos";
/// <summary>
/// An item was added. Specifically for when the memo set is initially created. This calls the same code in ItemUpdated.
/// Note: Since this was added later I had to turn the feature off and then on again for it to register this new event receiver
/// </summary>
public override void ItemAdded(SPItemEventProperties properties)
{
this.ItemUpdated(properties);
base.ItemAdded(properties);
}
/// <summary>
/// An item was updated. Most of the code is here.
/// </summary>
public override void ItemUpdated(SPItemEventProperties properties)
{
//check to see if this is the correct document library
if (properties.ListTitle.Equals(DRAFT_MEMOS_LIBRARY_TITLE) || properties.ListTitle.Equals(PUBLISHED_MEMOS_LIBRARY_TITLE))
{
try
{
properties.ListItem["SharePoint_x0020_ID"] = properties.ListItem["ID"];
//create the md5 hash
//only if it has a file do we put the hash. if it has no file then it's probably a memo set
if (properties.ListItem.File != null)
{
SPFile spfile = properties.ListItem.File;
Stream fileStream = spfile.OpenBinaryStream();
MD5 md5Hash = MD5.Create();
string hash = GetMd5Hash(md5Hash, fileStream);
//add file hash and id to item
properties.ListItem["File_x0020_Hash"] = hash;
properties.ListItem.SystemUpdate();
}
//get a reference to the item from the properties
SPListItem selectItem = properties.ListItem;
//do the following for memo sets only
if (selectItem["Content Type"].Equals("Memo Set"))
{
//loop through all the files in the memo set and increment the count
int memoCount = 0;
foreach (SPFile file in selectItem.Folder.Files)
{
if (file.ListItemAllFields["Content Type"].Equals("Guidance Memo"))
memoCount++;
}
//get a hook to the web and the warning list
SPWeb web = properties.Web;
SPList warningList = web.Lists["Guidance Memo Warnings"];
//todo: loop through all the listitems in the list and delete any with Memo Set == selectItem.Title
try
{
string memoID = (string)selectItem["Memo ID"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name = \"Document_x0020_Set\"/>" +
"<Value Type = \"Lookup\">" + memoID + "</Value></Eq></Where>";
//get the items in the warning list that have to do with the memo set
SPListItemCollection items = warningList.GetItems(query);
//create an array for deleting the items since you can't delete when iterating the collection
SPListItem[] itemsToDelete = new SPListItem[items.Count];
int i = 0;
foreach (SPListItem item in items)
{
itemsToDelete[i]=(item);
i++;
}
//for all the items to delete loop through the array and delete them
foreach(SPListItem itemToDelete in itemsToDelete){
if (itemToDelete != null)itemToDelete.Delete();
}
}
catch (Exception errorDeleting) { }
//if the memoCount is greater than 1 add a listitem to the list
if (memoCount > 1)
{
SPListItem warningItem = warningList.AddItem();
//since this is a lookup have to use a special object
warningItem["Document Set"] = new SPFieldLookupValue(selectItem.ID, selectItem.Title);
warningItem["Title"] = "There are more memos than one";
warningItem.Update();
}
//if the memoCount is 0 then add a list item to the list
if (memoCount == 0)
{
SPListItem warningItem = warningList.AddItem();
//since this is a lookup have to use a special object
warningItem["Document Set"] = new SPFieldLookupValue(selectItem.ID, selectItem.Title);
warningItem["Title"] = "There are no memos in the memo set";
warningItem.Update();
}
}
else //the item is a file in the memo set
{
//so find the memo set and trigger an update
string memoID = (string)selectItem["Memo ID"];
//get a hook to the publishing library
SPList list = selectItem.ParentList;
//query the list for the memo id
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name = \"Title\"/>" +
"<Value Type = \"Text\">"+memoID+"</Value></Eq></Where>";
//get a list of memo sets that match, should be only one
SPListItemCollection myItems = list.GetItems(query);
for (int i = 0; i < myItems.Count; i++)
{
SPListItem item = myItems[i];
//trigger the event handler for the parent memo set
item.SystemUpdate();
}
}
}
catch (Exception cantUpdateListItem)
{
}
}
base.ItemUpdated(properties);
}
static string GetMd5Hash(MD5 md5Hash, Stream fileStream)
{
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hash.ComputeHash(fileStream);
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
}
}