AcUtils
A high performance abstraction layer for AccuRev
Stat.cs
Go to the documentation of this file.
1 
16 using System;
17 using System.Collections.Generic;
18 using System.Diagnostics;
19 using System.Globalization;
20 using System.Linq;
21 using System.Xml.Linq;
22 
23 namespace AcUtils
24 {
26 
35  public enum ElementType {
38  unknown = 0,
41  dir = 1,
44  text = 2,
47  binary = 3,
50  ptext = 4,
53  elink = 5,
56  slink = 6,
59  unsupported = 99
60  };
61 
65  [Serializable]
66  [DebuggerDisplay("{EID} {Location} {Status} {NamedVersion}")]
67  public sealed class Element : IFormattable, IEquatable<Element>, IComparable<Element>, IComparable
68  {
69  #region class variables
70  private string _location;
71  private bool _folder;
72  private bool _executable;
73  private int _eid;
74  private ElementType _elementType;
75  private long? _size;
76  private DateTime? _modTime;
77  private string _hierType;
78  private int _virStreamNumber;
79  private int _virVersionNumber;
80  private string _namedVersion; // named stream\version number format, e.g. MARS_STAGE\7 or MARS_STAGE_barnyrd\24
81  private int _realStreamNumber;
82  private int _realVersionNumber;
83  private string _lapStream;
84  // AccuRev tech support, overlapInWs "was put in place for a feature that was started
85  // and then shelved and may be removed in a future release. Currently it is always true."
86  // private bool _overlapInWs;
87  private string _timeBasedStream;
88  private string _status;
89  #endregion
90 
91  #region Equality comparison
92 
94  public bool Equals(Element other)
100  {
101  if (ReferenceEquals(other, null)) return false;
102  if (ReferenceEquals(this, other)) return true;
104  var right = Tuple.Create(other.EID, other.VirStreamNumber, other.VirVersionNumber,
105  other.RealStreamNumber, other.RealVersionNumber, other.NamedVersion);
106  return left.Equals(right);
107  }
108 
113  public override bool Equals(object other)
114  {
115  if (ReferenceEquals(other, null)) return false;
116  if (ReferenceEquals(this, other)) return true;
117  if (GetType() != other.GetType()) return false;
118  return Equals(other as Element);
119  }
120 
126  public override int GetHashCode()
127  {
129  return hash.GetHashCode();
130  }
132  #endregion
133 
134  #region Order comparison
135 
137  public int CompareTo(Element other)
144  {
145  int result;
146  if (Element.ReferenceEquals(this, other))
147  result = 0;
148  else
149  result = Location.CompareTo(other.Location);
150 
151  return result;
152  }
153 
160  int IComparable.CompareTo(object other)
161  {
162  if (!(other is Element))
163  throw new ArgumentException("Argument is not an Element", "other");
164  Element o = (Element)other;
165  return this.CompareTo(o);
166  }
168  #endregion
169 
173  public string Location
174  {
175  get { return _location ?? String.Empty; }
176  internal set { _location = value; }
177  }
178 
182  public bool Folder
183  {
184  get { return _folder; }
185  internal set { _folder = value; }
186  }
187 
191 
192  public bool Executable
193  {
194  get { return _executable; }
195  internal set { _executable = value; }
196  }
197 
201  public int EID
202  {
203  get { return _eid; }
204  internal set { _eid = value; }
205  }
206 
210  public ElementType ElementType
211  {
212  get { return _elementType; }
213  internal set { _elementType = value; }
214  }
215 
219 
220  public long? Size
221  {
222  get { return _size; }
223  internal set { _size = value; }
224  }
225 
229  public DateTime? ModTime
230  {
231  get { return _modTime; }
232  internal set { _modTime = value; }
233  }
234 
238  public string HierType
239  {
240  get { return _hierType ?? String.Empty; }
241  internal set { _hierType = value; }
242  }
243 
247  public int VirStreamNumber
248  {
249  get { return _virStreamNumber; }
250  internal set { _virStreamNumber = value; }
251  }
252 
256  public int VirVersionNumber
257  {
258  get { return _virVersionNumber; }
259  internal set { _virVersionNumber = value; }
260  }
261 
265  public string NamedVersion
266  {
267  get { return _namedVersion ?? String.Empty; }
268  internal set { _namedVersion = value; }
269  }
270 
274  public int RealStreamNumber
275  {
276  get { return _realStreamNumber; }
277  internal set { _realStreamNumber = value; }
278  }
279 
283  public int RealVersionNumber
284  {
285  get { return _realVersionNumber; }
286  internal set { _realVersionNumber = value; }
287  }
288 
293 
294  public string LapStream
295  {
296  get { return _lapStream ?? String.Empty; }
297  internal set { _lapStream = value; }
298  }
299 
311 
312  public string TimeBasedStream
313  {
314  get { return _timeBasedStream ?? String.Empty; }
315  internal set { _timeBasedStream = value; }
316  }
317 
321  public string Status
322  {
323  get { return _status ?? String.Empty; }
324  internal set { _status = value; }
325  }
326 
327  #region ToString
328  public string ToString(string format, IFormatProvider provider)
353  {
354  if (provider != null)
355  {
356  ICustomFormatter fmt = provider.GetFormat(this.GetType()) as ICustomFormatter;
357  if (fmt != null)
358  return fmt.Format(format, this, provider);
359  }
360 
361  if (String.IsNullOrEmpty(format))
362  format = "G";
363 
364  switch (format.ToUpperInvariant())
365  {
366  case "LV": // long version (verbose)
367  {
368  if (_modTime != null)
369  return $"{Location}, {Status}{Environment.NewLine}" +
370  $"\tEID: {EID} {{{ElementType}}}, Size: {Size}, ModTime: {ModTime},{Environment.NewLine}" +
371  $"\t{NamedVersion}, Virtual: {VirStreamNumber}\\{VirVersionNumber}, Real: {RealStreamNumber}\\{RealVersionNumber}";
372  else
373  return $"{Location}, {Status}{Environment.NewLine}" +
374  $"\tEID: {EID} {{{ElementType}}}{Environment.NewLine}" +
375  $"\t{NamedVersion}, Virtual: {VirStreamNumber}\\{VirVersionNumber}, Real: {RealStreamNumber}\\{RealVersionNumber}";
376  }
377  case "G": // location, the depot-relative path of the element (default when not using a format specifier)
378  return Location;
379  case "F": // True if the element is a folder, False otherwise
380  return Folder.ToString();
381  case "E": // UNIX/Linux systems only: True if the executable bit is set, False if cleared
382  return Executable.ToString();
383  case "I": // element ID
384  return EID.ToString();
385  case "T": // element's type: dir, text, binary, ptext, elink, or slink
386  return ElementType.ToString();
387  case "FS": // file size in bytes
388  return (Size == null) ? String.Empty : Size.ToString();
389  case "MT": // element's modification time
390  return ModTime.ToString();
391  case "H": // hierarchy type: parallel or serial
392  return HierType;
393  case "V": // virtual stream\\version number designation, e.g. 5\12
394  return $"{VirStreamNumber}\\{VirVersionNumber}";
395  case "R": // real stream\\version number designation, e.g. 5\12
396  return $"{RealStreamNumber}\\{RealVersionNumber}";
397  case "N": // named stream\version number format, e.g. MARS_STAGE\7 or MARS_STAGE_barnyrd\24
398  return NamedVersion;
399  case "L": // stream where element is located when it has (\e underlap)(\e member) or (\e overlap)(\e member) status
400  return LapStream;
401  case "TB": // first time-based stream found when 'stat -s stream -o -B -fox' is used to retrieve elements with (overlap) and/or (underlap) status
402  return TimeBasedStream;
403  case "S": // version's status, e.g. (kept)(member)
404  return Status;
405  default:
406  throw new FormatException($"The {format} format string is not supported.");
407  }
408  }
409 
410  // Calls ToString(string, IFormatProvider) version with a null IFormatProvider argument.
411  public string ToString(string format)
412  {
413  return ToString(format, null);
414  }
415 
416  // Calls ToString(string, IFormatProvider) version with the general format and a null IFormatProvider argument.
417  public override string ToString()
418  {
419  return ToString("G", null);
420  }
421  #endregion ToString
422  }
423 
427 
446  [Serializable]
447  public static class Stat
448  {
449  #region class variables
450  private static List<Element> _elements = new List<Element>();
451  [NonSerialized] private static readonly object _locker = new object();
452  #endregion
453 
457  public static List<Element> Elements
458  {
459  get { return _elements; }
460  private set { _elements = value; }
461  }
462 
466  public static void clear()
467  {
468  _elements.Clear();
469  }
470 
479  public static bool init(string xml)
480  {
481  bool ret = false; // assume failure
482  try
483  {
484  XElement elements = XElement.Parse(xml);
485  IEnumerable<XElement> query = from e in elements.Elements("element")
486  where !e.Attribute("status").Value.Contains("no such elem")
487  select e;
488  foreach (XElement e in query)
489  {
490  Element element = new Element();
491  element.Status = (string)e.Attribute("status") ?? String.Empty;
492  element.Location = (string)e.Attribute("location") ?? String.Empty;
493  string dir = (string)e.Attribute("dir") ?? String.Empty;
494  element.Folder = String.Equals(dir, "yes");
495  string exe = (string)e.Attribute("executable") ?? String.Empty;
496  element.Executable = String.Equals(exe, "yes");
497  element.EID = (int?)e.Attribute("id") ?? 0;
498  element.ElementType = e.acxType("elemType");
499  element.Size = (long?)e.Attribute("size");
500  element.ModTime = e.acxTime("modTime");
501  element.HierType = (string)e.Attribute("hierType") ?? String.Empty;
502  int ival;
503  string vir = (string)e.Attribute("Virtual") ?? String.Empty;
504  if (!String.IsNullOrEmpty(vir))
505  {
506  string[] arrVir = vir.Split('\\');
507  if (Int32.TryParse(arrVir[0], NumberStyles.Integer, null, out ival))
508  element.VirStreamNumber = ival;
509  if (Int32.TryParse(arrVir[1], NumberStyles.Integer, null, out ival))
510  element.VirVersionNumber = ival;
511  }
512  element.NamedVersion = (string)e.Attribute("namedVersion") ?? String.Empty;
513  string real = (string)e.Attribute("Real") ?? String.Empty;
514  if (!String.IsNullOrEmpty(real))
515  {
516  string[] arrReal = real.Split('\\');
517  if (Int32.TryParse(arrReal[0], NumberStyles.Integer, null, out ival))
518  element.RealStreamNumber = ival;
519  if (Int32.TryParse(arrReal[1], NumberStyles.Integer, null, out ival))
520  element.RealVersionNumber = ival;
521  }
522  element.LapStream = (string)e.Attribute("overlapStream") ?? String.Empty;
523  element.TimeBasedStream = (string)e.Attribute("timeBasisStream") ?? String.Empty;
524  lock (_locker) { _elements.Add(element); }
525  }
526 
527  ret = true; // operation succeeded
528  }
529 
530  catch (Exception ecx)
531  {
532  AcDebug.Log($"Exception caught and logged in Stat.init{Environment.NewLine}{ecx.Message}");
533  }
534 
535  return ret;
536  }
537 
542 
545 
553  public static Element getElement(XElement version)
554  {
555  Debug.Assert(version.Name == "version", @"version.Name == ""version""");
556  int? virEID = (int?)version.Attribute("eid");
557  if (virEID == null) return null;
558 
559  int[] virStreamVersion = version.acxStreamVersion(RealVirtual.Virtual);
560  if (virStreamVersion == null) return null;
561  int[] realStreamVersion = version.acxStreamVersion(RealVirtual.Real);
562  if (realStreamVersion == null) return null;
563 
564  string virStream = version.acxStreamName(RealVirtual.Virtual);
565  if (virStream == null) return null;
566  string realStream = version.acxStreamName(RealVirtual.Real);
567  if (realStream == null) return null;
568 
569  IEnumerable<Element> query = from e in _elements
570  where e.EID == virEID &&
571  e.VirStreamNumber == virStreamVersion[0] && e.VirVersionNumber == virStreamVersion[1] &&
572  e.RealStreamNumber == realStreamVersion[0] && e.RealVersionNumber == realStreamVersion[1] &&
573  (e.NamedVersion.StartsWith(virStream) || e.NamedVersion.StartsWith(realStream))
574  select e;
575  return query.FirstOrDefault();
576  }
577  }
578 }
579 
static bool init(string xml)
Populate this list with elements from the XML emitted by the stat command.
Definition: Stat.cs:479
long Size
File size in bytes.
Definition: Stat.cs:221
ElementType ElementType
The element's type: dir, text, binary, ptext, elink, or slink.
Definition: Stat.cs:211
int RealStreamNumber
Real stream number.
Definition: Stat.cs:275
ElementType
Indicates the element's type. By default, AccuRev determines the element type for a newly created ver...
Definition: Stat.cs:35
static void clear()
Remove all elements from the (static) element's list.
Definition: Stat.cs:466
int EID
The element ID.
Definition: Stat.cs:202
override bool Equals(object other)
Overridden to determine equality.
Definition: Stat.cs:113
string HierType
"Hierarchy type" of the element: parallel or serial.
Definition: Stat.cs:239
string Status
The version's status, e.g. (kept)(member)
Definition: Stat.cs:322
string NamedVersion
Named stream\version number designation, e.g. MARS_MAINT3\17 or MARS_MAINT3_barnyrd\22 ...
Definition: Stat.cs:266
int CompareTo(Element other)
Generic IComparable implementation (default) for comparing Element objects to sort by element locatio...
Definition: Stat.cs:143
int VirVersionNumber
Virtual version number.
Definition: Stat.cs:257
bool Equals(Element other)
IEquatable implementation to determine the equality of instances of type Element.
Definition: Stat.cs:99
static void Log(string message, bool formatting=true)
Write the message text to STDOUT, to weekly log files located in %LOCALAPPDATA%\AcTools\Logs, and to trigger.log in the AccuRev server's ..storage\site_slice\logs folder in the case of triggers.
Definition: AcDebug.cs:378
int VirStreamNumber
Virtual stream number.
Definition: Stat.cs:248
string Location
Depot-relative path of the element.
Definition: Stat.cs:174
static Element getElement(XElement version)
Get the stat command's Element object from this list that corresponds to the version element in a tra...
Definition: Stat.cs:553
DateTime ModTime
The element's modification time.
Definition: Stat.cs:230
Defines the attributes of an element from the stat command.
Definition: Stat.cs:67
int RealVersionNumber
Real version number.
Definition: Stat.cs:284
string TimeBasedStream
Name of the first time-based stream found when stat -s -o -B -fox is used to retrieve elemen...
Definition: Stat.cs:313
string LapStream
Stream where the element is located when it has (underlap)(member) or (overlap)(member) status...
Definition: Stat.cs:295
bool Folder
true if the element is a folder, false otherwise.
Definition: Stat.cs:183
Use to log and display error and general purpose text messages, and to save the XML param data sent b...
Definition: AcDebug.cs:100
bool Executable
UNIX/Linux systems only: true if the executable bit is set, false if cleared.
Definition: Stat.cs:193
RealVirtual
Use to specify real or virtual values.
Definition: Extensions.cs:30
string ToString(string format, IFormatProvider provider)
The ToString implementation.
Definition: Stat.cs:352
static List< Element > Elements
The list of Element objects.
Definition: Stat.cs:458
The list of Element objects from the stat command.
Definition: Stat.cs:447
override int GetHashCode()
Override appropriate for type Element.
Definition: Stat.cs:126