Node
using Relativity.DataTransfer.Nodes.Internal;
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace Relativity.DataTransfer.Nodes
{
public abstract class Node : INode, IEquatable<Node>
{
private string _hashedName;
private string _hashedAbsolutePath;
private const string _HEXADECIMAL_FORMAT = "x2";
public string Name { get; }
public INodeContext Context { get; }
public INode Parent { get; }
public virtual string AbsolutePath => (Parent != null) ? BuildAbsolutePath() : Name;
public string HashedName {
get {
if (string.IsNullOrEmpty(_hashedName))
_hashedName = ComputeSha256(Name);
return _hashedName;
}
}
public string HashedAbsolutePath {
get {
if (string.IsNullOrEmpty(_hashedAbsolutePath))
_hashedAbsolutePath = ComputeSha256ForAbsolutePath();
return _hashedAbsolutePath;
}
}
protected Node(string name, INode parentNode)
{
ValidateName(name);
ValidateParent(parentNode);
ValidateContext(parentNode.Context);
Name = name;
Parent = parentNode;
Context = parentNode.Context;
}
protected Node(string name, IRoot rootNode, INodeContext context)
{
ValidateName(name);
ValidateParent(rootNode);
ValidateContext(context);
Name = name;
Parent = rootNode;
Context = context;
}
public bool Equals(Node other)
{
if ((object)other != null) {
if ((object)this != other) {
StringComparison comparisonType = FileSystemType.IsWindowsBased ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture;
return string.Equals(Name, other.Name, comparisonType) && object.Equals(Context, other.Context) && object.Equals(Parent, other.Parent);
}
return true;
}
return false;
}
public override bool Equals(object obj)
{
if (obj != null) {
if (this != obj)
return obj.GetType() == GetType() && Equals((Node)obj);
return true;
}
return false;
}
public override int GetHashCode()
{
StringComparer comparer = GetComparer();
int hashCode = comparer.GetHashCode(Name);
hashCode = ((hashCode * 397) ^ Context.GetHashCode());
return (hashCode * 397) ^ ((Parent != null) ? Parent.GetHashCode() : 0);
}
public static bool operator ==(Node left, Node right)
{
return object.Equals(left, right);
}
public static bool operator !=(Node left, Node right)
{
return !object.Equals(left, right);
}
private static void ValidateParent(INode parentNode)
{
if (parentNode == null)
throw new ArgumentException("parentNode");
}
private static void ValidateName(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("name");
}
private static void ValidateContext(INodeContext context)
{
if (context == null)
throw new ArgumentException("context");
}
private string BuildAbsolutePath()
{
string absolutePath = Parent.AbsolutePath;
if (!string.IsNullOrEmpty(absolutePath)) {
if (absolutePath.Last() != PathConstants.DirectorySeparatorAsChar)
return (Name != PathConstants.DirectorySeparatorAsString) ? $"{absolutePath}{PathConstants.DirectorySeparatorAsChar}{Name}" : (absolutePath ?? "");
return (Name != PathConstants.DirectorySeparatorAsString) ? (absolutePath + Name) : absolutePath;
}
return Name;
}
private static string ComputeSha256(string stringToHash)
{
StringBuilder stringBuilder = new StringBuilder();
using (SHA256 sHA = SHA256.Create()) {
byte[] array = sHA.ComputeHash(Encoding.UTF8.GetBytes(stringToHash));
byte[] array2 = array;
for (int i = 0; i < array2.Length; i++) {
byte b = array2[i];
stringBuilder.Append(b.ToString("x2"));
}
}
return stringBuilder.ToString();
}
private string ComputeSha256ForAbsolutePath()
{
string hashedAbsolutePath = Parent.HashedAbsolutePath;
if (!string.IsNullOrEmpty(hashedAbsolutePath))
return (hashedAbsolutePath.Last() == PathConstants.DirectorySeparatorAsChar) ? (hashedAbsolutePath + HashedName) : $"{hashedAbsolutePath}{PathConstants.DirectorySeparatorAsChar}{HashedName}";
return HashedName;
}
private static StringComparer GetComparer()
{
return FileSystemType.IsWindowsBased ? StringComparer.InvariantCultureIgnoreCase : StringComparer.InvariantCulture;
}
}
}