AcUtils
A high performance abstraction layer for AccuRev
AcStreams.cs
Go to the documentation of this file.
1 
16 using System;
17 using System.Collections.Generic;
18 using System.Diagnostics;
19 using System.Linq;
20 using System.Threading.Tasks;
21 using System.Xml.Linq;
22 
23 namespace AcUtils
24 {
25  #region enums
26 
27 
33  public enum StreamType {
36  unknown,
39  normal,
42  dynamic,
45  regular,
48  workspace,
51  snapshot,
54  passthru,
60  gated,
63  staging
64  };
66  #endregion
67 
72  [Serializable]
73  [DebuggerDisplay("{Name} ({ID}) {Type}, basis: {BasisName} ({BasisID})")]
74  public sealed class AcStream : IFormattable, IEquatable<AcStream>, IComparable<AcStream>, IComparable
75  {
76  #region class variables
77  private string _name; // stream name
78  private int _id; // stream ID number
79  private string _basisName; // basis stream name
80  private int _basisID; // basis stream ID number
81  private AcDepot _depot; // depot where the stream resides
82  private bool _isDynamic; // false in the case of workspace, snapshot and passthrough, true if normal
83  private StreamType _type; // unknown, normal, dynamic, regular, workspace, snapshot, passthru, passthrough, gated, staging
84  private DateTime? _time; // basis time; XML attribute "time" only exists for snapshot streams (creation date) or when a dynamic stream has a time basis
85  // note, the result of specifying 'As transaction #' in the GUI results in a time basis set on the stream
86  private DateTime _startTime; // stream's creation time or last time its name, time basis or state (remove, reactivate, reparent) changed
87  private bool _hidden; // hidden (removed) stream
88  private bool _hasDefaultGroup; // true if the stream has a default group
89  #endregion
90 
95  internal AcStream() { }
96 
97  #region Equality comparison
98 
100  public bool Equals(AcStream other)
107  {
108  if (ReferenceEquals(other, null)) return false;
109  if (ReferenceEquals(this, other)) return true;
110  var left = Tuple.Create(ID, Depot);
111  var right = Tuple.Create(other.ID, other.Depot);
112  return left.Equals(right);
113  }
114 
119  public override bool Equals(object other)
120  {
121  if (ReferenceEquals(other, null)) return false;
122  if (ReferenceEquals(this, other)) return true;
123  if (GetType() != other.GetType()) return false;
124  return this.Equals(other as AcStream);
125  }
126 
131  public override int GetHashCode()
132  {
133  var hash = Tuple.Create(ID, Depot);
134  return hash.GetHashCode();
135  }
137  #endregion
138 
139  #region Order comparison
140 
142 
148  public int CompareTo(AcStream other)
149  {
150  int result;
151  if (AcStream.ReferenceEquals(this, other))
152  result = 0;
153  else
154  result = String.Compare(Name, other.Name);
155 
156  return result;
157  }
158 
165  int IComparable.CompareTo(object other)
166  {
167  if (!(other is AcStream))
168  throw new ArgumentException("Argument is not an AcStream", "other");
169  AcStream o = (AcStream)other;
170  return this.CompareTo(o);
171  }
173  #endregion
174 
178  public string Name
179  {
180  get { return _name ?? String.Empty; }
181  internal set { _name = value; }
182  }
183 
187  public int ID
188  {
189  get { return _id; }
190  internal set { _id = value; }
191  }
192 
196  public string BasisName
197  {
198  get { return _basisName ?? String.Empty; }
199  internal set { _basisName = value; }
200  }
201 
205  public int BasisID
206  {
207  get { return _basisID; }
208  internal set { _basisID = value; }
209  }
210 
214  public AcDepot Depot
215  {
216  get { return _depot; }
217  internal set { _depot = value; }
218  }
219 
224  public bool IsDynamic
225  {
226  get { return _isDynamic; }
227  internal set { _isDynamic = value; }
228  }
229 
234  public StreamType Type
235  {
236  get { return _type; }
237  internal set { _type = value; }
238  }
239 
245 
247  public DateTime? Time
248  {
249  get { return _time; }
250  internal set { _time = value; }
251  }
252 
256  public DateTime StartTime
257  {
258  get { return _startTime; }
259  internal set { _startTime = value; }
260  }
261 
265  public bool Hidden
266  {
267  get { return _hidden; }
268  internal set { _hidden = value; }
269  }
270 
274  public bool HasDefaultGroup
275  {
276  get { return _hasDefaultGroup; }
277  internal set { _hasDefaultGroup = value; }
278  }
279 
285  {
286  AcStream basis = _depot.getBasis(_id);
287  return basis;
288  }
289 
290  #region ToString
291  public string ToString(string format, IFormatProvider provider)
312  {
313  if (provider != null)
314  {
315  ICustomFormatter fmt = provider.GetFormat(this.GetType()) as ICustomFormatter;
316  if (fmt != null)
317  return fmt.Format(format, this, provider);
318  }
319 
320  if (String.IsNullOrEmpty(format))
321  format = "G";
322 
323  switch (format.ToUpperInvariant())
324  {
325  case "G": // stream name; default when not using a format specifier
326  return Name; // general format should be short since it can be called by anything
327  case "LV": // long version (verbose)
328  return $"{Name} ({ID}) {{{Type}}} {Time}{Environment.NewLine}" +
329  $"Basis: {BasisName} ({BasisID}){Environment.NewLine}" +
330  $"Depot: {Depot}, Hidden: {Hidden}{(Hidden ? String.Empty : ", HasDefaultGroup: " + HasDefaultGroup)}";
331  case "I": // stream's ID number
332  return ID.ToString();
333  case "T": // type of stream: unknown, normal, dynamic, regular, workspace, snapshot, passthru, passthrough, gated, staging
334  return Type.ToString();
335  case "BT": // stream's time basis
336  return Time.ToString();
337  case "C": // stream's creation time or last time its name, time basis or state (remove, reactivate, reparent) changed
338  return StartTime.ToString();
339  case "BN": // basis stream name
340  return BasisName;
341  case "BI": // basis stream ID number
342  return BasisID.ToString();
343  case "D": // depot name
344  return Depot.ToString();
345  case "DY": // true if dynamic, false in the case of workspace, snapshot or passthrough
346  return IsDynamic.ToString();
347  case "H": // True if stream is hidden, False otherwise
348  return Hidden.ToString();
349  case "DG": // True if stream has a default group, False otherwise
350  return HasDefaultGroup.ToString();
351  default:
352  throw new FormatException($"The {format} format string is not supported.");
353  }
354  }
355 
356  // Calls ToString(string, IFormatProvider) version with a null IFormatProvider argument.
357  public string ToString(string format)
358  {
359  return ToString(format, null);
360  }
361 
362  // Calls ToString(string, IFormatProvider) version with the general format and a null IFormatProvider argument.
363  public override string ToString()
364  {
365  return ToString("G", null);
366  }
367  #endregion ToString
368  }
369 
374  [Serializable]
375  public sealed class AcStreams : List<AcStream>
376  {
377  #region class variables
378  private bool _dynamicOnly; // true if request is for dynamic streams only
379  private bool _includeHidden; // true if removed streams should be included
380  [NonSerialized] private readonly object _locker = new object();
381  #endregion
382 
383  #region object construction:
384 
386 
406  internal AcStreams(bool dynamicOnly, bool includeHidden)
407  {
408  _dynamicOnly = dynamicOnly;
409  _includeHidden = includeHidden;
410  }
411 
428 
435  internal async Task<bool> initAsync(AcDepot depot, string listfile = null)
436  {
437  bool ret = false; // assume failure
438  try
439  {
440  AcResult result = await AcCommand.runAsync($@"show {(_includeHidden ? "-fxig" : "-fxg")} -p ""{depot}""" +
441  $@"{((listfile == null) ? String.Empty : "-l " + "" + listfile + "")} streams")
442  .ConfigureAwait(false);
443  if (result != null && result.RetVal == 0)
444  {
445  XElement xml = XElement.Parse(result.CmdResult);
446  IEnumerable<XElement> filter = null;
447  if (_dynamicOnly)
448  filter = from s in xml.Elements("stream")
449  where (bool)s.Attribute("isDynamic") == true select s;
450  else
451  filter = from s in xml.Elements("stream") select s;
452 
453  foreach (XElement e in filter)
454  {
455  AcStream stream = new AcStream();
456  stream.Name = (string)e.Attribute("name");
457  stream.ID = (int)e.Attribute("streamNumber");
458  stream.BasisName = (string)e.Attribute("basis") ?? String.Empty;
459  stream.BasisID = (int?)e.Attribute("basisStreamNumber") ?? -1;
460  stream.Depot = depot;
461  stream.IsDynamic = (bool)e.Attribute("isDynamic");
462  string type = (string)e.Attribute("type");
463  stream.Type = (StreamType)Enum.Parse(typeof(StreamType), type);
464  // attribute "time" only exists for snapshot streams (creation date) or when a dynamic stream has a time basis
465  stream.Time = e.acxTime("time"); // time basis
466  stream.StartTime = (DateTime)e.acxTime("startTime");
467  // hidden attribute exists only if the stream is hidden
468  stream.Hidden = (e.Attribute("hidden") != null);
469  stream.HasDefaultGroup = (bool)e.Attribute("hasDefaultGroup");
470  lock (_locker) { Add(stream); }
471  }
472 
473  ret = true; // operation succeeded
474  }
475  }
476 
477  catch (AcUtilsException ecx)
478  {
479  AcDebug.Log($"AcUtilsException caught and logged in AcStreams.initAsync{Environment.NewLine}{ecx.Message}");
480  }
481 
482  catch (Exception ecx)
483  {
484  AcDebug.Log($"Exception caught and logged in AcStreams.initAsync{Environment.NewLine}{ecx.Message}");
485  }
486 
487  return ret;
488  }
490  #endregion
491 
497  public AcStream getStream(string name)
498  {
499  return this.SingleOrDefault(n => n.Name == name);
500  }
501  }
502 }
int CompareTo(AcStream other)
Generic IComparable implementation (default) for comparing AcStream objects to sort by stream name...
Definition: AcStreams.cs:148
AccuRev program return value and command result.
Definition: AcCommand.cs:29
int BasisID
Basis stream ID number.
Definition: AcStreams.cs:206
async Task< bool > initAsync(AcDepot depot, string listfile=null)
Populate this container with AcStream objects as per constructor parameters. AcStream objects are ins...
Definition: AcStreams.cs:435
bool IsDynamic
Whether the stream is a dynamic stream or not. false in the case of a workspace, snapshot or passthro...
Definition: AcStreams.cs:225
AcStream getBasis()
Get this stream's basis (parent) stream.
Definition: AcStreams.cs:284
AcStreams(bool dynamicOnly, bool includeHidden)
A container of AcStream objects that define AccuRev streams. AcStream objects are instantiated during...
Definition: AcStreams.cs:406
A depot object that defines the attributes of an AccuRev depot.
Definition: AcDepots.cs:49
string Name
Stream name.
Definition: AcStreams.cs:179
bool HasDefaultGroup
Whether the stream has a default group or not.
Definition: AcStreams.cs:275
override int GetHashCode()
Override appropriate for type AcStream.
Definition: AcStreams.cs:131
A stream object that defines the attributes of an AccuRev stream. AcStream objects are instantiated d...
Definition: AcStreams.cs:74
string CmdResult
The command result (usually XML) emitted by AccuRev.
Definition: AcCommand.cs:70
int RetVal
The AccuRev program return value for the command, otherwise minus one (-1) on error.
Definition: AcCommand.cs:61
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
AcDepot Depot
Depot the stream is located in.
Definition: AcStreams.cs:215
bool Equals(AcStream other)
IEquatable implementation to determine the equality of instances of type AcStream. Uses the stream ID number and depot to compare instances.
Definition: AcStreams.cs:106
StreamType Type
The kind of stream: unknown, normal, dynamic, regular, workspace, snapshot, passthru, passthrough, gated or staging.
Definition: AcStreams.cs:235
AcStream()
AcStream objects are instantiated during AcDepot and AcDepots construction. This constructor is calle...
Definition: AcStreams.cs:95
string BasisName
Basis stream name.
Definition: AcStreams.cs:197
DateTime Time
Stream's time basis or when the snapshot stream was created, otherwise null.
Definition: AcStreams.cs:248
Exception thrown when an AccuRev command fails. The AccuRev program return value is zero (0) on succe...
StreamType
The type of stream.
Definition: AcStreams.cs:33
AcStream getBasis(string name)
Get the basis (parent) stream for stream name.
Definition: AcDepots.cs:318
int ID
Stream ID number.
Definition: AcStreams.cs:188
AccuRev command processing.
Definition: AcCommand.cs:138
static async Task< AcResult > runAsync(string command, ICmdValidate validator=null)
Run the AccuRev command asynchronously with non-blocking I/O.
Definition: AcCommand.cs:184
string ToString(string format, IFormatProvider provider)
The actual implementation of the ToString method.
Definition: AcStreams.cs:311
Use to log and display error and general purpose text messages, and to save the XML param data sent b...
Definition: AcDebug.cs:100
DateTime StartTime
Stream's creation time or last time its name, time basis or state (remove, reactivate, reparent) changed.
Definition: AcStreams.cs:257
A container of AcStream objects that define AccuRev streams. AcStream objects are instantiated during...
Definition: AcStreams.cs:375
string ToString(string format, IFormatProvider provider)
The ToString implementation.
Definition: AcDepots.cs:573
AcStream getStream(string name)
Get the AcStream object for stream name.
Definition: AcStreams.cs:497
override bool Equals(object other)
Overridden to determine equality.
Definition: AcStreams.cs:119
bool Hidden
Whether the stream is hidden or not.
Definition: AcStreams.cs:266