FolderCache
Represents a class object to manage client-side folder operations through a simple cache.
using kCura.WinEDDS.Exceptions;
using kCura.WinEDDS.Importers;
using kCura.WinEDDS.Service;
using Microsoft.VisualBasic.CompilerServices;
using Relativity.DataExchange;
using Relativity.DataExchange.Logger;
using Relativity.Logging;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Text;
namespace kCura.WinEDDS
{
public class FolderCache : IFolderCache
{
public const char PathSeparatorChar = '\\';
public const string PathSeparator = "\\";
public const int FolderNotFoundId = -1;
private readonly ConcurrentDictionary<string, FolderCacheItem> _dictionary;
private readonly FolderCacheItem _rootFolder;
private readonly IHierarchicArtifactManager _hierarchicArtifactManager;
private readonly int _rootFolderId;
private readonly int _workspaceId;
private readonly ILog _logger;
public int Count => _dictionary.Count;
public FolderCache(ILog logger, IHierarchicArtifactManager hierarchicArtifactManager, int rootFolderId, int workspaceId)
{
if (logger == null)
throw new ArgumentNullException("logger");
if (hierarchicArtifactManager == null)
throw new ArgumentNullException("hierarchicArtifactManager");
if (rootFolderId < 1)
throw new ArgumentOutOfRangeException("rootFolderId", "The root folder artifact identifier must be greater than zero.");
if (workspaceId < 1)
throw new ArgumentOutOfRangeException("workspaceId", "The workspace artifact identifier must be greater than zero.");
_logger = logger;
_hierarchicArtifactManager = hierarchicArtifactManager;
_workspaceId = workspaceId;
_rootFolderId = rootFolderId;
_dictionary = new ConcurrentDictionary<string, FolderCacheItem>();
_rootFolder = new FolderCacheItem("\\", _rootFolderId);
_dictionary[_rootFolder.Path] = _rootFolder;
try {
DataSet dataSet = _hierarchicArtifactManager.RetrieveArtifacts(_workspaceId, rootFolderId);
dataSet.Relations.Add("NodeRelation", dataSet.Tables[0].Columns["ArtifactID"], dataSet.Tables[0].Columns["ParentArtifactID"]);
IEnumerator enumerator = default(IEnumerator);
try {
enumerator = dataSet.Tables[0].Rows.GetEnumerator();
while (enumerator.MoveNext()) {
DataRow dataRow = (DataRow)enumerator.Current;
if (dataRow["ParentArtifactID"] is DBNull)
RecursivelyPopulate(dataRow, _rootFolder);
}
} finally {
if (enumerator is IDisposable)
(enumerator as IDisposable).Dispose();
}
} catch (Exception ex) {
ProjectData.SetProjectError(ex);
Exception ex2 = ex;
if (ExceptionHelper.IsFatalException(ex2))
throw;
_logger.LogFatal(ex2, "Failed to retrieve all sub-folders within the {RootFolderId} root folder for workspace {WorkspaceId}.", new object[2] {
rootFolderId,
_workspaceId
});
throw new WebApiException(ExceptionHelper.AppendTryAgainAdminFatalMessage($"""{rootFolderId}""{_workspaceId}"""), ex2);
}
}
public int GetFolderId(string folderPath)
{
StringBuilder stringBuilder = new StringBuilder();
string[] array = folderPath.Split(new char[1] {
'\\'
});
foreach (string text in array) {
if (Operators.CompareString(text.Trim(), "", false) != 0)
stringBuilder.Append("\\" + text.Trim());
}
folderPath = stringBuilder.ToString();
if (Operators.CompareString(folderPath, "", false) == 0)
folderPath = "\\";
if (!_dictionary.ContainsKey(folderPath))
try {
FolderCacheItem newFolder = GetNewFolder(folderPath);
if (!_dictionary.ContainsKey(folderPath))
_dictionary[folderPath] = newFolder;
return newFolder.FolderID;
} catch (Exception ex) {
ProjectData.SetProjectError(ex);
Exception ex2 = ex;
if (ExceptionHelper.IsFatalException(ex2))
throw;
_logger.LogFatal(ex2, "Failed to create the {FolderPath} folder path for workspace {WorkspaceId}.", new object[2] {
folderPath.Secure(),
_workspaceId
});
throw new WebApiException(ExceptionHelper.AppendTryAgainAdminFatalMessage($"""{folderPath}""{_workspaceId}"""), ex2);
}
return _dictionary[folderPath].FolderID;
}
int IFolderCache.GetFolderId(string folderPath)
{
return this.GetFolderId(folderPath);
}
private FolderCacheItem GetNewFolder(string folderPath)
{
List<string> list = new List<string>();
string folderPath2 = (Operators.CompareString(folderPath, "", false) != 0 && Operators.CompareString(folderPath, "\\", false) != 0) ? folderPath.Substring(0, folderPath.LastIndexOf("\\")) : "\\";
list.Add(folderPath.Substring(checked(folderPath.LastIndexOf("\\") + 1)));
FolderCacheItem parentFolder = FindParentFolder(folderPath2, list);
return CreateFolders(parentFolder, list);
}
private FolderCacheItem CreateFolders(FolderCacheItem parentFolder, List<string> folderNames)
{
if (folderNames.Count <= 0)
return parentFolder;
string text = folderNames[0];
folderNames.RemoveAt(0);
int num = _hierarchicArtifactManager.Read(_workspaceId, parentFolder.FolderID, text);
if (-1 == num)
num = _hierarchicArtifactManager.Create(_workspaceId, parentFolder.FolderID, text);
string str = (Operators.CompareString(parentFolder.Path, "\\", false) != 0) ? parentFolder.Path : "";
FolderCacheItem folderCacheItem = new FolderCacheItem(str + "\\" + text, num);
_dictionary[folderCacheItem.Path] = folderCacheItem;
return CreateFolders(folderCacheItem, folderNames);
}
private FolderCacheItem FindParentFolder(string folderPath, List<string> pathToDestination)
{
if (!_dictionary.ContainsKey(folderPath)) {
string text = folderPath.Substring(checked(folderPath.LastIndexOf("\\") + 1));
if (Operators.CompareString(text, "", false) != 0) {
pathToDestination.Insert(0, text);
return FindParentFolder(folderPath.Substring(0, folderPath.LastIndexOf("\\")), pathToDestination);
}
return _rootFolder;
}
return _dictionary[folderPath];
}
private void RecursivelyPopulate(DataRow dataRow, FolderCacheItem parent)
{
DataRow[] childRows = dataRow.GetChildRows("NodeRelation");
foreach (DataRow dataRow2 in childRows) {
string text = (Operators.CompareString(parent.Path, "\\", false) != 0) ? (parent.Path + "\\" + dataRow2["Name"].ToString().Trim()) : ("\\" + dataRow2["Name"].ToString().Trim());
FolderCacheItem folderCacheItem = new FolderCacheItem(text.Trim(), Conversions.ToInteger(dataRow2["ArtifactID"]));
if (!_dictionary.ContainsKey(folderCacheItem.Path.Trim()))
_dictionary[folderCacheItem.Path.Trim()] = folderCacheItem;
RecursivelyPopulate(dataRow2, folderCacheItem);
}
}
}
}