PageRenderTime 50ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Raven.Studio/Features/Documents/ViewableDocument.cs

http://github.com/ayende/ravendb
C# | 254 lines | 212 code | 41 blank | 1 comment | 19 complexity | e20b565d1d0858005e176a7b695d0820 MD5 | raw file
Possible License(s): GPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, Apache-2.0, BSD-3-Clause, CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reactive.Linq;
  4. using System.Threading.Tasks;
  5. using System.Windows.Input;
  6. using System.Windows.Media;
  7. using Raven.Imports.Newtonsoft.Json;
  8. using Raven.Imports.Newtonsoft.Json.Linq;
  9. using Raven.Abstractions.Data;
  10. using Raven.Json.Linq;
  11. using Raven.Studio.Framework;
  12. using Raven.Studio.Infrastructure;
  13. using System.Linq;
  14. using Raven.Studio.Models;
  15. namespace Raven.Studio.Features.Documents
  16. {
  17. public class FriendlyDocument
  18. {
  19. public string Id { get; set; }
  20. public List<string> NeighborsIds { get; set; }
  21. public bool IsProjection { get; set; }
  22. }
  23. public class ViewableDocument : ViewModel
  24. {
  25. private const double CharacterWidth = 7;
  26. private const double LineHeight = 5;
  27. private readonly JsonDocument inner;
  28. private string id;
  29. private string clrType;
  30. private string collectionType;
  31. public ViewableDocument(JsonDocument inner)
  32. {
  33. this.inner = inner;
  34. Id = inner.Metadata.IfPresent<string>("@id");
  35. LastModified = inner.LastModified ?? DateTime.MinValue;
  36. ClrType = inner.Metadata.IfPresent<string>(Constants.RavenClrType);
  37. CollectionType = DetermineCollectionType(inner.Metadata);
  38. }
  39. private Brush fill;
  40. public Brush Fill
  41. {
  42. get { return fill ?? (fill = TemplateColorProvider.Instance.ColorFrom(CollectionType)); }
  43. }
  44. public ICommand Edit
  45. {
  46. get { return new EditDocumentCommand(this); }
  47. }
  48. private string toolTipText;
  49. public string ToolTipText
  50. {
  51. get
  52. {
  53. return DocumentSize.Current.DisplayStyle == DocumentDisplayStyle.IdOnly
  54. ? null
  55. : toolTipText ?? (toolTipText = ShortViewOfJson.GetContentTrimmedToDimensions(inner.DataAsJson, 60, 70));
  56. }
  57. }
  58. private string trimmedDocumentView;
  59. public string TrimmedDocumentView
  60. {
  61. get
  62. {
  63. if (trimmedDocumentViewNeedsRecalculation)
  64. {
  65. trimmedDocumentViewNeedsRecalculation = false;
  66. ProduceTrimmedDocumentView();
  67. }
  68. return DocumentSize.Current.DisplayStyle == DocumentDisplayStyle.IdOnly ? null : trimmedDocumentView;
  69. }
  70. private set
  71. {
  72. trimmedDocumentView = value;
  73. OnPropertyChanged(() => TrimmedDocumentView);
  74. }
  75. }
  76. private void ProduceTrimmedDocumentView()
  77. {
  78. if (DocumentSize.Current.DisplayStyle == DocumentDisplayStyle.IdOnly)
  79. return;
  80. var widthInCharacters = (int) (DocumentSize.Current.Width / CharacterWidth);
  81. var heightInLines = (int) (DocumentSize.Current.Height / LineHeight);
  82. Task.Factory.StartNew(() => ShortViewOfJson.GetContentTrimmedToDimensions(inner.DataAsJson, widthInCharacters, heightInLines))
  83. .ContinueOnSuccessInTheUIThread(v => TrimmedDocumentView = v);
  84. }
  85. public string DisplayId
  86. {
  87. get
  88. {
  89. if (string.IsNullOrEmpty(Id))
  90. {
  91. // this is projection, try to find something meaningful.
  92. return GetMeaningfulDisplayIdForProjection();
  93. }
  94. var display = GetIdWithoutPrefixes();
  95. Guid guid;
  96. if (Guid.TryParse(display, out guid))
  97. display = display.Substring(0, 8);
  98. return display;
  99. }
  100. }
  101. private string GetMeaningfulDisplayIdForProjection()
  102. {
  103. var selectedProperty = new KeyValuePair<string, RavenJToken>();
  104. var propertyNames = new[] { "Id", "Name" };
  105. foreach (var propertyName in propertyNames)
  106. {
  107. selectedProperty = inner.DataAsJson.FirstOrDefault(x => x.Key.EndsWith(propertyName, StringComparison.OrdinalIgnoreCase));
  108. if (selectedProperty.Key != null)
  109. break;
  110. }
  111. if (selectedProperty.Key == null) // couldn't find anything, we will use the first one
  112. selectedProperty = inner.DataAsJson.FirstOrDefault();
  113. if (selectedProperty.Key == null) // there aren't any properties
  114. return "{}";
  115. var value = selectedProperty.Value.Type == JTokenType.String
  116. ? selectedProperty.Value.Value<string>()
  117. : selectedProperty.Value.ToString(Formatting.None);
  118. if (value.Length > 30)
  119. value = value.Substring(0, 27) + "...";
  120. return value;
  121. }
  122. private string GetIdWithoutPrefixes()
  123. {
  124. var display = Id;
  125. var prefixToRemoves = new[]
  126. {
  127. "Raven/",
  128. CollectionType + "/",
  129. CollectionType + "-"
  130. };
  131. foreach (var prefixToRemove in prefixToRemoves)
  132. {
  133. if (display.StartsWith(prefixToRemove, StringComparison.OrdinalIgnoreCase))
  134. display = display.Substring(prefixToRemove.Length);
  135. }
  136. return display;
  137. }
  138. public string CollectionType
  139. {
  140. get { return collectionType; }
  141. set
  142. {
  143. collectionType = value;
  144. OnPropertyChanged(() => CollectionType);
  145. }
  146. }
  147. public string ClrType
  148. {
  149. get { return clrType; }
  150. set
  151. {
  152. clrType = value;
  153. OnPropertyChanged(() => ClrType);
  154. }
  155. }
  156. private DateTime lastModified;
  157. private bool trimmedDocumentViewNeedsRecalculation;
  158. public DateTime LastModified
  159. {
  160. get { return lastModified; }
  161. set
  162. {
  163. lastModified = value;
  164. OnPropertyChanged(() => LastModified);
  165. }
  166. }
  167. public string Id
  168. {
  169. get { return id; }
  170. set
  171. {
  172. id = value;
  173. OnPropertyChanged(() => Id);
  174. }
  175. }
  176. public JsonDocument Document
  177. {
  178. get { return inner; }
  179. }
  180. public bool MetadataOnly
  181. {
  182. get { return Document.DataAsJson.Count == 0; }
  183. }
  184. public override string ToString()
  185. {
  186. return inner.DataAsJson.ToString();
  187. }
  188. public static string DetermineCollectionType(RavenJObject metadata)
  189. {
  190. var id = metadata.IfPresent<string>("@id") ?? string.Empty;
  191. if (string.IsNullOrEmpty(id))
  192. return "Projection"; // meaning that the document is a projection and not a 'real' document
  193. if (id.StartsWith("Raven/"))
  194. return "Sys Doc";
  195. var entity = metadata.IfPresent<string>(Constants.RavenEntityName);
  196. return entity ?? "Doc";
  197. }
  198. protected override void OnViewLoaded()
  199. {
  200. Observable.FromEventPattern<EventHandler, EventArgs>(e => DocumentSize.Current.SizeChanged += e, e => DocumentSize.Current.SizeChanged -= e)
  201. .Throttle(TimeSpan.FromSeconds(0.5))
  202. .TakeUntil(Unloaded)
  203. .ObserveOnDispatcher()
  204. .Subscribe(_ => InvalidateData());
  205. InvalidateData();
  206. }
  207. private void InvalidateData()
  208. {
  209. trimmedDocumentViewNeedsRecalculation = true;
  210. OnPropertyChanged(() => TrimmedDocumentView);
  211. }
  212. }
  213. }