private bool EnsureAvailableName(ref string destinationDisplayName, Folder parent, bool creatingDocument, bool newVersion = false) { const int MaxIterations = 10; string originalDisplayName = destinationDisplayName; string name = destinationDisplayName.ToUpperInvariant(); if (NameConflicts(parent, name, creatingDocument, newVersion)) { int iteration = 0; do { if (iteration == MaxIterations) { // Try one last time with a random name. destinationDisplayName = Utilities.GenerateNewName(originalDisplayName, creatingDocument, Utilities.GenerateRandomString("0123456789", 8)); name = destinationDisplayName.ToUpperInvariant(); iteration++; continue; } else if (iteration == MaxIterations + 1) { return false; } destinationDisplayName = Utilities.GenerateNewName(originalDisplayName, creatingDocument, (iteration + 2).ToString()); name = destinationDisplayName.ToUpperInvariant(); iteration++; // Don't allow new versions if we already had a name conflict. newVersion = false; } while (NameConflicts(parent, name, creatingDocument, newVersion)); } return true; }
private bool NameConflicts(Folder parent, string name, bool creatingDocument, bool newVersion) { File file = parent.Files.AsQueryable().Where(f => f.Name == name).SingleOrDefault(); if (file == null || file.State == ObjectState.Deleted) return false; if (creatingDocument && newVersion && file is Document) return false; return true; }
private FileBrowseViewModel CreateBrowseModelForFolder(Folder folder, string fullDisplayName) { long userId = User.Identity.GetUserId(); Folder userRootFolder = _fileManager.GetUserRootFolder(userId); if (folder == null) { folder = userRootFolder; fullDisplayName = ""; } Folder originalFolder = folder; // Follow any invitation link. if (folder.InvitationId != null) folder = folder.Invitation.Target; FileBrowseViewModel model = new FileBrowseViewModel(); model.FullDisplayName = fullDisplayName; model.DisplayName = originalFolder == userRootFolder ? "Home" : originalFolder.DisplayName; model.State = originalFolder.State; model.Files = ( from file in folder.Files.AsQueryable() where file.State == ObjectState.Normal || file.State == folder.State // Always show deleted files in a deleted folder orderby !(file is Folder) ascending, file.Name ascending let latestVersion = (file is Document) ? (from version in ((Document)file).DocumentVersions.AsQueryable() orderby version.TimeStamp descending select version).FirstOrDefault() : null select new FileBrowseViewModel.FileEntry { Id = file.Id, FullDisplayName = fullDisplayName + "/" + file.DisplayName, DisplayName = file.DisplayName, IsFolder = file is Folder, Size = latestVersion != null ? latestVersion.Blob.Size : 0, TimeStamp = latestVersion != null ? latestVersion.TimeStamp : DateTime.UtcNow, State = file.State, HasInvitation = (file is Folder) ? ((Folder)file).InvitationId != null : false, HasTargetInvitations = (file is Folder) ? ((Folder)file).TargetOfInvitations.Any() : false } ).ToList(); model.Parents = new List<Tuple<string, string>>(); // Construct the parent list for the breadcrumb. List<Folder> parentFolders = new List<Folder>(); Folder currentFolder = folder; while (currentFolder != userRootFolder) { if (currentFolder.TargetOfInvitations.Any()) { model.SharedFolder = true; // Follow any invitation link backwards. var invitation = _fileManager.GetInvitationForUser(currentFolder, userId); Folder acceptedFolder = null; if (invitation != null) acceptedFolder = invitation.AcceptedFolders.SingleOrDefault(); if (acceptedFolder != null) { currentFolder = acceptedFolder; model.SharedWithMe = true; } } if (currentFolder != userRootFolder) parentFolders.Add(currentFolder); currentFolder = currentFolder.ParentFolder; }; parentFolders.Reverse(); if (parentFolders.Count != 0) parentFolders.RemoveAt(parentFolders.Count - 1); if (folder != userRootFolder) model.Parents.Add(new Tuple<string, string>("Home", "")); StringBuilder sb = new StringBuilder(); foreach (var f in parentFolders) { sb.Append('/'); sb.Append(f.DisplayName); model.Parents.Add(new Tuple<string, string>(f.DisplayName, sb.ToString())); } return model; }