PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/source/BoldBrick.SharePoint.CommonControls/DataObjects/Base/BaseContentType.cs

#
C# | 302 lines | 188 code | 50 blank | 64 comment | 21 complexity | 0eba2df51a4aa546c54234d6a1fdf1e9 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using BoldBrick.Core.Logging;
  5. using BoldBrick.SharePoint.CommonControls.Extensions;
  6. using Microsoft.SharePoint;
  7. using Microsoft.SharePoint.Utilities;
  8. namespace BoldBrick.SharePoint.CommonControls.DataObjects.Base
  9. {
  10. /// <summary>
  11. /// Base metadata class for <see cref="SPContentType"/> object
  12. /// </summary>
  13. public abstract class BaseContentType : BaseDataObject
  14. {
  15. private static readonly ILogger log = Logger.GetLogger(typeof(BaseContentType));
  16. #region Properties
  17. private SPContentTypeId id = SPContentTypeId.Empty;
  18. /// <summary>
  19. /// ID (vector) of the content type
  20. /// </summary>
  21. public SPContentTypeId ID
  22. {
  23. get
  24. {
  25. if (id == SPContentTypeId.Empty)
  26. id = new SPContentTypeId(GetContentTypeID());
  27. return id;
  28. }
  29. }
  30. #endregion
  31. #region ------ Metadata Methods -----------------------------------------------------------
  32. /// <summary>
  33. /// Gets content type ID in string format
  34. /// </summary>
  35. /// <returns>Returns content type ID in string format</returns>
  36. protected abstract string GetContentTypeID();
  37. /// <summary>
  38. /// Gets name of the content type
  39. /// </summary>
  40. /// <param name="language">Language identifier</param>
  41. /// <returns></returns>
  42. public virtual string GetName(uint language)
  43. {
  44. string source = string.Format("$Resources: {0}", GetNameResourceKey());
  45. return SPUtility.GetLocalizedString(source, this.ResourceFileName, language);
  46. }
  47. /// <summary>
  48. /// Gets resource key for name of the content type
  49. /// </summary>
  50. /// <returns>Returns resource key for name of the content type</returns>
  51. protected virtual string GetNameResourceKey()
  52. {
  53. throw new NotImplementedException("Implement 'GetNameResourceKey' method in inherited class or override 'GetName' method.");
  54. }
  55. /// <summary>
  56. /// Gets group name of the content type
  57. /// </summary>
  58. /// <param name="language">Language identifier</param>
  59. /// <returns>Returns group name of the content type</returns>
  60. public virtual string GetGroupName(uint language)
  61. {
  62. string source = string.Format("$Resources: {0}", GetGroupResourceKey());
  63. return SPUtility.GetLocalizedString(source, this.ResourceFileName, language);
  64. }
  65. /// <summary>
  66. /// Gets resource key for group name of the content type
  67. /// </summary>
  68. /// <returns>Returns resource key for group name of the content type</returns>
  69. protected virtual string GetGroupResourceKey()
  70. {
  71. throw new NotImplementedException("Implement 'GetGroupResourceKey' method in inherited class or override 'GetGroupName' method.");
  72. }
  73. /// <summary>
  74. /// Gets description of the content type
  75. /// </summary>
  76. /// <param name="language">Language identifier</param>
  77. /// <returns>Returns description of the content type</returns>
  78. public virtual string GetDescription(uint language)
  79. {
  80. string nameResourceKey = GetDescriptionResourceKey();
  81. if (string.IsNullOrEmpty(nameResourceKey))
  82. return null;
  83. string source = string.Format("$Resources: {0}", nameResourceKey);
  84. return SPUtility.GetLocalizedString(source, this.ResourceFileName, language);
  85. }
  86. /// <summary>
  87. /// Gets resource key for description of the content type
  88. /// </summary>
  89. /// <returns>Returns resource key for description of the content type</returns>
  90. protected virtual string GetDescriptionResourceKey()
  91. {
  92. return null;
  93. }
  94. #endregion
  95. #region Create Methods
  96. /// <summary>
  97. /// Creates the content type in web. If content type if already created, updates content type properties
  98. /// </summary>
  99. /// <param name="web">Web of the content type</param>
  100. public void Create(SPWeb web)
  101. {
  102. string contentTypeName = this.GetName(web.Language);
  103. log.Write(LogLevel.Info, "Create '{0}' content type with '{1}' ID in '{1}' web.", contentTypeName, this.ID, web.ServerRelativeUrl);
  104. SPContentType contentType = web.GetContentType(this.ID);
  105. if (contentType == null)
  106. {
  107. web.AllowUnsafeUpdates = true;
  108. string name = GetName(web.Language);
  109. contentType = new SPContentType(this.ID, web.ContentTypes, name);
  110. web.ContentTypes.Add(contentType);
  111. }
  112. else
  113. {
  114. log.Write(LogLevel.Info, "'{0}' content type with '{1}' ID already exist in '{2}' web.", contentTypeName, this.ID, web.ServerRelativeUrl);
  115. }
  116. contentType.Group = GetGroupName(web.Language);
  117. string description = GetDescription(web.Language);
  118. if (description != null)
  119. {
  120. contentType.Description = description;
  121. }
  122. contentType.Update(true);
  123. web.Update();
  124. UpdateFieldLinks(web);
  125. }
  126. #endregion
  127. #region Columns Methods
  128. /// <summary>
  129. /// Gets list columns of the content type
  130. /// </summary>
  131. /// <returns>Returns list columns of the content type</returns>
  132. public virtual List<ListColumn> GetListColumns()
  133. {
  134. return new List<ListColumn>();
  135. }
  136. /// <summary>
  137. /// Gets ordered list columns of the content type (for display or edit forms)
  138. /// </summary>
  139. /// <returns>Returns ordered list columns of the content type (for display or edit forms)</returns>
  140. public virtual List<ListColumn> GetOrderedListColumns()
  141. {
  142. return GetListColumns();
  143. }
  144. /// <summary>
  145. /// Updates field links order based of <see cref="GetOrderedListColumns"/> method definition
  146. /// </summary>
  147. /// <param name="contentTypes">Parent collection of the content type</param>
  148. public void UpdateColumnOrder(SPContentTypeCollection contentTypes)
  149. {
  150. log.Write(LogLevel.Info, "Reordering fields in '{0}' content type.", this);
  151. string[] order = GetOrderedListColumns()
  152. .Select(column => column.InternalName)
  153. .ToArray();
  154. if (order.Length == 0)
  155. {
  156. log.Write(LogLevel.Warn, "No columns in defintion for reordering fields in '{0}' content type.", this);
  157. return;
  158. }
  159. SPContentType contentType = contentTypes
  160. .OfType<SPContentType>()
  161. .FirstOrDefault(cnt => cnt.Id.Equals(this.ID) || cnt.Id.IsChildOf(this.ID));
  162. if (contentType == null)
  163. {
  164. log.Write(LogLevel.Error, "'{0}' content type not found.", this);
  165. return;
  166. }
  167. contentType.FieldLinks.Reorder(order);
  168. contentType.Update(true);
  169. }
  170. /// <summary>
  171. /// Updates field links base on <see cref="GetListColumns"/> method definition
  172. /// </summary>
  173. /// <param name="web">Parent web of the content type</param>
  174. public void UpdateFieldLinks(SPWeb web)
  175. {
  176. string contentTypeName = GetName(web.Language);
  177. log.Write(LogLevel.Info, "Update field link for '{0}' content type in '{1}' web.", contentTypeName, web.ServerRelativeUrl);
  178. SPContentType contentType = web.GetContentType(contentTypeName);
  179. if (contentType == null)
  180. {
  181. string message = string.Format("'{0}' content type does not exist in '{1}' web.",
  182. contentTypeName,
  183. web.ServerRelativeUrl);
  184. log.Write(LogLevel.Error, message);
  185. throw new Exception(message);
  186. }
  187. web.AllowUnsafeUpdates = true;
  188. IEnumerable<ListColumn> listColumns = this.GetListColumns();
  189. foreach (ListColumn listColumn in listColumns)
  190. {
  191. log.Write(LogLevel.Info, "Try to add '{0}' field link to '{1}' content type in '{2}' web.", listColumn.InternalName, contentTypeName, web.ServerRelativeUrl);
  192. SPField field = web.AvailableFields.GetFieldByInternalName(listColumn.InternalName);
  193. if (field == null)
  194. {
  195. string message = string.Format("'{0}' field does not exist in '{1}' web.",
  196. listColumn.InternalName,
  197. web.ServerRelativeUrl);
  198. log.Write(LogLevel.Error, message);
  199. throw new Exception(message);
  200. }
  201. SPFieldLink fieldLink = contentType.GetFieldLink(listColumn.InternalName);
  202. bool updated = false;
  203. if (fieldLink == null)
  204. {
  205. contentType.AddFieldLink(field);
  206. updated = true;
  207. fieldLink = contentType.GetFieldLink(listColumn.InternalName);
  208. log.Write(LogLevel.Info, "'{0}' field link is successfully added to '{1}' content type in '{2}' web.",
  209. listColumn.InternalName,
  210. contentTypeName,
  211. web.ServerRelativeUrl);
  212. }
  213. else
  214. {
  215. log.Write(LogLevel.Info, "'{0}' field link is already added to '{1}' content type in '{2}' web.",
  216. listColumn.InternalName,
  217. contentTypeName,
  218. web.ServerRelativeUrl);
  219. }
  220. updated |= UpdateFieldLink(fieldLink, listColumn, web.Language);
  221. if (updated)
  222. {
  223. contentType.Update(true);
  224. }
  225. }
  226. }
  227. /// <summary>
  228. /// Updates field link of this content type
  229. /// </summary>
  230. /// <param name="fieldLink">Field link to update</param>
  231. /// <param name="listColumn"><see cref="ListColumn"/> metadata object with properties</param>
  232. /// <param name="language">Language identifier</param>
  233. /// <returns>Returns true if field link is updated, otherwise returns false</returns>
  234. private static bool UpdateFieldLink(SPFieldLink fieldLink, ListColumn listColumn, uint language)
  235. {
  236. bool updated = false;
  237. string displayName = listColumn.GetDisplayName(language);
  238. if (fieldLink.DisplayName != displayName)
  239. {
  240. fieldLink.DisplayName = displayName;
  241. updated = true;
  242. }
  243. return updated;
  244. }
  245. #endregion
  246. public override string ToString()
  247. {
  248. string name = GetName(1033);
  249. return string.Format("{0} ({1})", name, this.ID);
  250. }
  251. }
  252. }