using System;
using System.Collections.Generic;
using System.Data;
using System.Collections;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using CMS.Controls;
using CMS.EventLog;
using CMS.GlobalHelper;
using CMS.SettingsProvider;
using CMS.SharePoint.Imaging;
using CMS.SharePoint.Lists;
public partial class CMSWebParts_SharePoint_SharePointDataSource_files_SharePointDatasource : CMSBaseDataSource
{
#region "Public constants"
// SharePoint modes
public const string MODE_LIST_ITEMS = "listitems";
public const string MODE_SITE_LISTS = "sitelists";
public const string MODE_PICTURE_LIBRARIES = "piclibs";
public const string MODE_PICTURE_LIBRARY_ITEMS = "piclibitems";
#endregion
#region "Private variables"
private bool useBase64Encoding = false;
private bool retrieved = false;
private XmlNode camlData = null;
private object dataSource = null;
private bool? mHasData = null;
// Properties
private string mUsername;
private string mPassword;
private string mListName;
private string mSPServiceURL;
private bool mShowReturnedCAML;
private int mRowLimit;
private string mQuery;
private string mViewFields;
private bool mUseClassicDataset = true;
private string mFields;
private string mMode = MODE_LIST_ITEMS;
private string mItemIDField;
private string mSelectedItemFieldName = null;
private string mItemIDFieldType = "Text";
private bool? mIsSelected = null;
private string mErrorMessage = null;
private static Regex mSpecialCharsRegex = null;
#endregion
#region "Private properties"
///
/// Regex used for replacing special characters from Sharepoint xml.
///
private static Regex SpecialCharsRegex
{
get
{
if (mSpecialCharsRegex == null)
{
mSpecialCharsRegex = new Regex("(_x00[0-9a-z]{2}_)", RegexOptions.IgnoreCase);
}
return mSpecialCharsRegex;
}
}
#endregion
#region "Public properties"
///
/// Gets Datasource object.
///
public override object DataSource
{
get
{
object datasource = GetDataSource();
// If GetDataSource didn't cause retrieval, it was loaded from cache
if (!retrieved)
{
if (datasource != null)
{
ShowRawResponse(null);
mHasData = true;
}
// If null is in cache, try retrieve, could be error
else
{
datasource = GetDataSourceFromDB();
// New retrieval successful
if (datasource != null)
{
// Clear old cache item
ClearCache();
// Causes new dataset to be cached
datasource = GetDataSource();
}
}
}
return datasource;
}
}
///
/// Gets or sets the value that indicates whether current datasource contains selected item.
///
public override bool IsSelected
{
get
{
if (!mIsSelected.HasValue)
{
mIsSelected = ((Mode == MODE_LIST_ITEMS) && (QueryHelper.GetText(ItemIDField, null) != null));
}
return mIsSelected.Value;
}
set
{
mIsSelected = value;
}
}
///
/// Gets or sets value of username.
///
public string Username
{
get
{
return mUsername;
}
set
{
mUsername = value;
}
}
///
/// Gets or sets value of password.
///
public string Password
{
get
{
return mPassword;
}
set
{
mPassword = value;
}
}
///
/// Gets or sets value of SharePoint list name.
///
public string ListName
{
get
{
return mListName;
}
set
{
mListName = value;
}
}
///
/// Gets or sets URL of SharePoint service (Eg. Lists.asmx, Imaging.asmx).
///
public string SPServiceURL
{
get
{
return mSPServiceURL;
}
set
{
mSPServiceURL = value;
}
}
///
/// Enables or disables showing CAML on output.
///
public bool ShowReturnedCAML
{
get
{
return mShowReturnedCAML;
}
set
{
mShowReturnedCAML = value;
}
}
///
/// Gets or set the row limit.
///
public int RowLimit
{
get
{
return mRowLimit;
}
set
{
mRowLimit = value;
}
}
///
/// Gets or sets query to specify which document should be retrieved (like where condition).
///
public string Query
{
get
{
return mQuery;
}
set
{
mQuery = value;
}
}
///
/// Gets or sets document fields which should be retrieved.
///
public string ViewFields
{
get
{
return mViewFields;
}
set
{
mViewFields = value;
}
}
///
/// Enables or disables using of classic dataset as data source for ASCX transformation.
///
public bool UseClassicDataset
{
get
{
return mUseClassicDataset;
}
set
{
mUseClassicDataset = value;
}
}
///
/// Gets or sets fields which should be included in dataset
/// Note: Only if UseClassicDataset is enabled
///
public string Fields
{
get
{
return mFields;
}
set
{
mFields = value;
}
}
///
/// Gets or sets the mode which specifies what this webpart exactly do.
///
public string Mode
{
get
{
return mMode;
}
set
{
mMode = value;
}
}
///
/// Gets or sets query string key name. Presence of the key in query string indicates,
/// that some item should be selected. The item is determined by query string value.
///
public string ItemIDField
{
get
{
return mItemIDField;
}
set
{
mItemIDField = value;
}
}
///
/// Gets or sets the field name which is used for selecting item. Case sensitive!
///
public string SelectedItemFieldName
{
get
{
return mSelectedItemFieldName;
}
set
{
mSelectedItemFieldName = value;
}
}
///
/// Gets or sets the type of field for selecting item.
///
public string ItemIDFieldType
{
get
{
return mItemIDFieldType;
}
set
{
mItemIDFieldType = value;
}
}
///
/// Indicates whether datasource has some data = is not empty.
///
public bool HasData
{
get
{
if (!mHasData.HasValue)
{
// Get data records - value of mHasData is set
GetDataRecords(camlData);
}
return mHasData.Value;
}
}
///
/// Returns error message.
///
public string ErrorMessage
{
get
{
return mErrorMessage;
}
}
#endregion
#region "Data source"
///
/// Gets data from SharePoint.
///
/// Dataset or XmlNode as object
protected override object GetDataSourceFromDB()
{
// Mark loading was tried
retrieved = true;
object data = null;
try
{
// Check if URL address of web service is valid
if (!ValidationHelper.IsURL(SPServiceURL))
{
DisplayError(ResHelper.GetString("SharePoint.invalidURL"));
return null;
}
// Get SharePoint data and set datasource
data = GetSharePointData();
}
catch (Exception ex)
{
EventLogProvider ep = new EventLogProvider();
ep.LogEvent("SharePointDataSource", "GetSharePointData", ex);
}
return data;
}
#endregion
#region "SharePoint methods"
///
/// Retrieves data from SharePoint server using web services.
///
/// Dataset or XmlNode
protected object GetSharePointData()
{
#region "Prepare credentials for authentication"
ICredentials credentials = null;
// If there are data in username or password use it for authentication
if (String.IsNullOrEmpty(Username) && String.IsNullOrEmpty(Password))
{
credentials = SharePointFunctions.GetSharePointCredetials();
}
else
{
credentials = SharePointFunctions.GetSharePointCredetials(Username, Password, useBase64Encoding);
}
#endregion
#region "Retrieve SharePoint data"
string serviceURL = SPServiceURL;
// If not direct web service specified, determine web service URL by mode
if (!serviceURL.EndsWithCSafe(".asmx", true))
{
// Remove trailing slash
serviceURL = serviceURL.TrimEnd('/');
switch (Mode.ToLowerCSafe())
{
case MODE_LIST_ITEMS:
case MODE_SITE_LISTS:
serviceURL += "/_vti_bin/lists.asmx";
break;
case MODE_PICTURE_LIBRARIES:
case MODE_PICTURE_LIBRARY_ITEMS:
serviceURL += "/_vti_bin/imaging.asmx";
break;
}
}
// Query web service
try
{
Lists spLists;
Imaging spImaging;
switch (Mode.ToLowerCSafe())
{
// Load list items
case MODE_LIST_ITEMS:
// Instantiate Lists service
spLists = new Lists(serviceURL);
spLists.Credentials = credentials;
camlData = LoadListItems(spLists, ListName);
break;
// Load site lists
case MODE_SITE_LISTS:
// Instantiate Lists service
spLists = new Lists(serviceURL);
spLists.Credentials = credentials;
// Get all SharePoint lists
camlData = spLists.GetListCollection();
break;
// Load picture libraries
case MODE_PICTURE_LIBRARIES:
// Instantiate imaging service
spImaging = new Imaging(serviceURL);
spImaging.Credentials = credentials;
// Get picture libraries
camlData = spImaging.ListPictureLibrary();
break;
// Load picture library items
case MODE_PICTURE_LIBRARY_ITEMS:
// Instantiate imaging service
spImaging = new Imaging(serviceURL);
spImaging.Credentials = credentials;
// Show error if library name empty
if (String.IsNullOrEmpty(ListName))
{
DisplayError(ResHelper.GetString("SharePoint.picslibunspecified"));
break;
}
// Get pictures in libraries, directly (not in folder)
camlData = spImaging.GetListItems(ListName, null);
break;
}
}
catch (Exception ex)
{
DisplayError(ResHelper.GetString("sharepoint.erroradta") + ResHelper.Colon + " " + ex.Message);
}
// No data
if (camlData == null)
{
return null;
}
#endregion
#region "Prepare data"
// Use of XSLT transformation
if (!UseClassicDataset)
{
dataSource = camlData;
}
// Use of classic dataset
else
{
// Prepare dataset
DataSet ds = new DataSet();
// If datset fields are specified
if (!String.IsNullOrEmpty(Fields))
{
DataTable dt = ds.Tables.Add();
string[] fields = Fields.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string field in fields)
{
string currentField = field.Trim();
if (!string.IsNullOrEmpty(currentField))
{
try
{
dt.Columns.Add(field.Trim());
}
catch (DuplicateNameException)
{
mErrorMessage = ResHelper.GetString("sharepoint.duplicateField");
}
}
}
XmlNodeList records = GetDataRecords(camlData);
List fieldsCheck = new List();
fieldsCheck.AddRange(fields);
// Load items to dataset
foreach (XmlNode record in records)
{
DataRow dr = dt.NewRow();
// Add fields
foreach (string field in fields)
{
string currentField = field.Trim();
if (!string.IsNullOrEmpty(currentField))
{
XmlAttribute attr = record.Attributes[currentField];
if (attr != null)
{
dr[currentField] = attr.Value;
// At least one record has the field
fieldsCheck.Remove(field);
}
}
}
dt.Rows.Add(dr);
}
// None of retrieved records has fields
if (fieldsCheck.Count > 0)
{
DisplayError(String.Format(ResHelper.GetString("sharepoint.fieldnotFound"), fieldsCheck[0]));
return null;
}
// Set daatsource
dataSource = ds;
}
// No fields specified, use all fields
else
{
// Only if CAML contains data record, otherwise dataset would contain wrong values
if (HasData)
{
camlData.InnerXml = SpecialCharsRegex.Replace(camlData.InnerXml, "_");
XmlNodeReader rd = new XmlNodeReader(camlData);
ds.ReadXml(rd);
rd.Close();
switch (Mode.ToLowerCSafe())
{
// Use last datatable as datasource
case MODE_LIST_ITEMS:
dataSource = ds.Tables[ds.Tables.Count - 1].DefaultView;
break;
// Filter hidden lists in dataset
case MODE_SITE_LISTS:
// Dataset structure changes based on xml, try to use last data table
DataTable dt = ds.Tables[ds.Tables.Count - 1];
// Show only visible lists
dt.DefaultView.RowFilter = "Hidden = 'False'";
dataSource = dt.DefaultView;
break;
// Dateset with picture libraries
case MODE_PICTURE_LIBRARIES:
dataSource = ds.Tables[ds.Tables.Count - 1].DefaultView;
break;
// Dataset with pictures
case MODE_PICTURE_LIBRARY_ITEMS:
dataSource = ds.Tables[ds.Tables.Count - 1].DefaultView;
break;
}
}
}
}
#endregion
ShowRawResponse(camlData);
return dataSource;
}
///
/// Returns XmlNodeList with data records depending on retrieve mode.
///
/// SharePoint data
protected XmlNodeList GetDataRecords(XmlNode camlData)
{
XmlNodeList records = null;
if (camlData != null)
{
// Get items from CAML
XmlNamespaceManager nsmgr = new XmlNamespaceManager(camlData.OwnerDocument.NameTable);
nsmgr.AddNamespace("soap", "http://schemas.microsoft.com/sharepoint/soap/");
switch (Mode.ToLowerCSafe())
{
// Get records of list items
case MODE_LIST_ITEMS:
nsmgr.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
nsmgr.AddNamespace("z", "#RowsetSchema");
records = camlData.SelectNodes("/rs:data/z:row", nsmgr);
break;
// Get records of site lists, do not select hidden lists
case MODE_SITE_LISTS:
records = camlData.SelectNodes("/soap:List[@Hidden = 'False']", nsmgr);
break;
// Get records of picture libraries
case MODE_PICTURE_LIBRARIES:
// Define whatever prefix for default xml namespace
nsmgr.AddNamespace("lib", "http://schemas.microsoft.com/sharepoint/soap/ois/");
records = camlData.SelectNodes("/lib:Library", nsmgr);
break;
// Get records of pictures in library
case MODE_PICTURE_LIBRARY_ITEMS:
nsmgr.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
nsmgr.AddNamespace("z", "#RowsetSchema");
records = camlData.SelectNodes("/z:row", nsmgr);
break;
}
}
// Set has data flag
mHasData = ((records != null) && (records.Count > 0));
return records;
}
///
/// Queries SharePoint for list items.
///
/// List service proxy class instance
/// List name
/// CAML with list items
protected XmlNode LoadListItems(Lists listService, string listName)
{
// Get all SharePoint lists
XmlNode listCollectionCaml = listService.GetListCollection();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(listCollectionCaml.OwnerDocument.NameTable);
nsmgr.AddNamespace("soap", "http://schemas.microsoft.com/sharepoint/soap/");
// Check list with given name exists
XmlNodeList collections = listCollectionCaml.SelectNodes("/soap:List[@Title = '" + listName + "']", nsmgr);
// If specified list does not exists show error
if (collections.Count == 0)
{
DisplayError(ResHelper.GetString("SharePoint.listdoesnotexists"));
return null;
}
#region "Advanced options"
//XmlElement query = null;
XmlDocument viewFields = null;
XmlDocument query = null;
XmlDocument queryOptions = null;
// Specify search by query
if (!String.IsNullOrEmpty(Query))
{
//query = xmlOptions.CreateElement("Query");
//query.InnerXml = this.Query; //"0";
query = new XmlDocument();
query.LoadXml(Query);
}
// Select item
if (!String.IsNullOrEmpty(ItemIDField))
{
string queryValue = QueryHelper.GetText(ItemIDField, null);
if (queryValue != null)
{
IsSelected = true;
// Set field name from ItemIDField if not set
string fieldName = (String.IsNullOrEmpty(SelectedItemFieldName)) ? ItemIDField : SelectedItemFieldName;
// No query was set
if (query == null)
{
query = new XmlDocument();
}
// Get or create Query node
XmlNode queryNode = query.SelectSingleNode("Query");
if (queryNode == null)
{
queryNode = query.CreateNode(XmlNodeType.Element, "Query", null);
query.AppendChild(queryNode);
}
// Get or create Where node
XmlNode whereNode = queryNode.SelectSingleNode("Where");
if (whereNode == null)
{
whereNode = query.CreateNode(XmlNodeType.Element, "Where", null);
queryNode.AppendChild(whereNode);
}
// Prepare query for selecting item
string selectItem = String.Format("{2}", fieldName, ItemIDFieldType, queryValue);
// Incorporate with original query
if (!String.IsNullOrEmpty(whereNode.InnerXml))
{
selectItem = String.Format("{0}{1}", whereNode.InnerXml, selectItem);
}
// Update Where node
whereNode.InnerXml = selectItem;
}
}
// Specify which fields should be retrieved
if (!String.IsNullOrEmpty(ViewFields))
{
viewFields = new XmlDocument();
string xml = "";
string[] fields = ViewFields.Split(';');
foreach (string field in fields)
{
xml += string.Format("", field.Trim());
}
xml += "";
viewFields.LoadXml(xml);
}
//xmlDoc.CreateElement("QueryOptions");
//queryOptions.InnerXml = "";
// If set limit maximum count of rows
string rowLimit = (RowLimit > 0) ? RowLimit.ToString() : null;
#endregion
// Get documents in the list
XmlNode documentsXml = listService.GetListItems(ListName, null, query, viewFields, rowLimit, queryOptions, null);
return documentsXml;
}
///
/// Shows error with message.
///
/// Message
protected void DisplayError(string message)
{
Label lblError = new Label();
lblError.Text = message;
lblError.CssClass = "ErrorLabel";
Controls.Add(lblError);
}
///
/// Displays raw SharePoint(CAML) response or message about loading from cache.
/// Depends on ShowReturnedCAML property.
///
/// Raw response or null
protected void ShowRawResponse(XmlNode camlData)
{
// If enabled, show raw CAML = SharePoint response
if (ShowReturnedCAML)
{
ltlRawXml.Visible = true;
string value;
if (camlData != null)
{
value = HTMLHelper.HTMLEncode(HTMLHelper.ReformatHTML(camlData.InnerXml));
}
else
{
value = "loaded from cache";
}
ltlRawXml.Text = "" + value + "
";
}
}
#endregion
}