/// <summary> /// Checkin the object as a new object at a new location with a new name. /// </summary> /// <param name="parentId">Th eparent of the new object.</param> /// <param name="name">The name of the new object.</param> /// <returns>The ID of the new document.</returns> public virtual int CheckinAs(int parentId, string name, string file, Func <FWDocument, bool> keywordingAndCheckinFunction = null) { FWDocument newDocument = Conn.Content.CreateDocument(parentId, this.MaskId); //newDocument.Core.copyMembers(Core); newDocument.File = file; newDocument.Name = name; newDocument.Version.Version = "1"; if (LockId > 0) { Unlock(); } if (null != keywordingAndCheckinFunction) { keywordingAndCheckinFunction(newDocument); } else { newDocument.Checkin(); } return(newDocument.Id); }
/// <summary> /// Locks and creates neccessary files for editing of document created from selected template document, by using template document data. /// </summary> /// <param name="document">Document created from specific document template, for that neccessary files for editing have to be craeted in checkout directory.</param> /// <param name="template">Template document, that contains data, which have to be used to create neccessary files in checkout directory for editing of specific document.</param> /// <returns> /// Returns a reference to document with a checkedout file, which can be used to edit a document created from a selected document template. /// </returns> public virtual FWDocument ApplyDocumentTemplate(FWDocument document, FWDocument template) { bool existsDocument = (document != null); bool existsTemplateDocument = (template != null && !string.IsNullOrEmpty(template.File) && File.Exists(template.File)); if (existsDocument && existsTemplateDocument) { document.Refresh(); // Dokumenteintrag im Archiv sperren if (document.LockId == -1) { document = Conn.Content.LockDocument(document.Id); } string fileExtension = Path.GetExtension(template.File); string checkedOutFilePath = MakeCheckOutFilePath(document.Name, fileExtension, document.Id.ToString(), document.Version.Id.ToString()); bool existsCheckedOutFileAlready = (!string.IsNullOrEmpty(checkedOutFilePath) && File.Exists(checkedOutFilePath)); if (!existsCheckedOutFileAlready) { File.Copy(template.File, checkedOutFilePath); FileInfo fInfo = new FileInfo(checkedOutFilePath); if (fInfo.Exists) { fInfo.Attributes = FileAttributes.Normal; Conn.Content.DownloadManager.CreateStateFile(checkedOutFilePath, document.Id.ToString(), document.Version.Id.ToString(), document.LockId.ToString()); } } } return(document); }
/// <summary> /// Returns back a path to the checked out file of specific document. Only if state file exists for a specific document a path /// to the checkedout file will be returned back. /// </summary> /// <param name="document">Reference to document for that path to checked out document have to be returned back.</param> /// <returns> /// Path to the checked out file or null if no one exists for a specific document. /// </returns> public string GetCheckedOutFileOf(FWDocument document) { string filePath = null; bool existsDocument = (document != null); if (existsDocument) { string[] checkedOutFiles = GetCheckedOutFilesWithStateFile(checkOutDir); bool existsCheckedOutFiles = (checkedOutFiles != null && checkedOutFiles.Length > 0); if (existsCheckedOutFiles) { foreach (string file in checkedOutFiles) { try { // Load state file that belongs to a specific checked out file StateFile stateFile = new StateFile(file + ".state"); if (stateFile.ObjectId.HasValue && stateFile.LockId.HasValue) { if (stateFile.LockId.Value != -1 && stateFile.LockId.Value == Conn.Session.User.id && stateFile.ObjectId == document.Id) { filePath = file; break; } } } catch { } } } } return(filePath); }
/// <summary> /// Returns list of checked out documents. Only documents with state file and lockid value unequal -1 in the state file are /// valid checked out documents and will be returned back. /// </summary> /// <returns> /// List of checked out documents. /// </returns> public IList <FWDocument> GetCheckedOutDocuments() { IList <FWDocument> checkedOutDocs = new List <FWDocument>(); try { // Load all checked out files, which have a state file. Only this files are valid. string[] checkedOutFilesWithStateFile = GetCheckedOutFilesWithStateFile(checkOutDir); bool existsCheckedOutFiles = (checkedOutFilesWithStateFile != null && checkedOutFilesWithStateFile.Length > 0); if (existsCheckedOutFiles) { // This dictionary will be used to proove if checked out document exists more than one time Dictionary <int, FWDocument> checkedOutDocsIdsDictionary = new Dictionary <int, FWDocument>(); foreach (string checkedOutFilePath in checkedOutFilesWithStateFile) { try { bool existsCheckedOutFile = (!string.IsNullOrEmpty(checkedOutFilePath) && File.Exists(checkedOutFilePath)); if (existsCheckedOutFile) { // Load state file that belongs to a specific checked out file StateFile stateFile = new StateFile(checkedOutFilePath + ".state"); if (stateFile.ObjectId.HasValue && stateFile.LockId.HasValue) { if (stateFile.LockId.Value != -1 && stateFile.LockId.Value == Conn.Session.User.id) { FWDocument checkedOutDocument = Conn.Content.GetDocument(stateFile.ObjectId.Value); if (checkedOutDocument != null) { if (!checkedOutDocsIdsDictionary.ContainsKey(checkedOutDocument.Id)) { checkedOutDocsIdsDictionary.Add(checkedOutDocument.Id, checkedOutDocument); checkedOutDocs.Add(checkedOutDocument); } } } } } } catch { } } } } catch { } return(checkedOutDocs); }
/// <summary> /// Deletes imediatelly all not more checked out documents in a checkout directory. A document is not more checked out if state file for a /// specific document not more exists in a checkout directory. /// </summary> public void ForceCleanup() { bool existsCheckOutDirectory = (!string.IsNullOrEmpty(checkOutDir) && Directory.Exists(checkOutDir)); if (existsCheckOutDirectory) { string[] checkOutDirectoryFiles = Directory.GetFiles(checkOutDir); bool existsCheckOutDirectoryFiles = (checkOutDirectoryFiles != null && checkOutDirectoryFiles.Length > 0); if (existsCheckOutDirectoryFiles) { foreach (string checkedOutFile in checkOutDirectoryFiles) { try { bool existsStateFileForCheckedOutFile = ExistsStateFileForFile(checkedOutFile); if (!existsStateFileForCheckedOutFile) { FileInfo fInfo = new FileInfo(checkedOutFile); if (fInfo.Exists && !fInfo.Extension.Equals(".state") && !fInfo.Attributes.HasFlag(FileAttributes.Hidden)) { fInfo.Attributes = FileAttributes.Normal; fInfo.Delete(); } } else { // Proove if document with specific id exists in archive, if not delete a checked out file StateFile stateFile = new StateFile(checkedOutFile + ".state"); if (stateFile.ObjectId.HasValue) { FWDocument document = Conn.Content.TryGetDocument(stateFile.ObjectId.Value.ToString(), Utils.FWAccessModes.Nothing); if (document == null) { FileInfo fInfo = new FileInfo(checkedOutFile + ".state"); if (fInfo.Exists) { fInfo.Attributes = FileAttributes.Normal; fInfo.Delete(); } } } } } catch { } } } } }
/// <summary> /// Deletes checked out and state file of selected document if any of them exists. Only for no more locked document /// checked out and state file can be deleted. /// </summary> /// <param name="document">Document, for that checked out and state file have to be deleted in checkout directory.</param> public void RemoveCheckedOutDocumentFiles(FWDocument document) { bool existsDocument = (document != null); bool existsCheckOutDirectory = (!string.IsNullOrEmpty(checkOutDir) && Directory.Exists(checkOutDir)); if (existsDocument && document.LockId == -1) { string[] checkedOutFiles = GetCheckedOutFilesWithStateFile(checkOutDir); bool existsCheckedOutFiles = (checkedOutFiles != null && checkedOutFiles.Length > 0); if (existsCheckedOutFiles) { foreach (string file in checkedOutFiles) { bool isStateFileDeleted = false; try { // Load state file that belongs to a specific checked out file StateFile stateFile = new StateFile(file + ".state"); if (stateFile.ObjectId.HasValue && stateFile.ObjectId == document.Id && stateFile.LockId == Conn.Session.User.id) { FileInfo stateFileInfo = new FileInfo(file + ".state"); if (stateFileInfo.Exists) { stateFileInfo.Attributes = FileAttributes.Normal; stateFileInfo.Delete(); isStateFileDeleted = true; // Issue event OnCheckedOutDocumentRemoved(new EventArgs()); } } } catch { } if (isStateFileDeleted) { break; } } } // Delete all files which dont have a state file ForceCleanup(); } }
/// <summary> /// Return a FWDocument for the given file. /// </summary> /// <param name="file">Controlled file</param> /// <returns>FWDocument object</returns> public virtual FWDocument GetFWDocumentFromFile(string file) { FWDocument doc = null; if (IsControlledFile(file)) { string objId, docId; if (GetIdFromFileName(file, out objId, out docId)) { doc = ifc.Conn.Content.GetDocument(objId); // Wenn die Datei mit AttachNewDocumentWorkFile einem Dokument zugewiesen wurde, // dann ist sie nicht im doc.File eingetragen. doc.File = file; } } return(doc); }
/// <summary> /// Makes a valid and unique file name in the checkout directory. /// </summary> /// <param name="document">Reference to document object, for hat file path have to be created.</param> /// <returns> /// New unique checkout file path for a specific document with following structure: ...\checkoutdir\documentname--objectid-docid.ext /// </returns> public virtual string MakeCheckOutFilePath(FWDocument document) { string name = document.OriginalFileName; if (string.IsNullOrEmpty(name)) { name = document.Name; } else { int p = name.LastIndexOf('.'); if (p >= 0) { name = name.Substring(0, p); } } return(MakeCheckOutFilePath(name, document.Version.Core.ext, document.Id.ToString(), document.Version.Id.ToString())); }
/// <summary> /// This function locks the document <code>doc</code> and assigns the document file from <code>templ</code>. /// </summary> /// <param name="doc">Document</param> /// <param name="templ">Template document</param> /// <returns></returns> public virtual FWDocument ApplyDocumentTemplate(FWDocument doc, FWDocument templ) { // Dokumenteintrag im Archiv sperren if (doc.LockId == -1) { doc = LockDocument(doc.Id); } // Vorlagedatei String templFile = templ.File; // Vorlagedatei ins Arbeitsverzeichnis kopieren // und über den Dateienamen an das Dokument binden. string destFile = DownloadManager.AttachNewDocumentWorkFile(templFile, "", doc.Name, doc.Id.ToString(), doc.Version.Id.ToString()); doc.Version.File = destFile; return(doc); }
/// <summary> /// Mark the file as invalid. /// </summary> /// <param name="filePath">File path.</param> /// <remarks>The next call to Cleanup will delete the file.</remarks> public virtual void InvalidateFile(string filePath) { FWDocument document = GetFWDocumentFromFile(filePath); if ((document == null || document.LockId == -1) && workDir.Equals(System.IO.Path.GetDirectoryName(filePath))) { FileInfo fileInfo = new FileInfo(filePath); if (fileInfo.Exists) { fileInfo.Attributes = FileAttributes.ReadOnly; } FileInfo stateInfo = GetStateFileInfo(fileInfo); if (stateInfo.Exists) { stateInfo.Delete(); } } }
/// <summary> /// Creates a checked out and state file in a checkout directory for a specific document. For creation of checked out /// and state file document must be locked by actually user. If files already exists no one will be created. /// </summary> /// <param name="document"> /// Document locked by actually user, for that checkedout and state file have to be created. /// </param> /// <exception cref="Exception"> /// Exception will be issued, if checked out or state file was not created successfully or some error occures, while creating it. /// </exception> protected virtual void CreateCheckedOutDocumentFiles(FWDocument document) { bool existsDocument = (document != null); bool existsIxConn = (document.Conn != null); bool existsDocUrl = (document != null && document.Version != null && !string.IsNullOrEmpty(document.Version.Url)); bool isDocLockedByActuallyUser = (document != null && document.LockId == document.Conn.Session.User.id); bool existsCheckedOutDocumentAlready = (document != null && !string.IsNullOrEmpty(document.CheckedoutFile) && File.Exists(document.CheckedoutFile)); if (!existsDocument || !existsIxConn || !existsDocUrl || !isDocLockedByActuallyUser) { throw new Exception("Für die Bearbeitung des Dokuments konnten im Checkout Verzeichniss nicht die erforderlichen Dateien erstellt werden. Mögliche Ursachen: Dokument oder Verbindung zum Indexserver nicht vorhanden, Url für den Download des Dokuments nicht vorhanden oder das Dokument ist nicht durch den momentanen Benutzer für die Bearbeitung gesperrt."); } else { if (!existsCheckedOutDocumentAlready) { FWConnection ixConn = document.Conn; string docUrl = document.Version.Url; // download the file, if it's a read-URL // (DocVersion contains a write-URL after checkinDocBegin) if (docUrl.IndexOf("readdoc") >= 0) { // Create file path to new checked out document string checkedOutFilePath = MakeCheckOutFilePath(document); // If new created checkout file path exists. This can be if old file was not deleted yet or could not be deleted because // it is locked by another process. bool existsCheckedOutFilePath = (!string.IsNullOrEmpty(checkedOutFilePath) && File.Exists(checkedOutFilePath)); // If checkout file path created above already exists than create one with guid. This is an unique file path, becuase file path // contains a guid that only appears one time. if (existsCheckedOutFilePath) { checkedOutFilePath = MakeCheckOutFilePathWithGuid(document); } // Download file into ixConn.Content.Download(docUrl, checkedOutFilePath); if (string.IsNullOrEmpty(checkedOutFilePath) || !File.Exists(checkedOutFilePath)) { string errorMsg = string.Format("Für die Bearbeitung des Dokuments {0} konnten in CheckOut Verzeichniss nicht die notwendigen Dateien erstellt werden.", document.Name); throw new Exception(errorMsg); } // Create state file for checked out document string stateFilePath = ixConn.Content.DownloadManager.CreateStateFile(checkedOutFilePath, document.Id.ToString(), document.Version.Id.ToString(), document.LockId.ToString()); if (string.IsNullOrEmpty(stateFilePath) || !File.Exists(stateFilePath)) { string errorMsg = string.Format("Für die Bearbeitung des Dokuments {0} konnten in CheckOut Verzeichniss nicht die notwendigen Dateien erstellt werden.", document.Name); throw new Exception(errorMsg); } // If checkout file and state file was created successfully set file attribute to normal, to ensure, // that file can be modified FileInfo checkedOutFileInfo = new FileInfo(checkedOutFilePath); checkedOutFileInfo.Attributes = FileAttributes.Normal; // Issue a event OnNewCheckedOutDocument(new EventArgs()); } } } }
/// <summary> /// Checks out a selected document and returns back result of checkout. While checkout of selected document checked out and state file will be created in /// checkout directory. /// </summary> /// <param name="document">Document, that have to be checked out.</param> /// <returns> /// Result of checkout operation. /// </returns> public CheckoutResult Checkout(FWDocument document) { CheckoutResult checkOutResult = new CheckoutResult() { FWDocument = document, Success = false }; try { bool existsDocForCheckOut = (document != null); bool existsDocUrl = (document != null && document.Version != null && !string.IsNullOrEmpty(document.Version.Url)); bool existsIxConn = (document.Conn != null); if (existsDocForCheckOut && existsDocUrl && existsIxConn) { // Delete not more checked out documents in checkout directory ForceCleanup(); // Actualize data of document document.Refresh(); FWConnection ixConn = document.Conn; // Exists checkout file already bool existsCheckedOutFile = (!string.IsNullOrEmpty(document.CheckedoutFile) && File.Exists(document.CheckedoutFile)); // If checkout file already exists if (existsCheckedOutFile) { // If document lock, not exists for currently user set one if (document.LockId == -1) { FWDocument lockedDocument = ixConn.Content.LockDocument(document.Id); if (lockedDocument.LockId == ixConn.Session.User.id) { checkOutResult.FWDocument = lockedDocument; checkOutResult.Success = true; } else { checkOutResult.Message = string.Format("Das Dokument {0} kann nicht zur Bearbeitung ausgecheckt werden, da das Sperren des Dokuments für die Bearbeitung nicht erfolgreich durchgeführt werden konnte.", document.Name); } } else { if (document.LockId == ixConn.Session.User.id) { checkOutResult.FWDocument = document; checkOutResult.Success = true; } else { checkOutResult.Message = string.Format("Das Dokument {0} kann nicht zur Bearbeitung ausgecheckt werden, da dieses bereits durch einen anderen Benutzer für die Bearbeitung gesperrt worden ist.", document.Name); } } } else { if (document.LockId == -1) { FWDocument lockedDocument = ixConn.Content.LockDocument(document.Id); if (lockedDocument.LockId == ixConn.Session.User.id) { // Create checkout file and state file for checked out document CreateCheckedOutDocumentFiles(lockedDocument); lockedDocument.Refresh(); checkOutResult.FWDocument = lockedDocument; checkOutResult.Success = true; } else { checkOutResult.Message = string.Format("Das Dokument {0} kann nicht zur Bearbeitung ausgecheckt werden, da das Sperren des Dokuments für die Bearbeitung nicht erfolgreich durchgeführt werden konnte.", document.Name); } } else if (document.LockId == ixConn.Session.User.id) { // Create checkout file and state file for checked out document CreateCheckedOutDocumentFiles(document); document.Refresh(); checkOutResult.FWDocument = document; checkOutResult.Success = true; } else { checkOutResult.Message = string.Format("Das Dokument {0} kann nicht zur Bearbeitung ausgecheckt werden, da es durch einen anderen Benutzer bereits für die Bearbeitung gesperrt worden ist.", document.Name); } } } else { checkOutResult.Message = "Das Dokument kann nicht zur Bearbeitung ausgecheckt werden. Mögliche Ursachen: Dokument existiert nicht, keine Verbindung zum Indexserver oder die Url des Dokuments ist nicht vorhanden."; } } catch (Exception ex) { checkOutResult.Success = false; checkOutResult.Message = "Das Auschecken des Dokuments zur Bearbeitung ist aufgrund des folgenden Fehlers fehlgeschlagen. Fehler: " + ex.Message; } return(checkOutResult); }