public static bool ItemExistsWithType(ISession session, string path, DotCMIS.Enums.BaseTypeId type) { try { // Try querying for this object. The object not existing is a common case, so do not log potential error. ICmisObject cmisObject = session.GetObjectByPath(path, false); if (cmisObject == null) { return(false); } return(cmisObject.ObjectType.BaseTypeId.Equals(type) || cmisObject.ObjectType.GetBaseType().BaseTypeId.Equals(type)); } catch (Exception e) { if (e is ArgumentNullException || e is CmisObjectNotFoundException) { // In DotCMIS, this exception actually means that the document does not exist. return(false); } else { throw; } } }
public void SmokeTestRootFolder() { ICmisObject rootFolderObject = Session.GetRootFolder(); Assert.NotNull(rootFolderObject); Assert.NotNull(rootFolderObject.Id); Assert.True(rootFolderObject is IFolder); IFolder rootFolder = (IFolder)rootFolderObject; Assert.AreEqual("/", rootFolder.Path); Assert.AreEqual(1, rootFolder.Paths.Count); Assert.NotNull(rootFolder.AllowableActions); Assert.True(rootFolder.AllowableActions.Actions.Contains(Actions.CanGetProperties)); Assert.False(rootFolder.AllowableActions.Actions.Contains(Actions.CanGetFolderParent)); IItemEnumerable <ICmisObject> children = rootFolder.GetChildren(); Assert.NotNull(children); foreach (ICmisObject child in children) { Assert.NotNull(child); Assert.NotNull(child.Id); Assert.NotNull(child.Name); Console.WriteLine(child.Name + " (" + child.Id + ")"); } }
public void TestPath() { IDictionary <string, string> parameters = new Dictionary <string, string>(); CmisObjectCache cache = new CmisObjectCache(); cache.Initialize(null, parameters); string cacheKey1 = "ck1"; string path = "/test/path"; MockObject mock1 = new MockObject("1"); cache.PutPath(path, mock1, cacheKey1); ICmisObject o1 = cache.GetById(mock1.Id, cacheKey1); Assert.NotNull(o1); Assert.AreEqual(mock1.Id, o1.Id); ICmisObject o2 = cache.GetByPath(path, cacheKey1); Assert.NotNull(o2); Assert.AreEqual(mock1.Id, o2.Id); Assert.Null(cache.GetByPath("/some/other/path/", cacheKey1)); }
protected bool MatchObject(ICmisObject expected, ICmisObject actual) { if (actual == null) { return Problem("An ICmisObject", "Something else"); } if (expected.BaseTypeId != actual.BaseTypeId) { return Problem("Object with BaseTypeId {0}", expected.BaseTypeId, actual.BaseTypeId); } if (expected.Id != actual.Id) { return Problem("Object with Id \"{0}\"", expected.BaseTypeId, actual.BaseTypeId); } /* * This would have to be done by hand. Skipping for now if (!expected.Properties.SequenceEqual(actual.Properties)) { return Problem("Object with Properties \"{0}\"", expected.Properties, actual.Properties); } */ if (expected is IFolder) { return MatchFolder(expected as IFolder, actual as IFolder); } else if (expected is IDocument) { return MatchDocument(expected as IDocument, actual as IDocument); } return true; }
public NtStatus GetFileSecurity(string fileName, out FileSystemSecurity security, AccessControlSections sections, DokanFileInfo info) { var cmisPath = fileName.Replace("\\", "/"); ICmisObject cmisObject = (IDocument)cmisSession.GetObjectByPath(cmisPath); try { // TODO //security = info.IsDirectory // ? (FileSystemSecurity)Directory.GetAccessControl("TODO GetPath(fileName)") // : File.GetAccessControl("TODO GetPath(fileName)"); if (cmisObject is IFolder) { //security = new System.Security.AccessControl.DirectorySecurity(); //security.AccessRightType = new AccessRig security = Directory.GetAccessControl(Constants.TEMPLATE_FOLDER); // TODO create from scratch rather than using a template } else { security = File.GetAccessControl(Constants.TEMPLATE_FILE); // TODO create from scratch rather than using a template } return(Trace("GetFileSecurity", fileName, info, DokanResult.Success, sections.ToString())); } catch (UnauthorizedAccessException) { security = null; return(Trace("GetFileSecurity", fileName, info, DokanResult.AccessDenied, sections.ToString())); } }
public IObjectId CreateDocumentFromSource(IObjectId source, IDictionary <string, object> properties, IObjectId folderId, VersioningState?versioningState, IList <IPolicy> policies, IList <IAce> addAces, IList <IAce> removeAces) { if (source == null || source.Id == null) { throw new ArgumentException("Source must be set!"); } // get the type of the source document IObjectType type = null; if (source is ICmisObject) { type = ((ICmisObject)source).ObjectType; } else { ICmisObject sourceObj = GetObject(source); type = sourceObj.ObjectType; } if (type.BaseTypeId != BaseTypeId.CmisDocument) { throw new ArgumentException("Source object must be a document!"); } string newId = Binding.GetObjectService().CreateDocumentFromSource(RepositoryId, source.Id, ObjectFactory.ConvertProperties(properties, type, (versioningState == VersioningState.CheckedOut ? CreateAndCheckoutUpdatability : CreateUpdatability)), (folderId == null ? null : folderId.Id), versioningState, ObjectFactory.ConvertPolicies(policies), ObjectFactory.ConvertAces(addAces), ObjectFactory.ConvertAces(removeAces), null); return(newId == null ? null : CreateObjectId(newId)); }
public NtStatus DeleteFile(string fileName, DokanFileInfo info) { var cmisPath = fileName.Replace("\\", "/"); bool pathExists = true; bool pathIsFile = true; ICmisObject cmisObject = null; try { cmisObject = cmisSession.GetObjectByPath(cmisPath); pathIsFile = !(cmisObject is IFolder); } /*catch (IOException) // TODO remove * { * pathExists = false; * }*/ catch (DotCMIS.Exceptions.CmisObjectNotFoundException) { pathExists = false; } return(Trace("DeleteFile", fileName, info, pathExists && pathIsFile ? DokanResult.Success : DokanResult.FileNotFound)); //return Trace("DeleteFile", fileName, info, File.Exists("TODO GetPath(fileName)") ? DokanResult.Success : DokanResult.FileNotFound); // we just check here if we could delete the file - the true deletion is in Cleanup }
public NtStatus DeleteDirectory(string fileName, DokanFileInfo info) { var cmisPath = fileName.Replace("\\", "/"); bool pathExists = true; bool pathIsDirectory = true; ICmisObject cmisObject = null; try { cmisObject = cmisSession.GetObjectByPath(cmisPath); pathIsDirectory = cmisObject is IFolder; } /*catch (IOException) // TODO remove * { * pathExists = false; * }*/ catch (DotCMIS.Exceptions.CmisObjectNotFoundException) { pathExists = false; } return(Trace("DeleteDirectory", fileName, info, pathExists && pathIsDirectory ? DokanResult.Success : DokanResult.DirectoryNotEmpty)); //return Trace("DeleteDirectory", fileName, info, Directory.EnumerateFileSystemEntries("TODO GetPath(fileName)").Any() ? DokanResult.DirectoryNotEmpty : DokanResult.Success); // if dir is not empty it can't be deleted }
public static void AddRemoteObject(this Mock <ISession> session, ICmisObject remoteObject) { session.Setup(s => s.GetObject(It.Is <string>(id => id == remoteObject.Id))).Returns(remoteObject); HashSet <string> paths = new HashSet <string>(); if (remoteObject is IFolder) { paths.Add((remoteObject as IFolder).Path); if ((remoteObject as IFolder).Paths != null) { foreach (string path in (remoteObject as IFolder).Paths) { paths.Add(path); } } } else if (remoteObject is IDocument) { foreach (string path in (remoteObject as IDocument).Paths) { paths.Add(path); } } foreach (string path in paths) { session.Setup(s => s.GetObjectByPath(It.Is <string>(p => p == path))).Returns(remoteObject); } }
/// <summary> /// Retrieve the CMIS metadata of a document. /// </summary> /// <returns>a dictionary in which each key is a type id and each value is a couple indicating the mode ("readonly" or "ReadWrite") and the value itself.</returns> public static Dictionary <string, string[]> FetchMetadata(ICmisObject o, IObjectType typeDef) { Dictionary <string, string[]> metadata = new Dictionary <string, string[]>(); IList <IPropertyDefinition> propertyDefs = typeDef.PropertyDefinitions; // Get metadata. foreach (IProperty property in o.Properties) { // Mode string mode = "readonly"; foreach (IPropertyDefinition propertyDef in propertyDefs) { if (propertyDef.Id.Equals("cmis:name")) { Updatability updatability = propertyDef.Updatability; mode = updatability.ToString(); } } // Value if (property.IsMultiValued) { metadata.Add(property.Id, new string[] { property.DisplayName, mode, property.ValuesAsString }); } else { metadata.Add(property.Id, new string[] { property.DisplayName, mode, property.ValueAsString }); } } return(metadata); }
/// <inheritdoc/> public void Put(ICmisObject cmisObject, string cacheKey) { // no object, no id, no cache key - no cache if (cmisObject == null || cmisObject.Id == null || cacheKey == null) { return; } lock (cacheLock) { IDictionary <string, ICmisObject> cacheKeyDict = objectCache.Get(cmisObject.Id); if (cacheKeyDict == null) { cacheKeyDict = new Dictionary <string, ICmisObject>(); objectCache.Add(cmisObject.Id, cacheKeyDict); } cacheKeyDict[cacheKey] = cmisObject; // folders may have a path, use it! string path = cmisObject.GetPropertyValue(PropertyIds.Path) as string; if (path != null) { pathToIdCache.Add(path, cmisObject.Id); } } }
/// <summary> /// Determines if the specified action is allowed on the cmis object. /// </summary> /// <returns><c>true</c> if action is allowed on the cmis object; otherwise, <c>false</c> or <c>null</c> if no information about actions is available.</returns> /// <param name="obj">Cmis Object.</param> /// <param name="action">Action name.</param> public static bool?IsActionAllowed(this ICmisObject obj, string action) { try { return(obj.AllowableActions.Actions.Contains(action)); } catch (NullReferenceException) { return(null); } }
/// <summary> /// Removes the sync ignore flags of the given device Ids from the given cmis object. /// </summary> /// <param name="obj">Remote CMIS Object.</param> /// <param name="deviceIds">Device identifiers which should be removed from ignore list.</param> public static void RemoveSyncIgnore(this ICmisObject obj, params Guid[] deviceIds) { string[] ids = new string[deviceIds.Length]; for (int i = 0; i < deviceIds.Length; i++) { ids[i] = deviceIds[i].ToString().ToLower(); } }
private void VerifyThatRenameSolverIsCalled( IFileSystemInfo localObject, ICmisObject remoteObject, ContentChangeType localChange = ContentChangeType.NONE, ContentChangeType remoteChange = ContentChangeType.NONE) { this.changeSolver.Verify(s => s.Solve(It.IsAny <IFileSystemInfo>(), It.IsAny <IObjectId>(), It.IsAny <ContentChangeType>(), It.IsAny <ContentChangeType>()), Times.Never()); this.renameSolver.Verify(s => s.Solve(localObject, remoteObject, localChange, remoteChange), Times.Once()); }
public void TestCache() { IDictionary <string, string> parameters = new Dictionary <string, string>(); CmisObjectCache cache = new CmisObjectCache(); cache.Initialize(null, parameters); string cacheKey1 = "ck1"; string cacheKey2 = "ck2"; // add first object MockObject mock1 = new MockObject("1"); cache.Put(mock1, cacheKey1); ICmisObject o1 = cache.GetById(mock1.Id, cacheKey1); Assert.NotNull(o1); Assert.AreEqual(mock1.Id, o1.Id); Assert.Null(cache.GetById(mock1.Id, cacheKey2)); Assert.Null(cache.GetById("- some id -", cacheKey1)); // add second object - same id MockObject mock2 = new MockObject("1"); cache.Put(mock2, cacheKey2); o1 = cache.GetById(mock1.Id, cacheKey1); Assert.NotNull(o1); Assert.AreEqual(mock1.Id, o1.Id); ICmisObject o2 = cache.GetById(mock2.Id, cacheKey2); Assert.NotNull(o2); Assert.AreEqual(mock2.Id, o2.Id); // add third object - other id MockObject mock3 = new MockObject("3"); cache.Put(mock3, cacheKey1); o1 = cache.GetById(mock1.Id, cacheKey1); Assert.NotNull(o1); Assert.AreEqual(mock1.Id, o1.Id); o2 = cache.GetById(mock2.Id, cacheKey2); Assert.NotNull(o2); Assert.AreEqual(mock2.Id, o2.Id); ICmisObject o3 = cache.GetById(mock3.Id, cacheKey1); Assert.NotNull(o3); Assert.AreEqual(mock3.Id, o3.Id); }
/// <summary> /// Synchronize changes made to a particular CMIS object. /// </summary> private bool CrawlCmisObject(ICmisObject cmisObject) { bool success = true; if (cmisObject is DotCMIS.Client.Impl.Folder) { var remoteSubFolder = cmisObject as IFolder; // Look for the local equivalent. var localFolderItem = database.GetFolderSyncItemFromRemotePath(remoteSubFolder.Path); while (true) { // If other local folders have the same id, they are obsolete and must be deteled. var foldersToDelete = database.GetAllFoldersWithCmisId(cmisObject.Id).Where(p => p.RemotePath != remoteSubFolder.Path); foreach (var folderToDelete in foldersToDelete) { success &= RemoveFolderLocally(folderToDelete.LocalPath); } ; if (localFolderItem != null || remoteSubFolder.IsRootFolder) { break; } // Go up one level before performing the same thing. remoteSubFolder = remoteSubFolder.Parents[0]; //TODO: Fix Parents[0] for multi-parent repositories localFolderItem = database.GetFolderSyncItemFromRemotePath(remoteSubFolder.Path); } ; success &= CrawlSync(remoteSubFolder, remoteSubFolder.Path, localFolderItem.LocalPath); } else if (cmisObject is DotCMIS.Client.Impl.Document) { var remoteDocument = cmisObject as IDocument; // Apply the change on all paths via which it is applicable. foreach (IFolder remoteIFolder in remoteDocument.Parents) { if (PathIsApplicable(remoteIFolder.Path)) { Logger.Debug("Document change is applicable:" + remoteIFolder); var localFolderItem = database.GetFolderSyncItemFromRemotePath(remoteIFolder.Path); var localFolder = localFolderItem.LocalPath; var remoteDocumentPath = CmisUtils.PathCombine(remoteIFolder.Path, repoInfo.CmisProfile.localFilename(remoteDocument)); var documentItem = SyncItemFactory.CreateFromRemoteDocument(remoteDocumentPath, remoteDocument, repoInfo, database); success &= CrawlRemoteDocument(remoteDocument, documentItem.RemotePath, localFolder, null); } } } return(success); }
/// <summary> /// Process a detected deletion. /// </summary> /// <param name="remoteFolder">Remote folder.</param> /// <param name="localFolder">Local folder.</param> /// <param name="pathname">Pathname.</param> /// <returns>Whether the delete has now been synchronized, so that no further action is needed</returns> private bool WatcherSyncDelete(string remoteFolder, string localFolder, string pathname, Grace grace) { SleepWhileSuspended(); // In many programs (like Microsoft Word), deletion is often just a save: // 1. Save data to temporary file ~wrdxxxx.tmp // 2. Delete Example.doc // 3. Rename ~wrdxxxx.tmp to Example.doc // See https://support.microsoft.com/en-us/kb/211632 // So, upon deletion, wait a bit for any save operation to hopefully finalize, then sync. // This is not 100% foolproof, as saving can last for more than the grace time, but probably // the best we can do without mind-reading third-party programs. grace.WaitGraceTime(); try { if (Utils.IsMetadataFile(pathname)) { // Nothing to do return(true); } SyncItem item = database.GetSyncItemFromLocalPath(pathname); if (item == null) { // The item must be in the database return(false); } ICmisObject cmisObject = session.GetObjectByPath(item.RemotePath); if (cmisObject == null) { // the object does not exist on the server so nothing to do return(true); } cmisObject.Delete(true); // Folder or File database.RemoveFolder(item); database.RemoveFile(item); // Remove metadata if exists if (File.Exists(pathname + ".metadata")) { File.Delete(pathname + ".metadata"); database.RemoveMetadataFile(item); } return(true); } catch (Exception e) { ProcessRecoverableException("Could Not process Watch Sync Delete : ", e); return(false); } }
/* * TODO: enable support for properties * [Parameter(Position = 4, Mandatory = false)] * public Hashtable Properties { get; set; } */ protected override void EndProcessing() { var navigation = new CmisNavigation(CmisSession, WorkingFolder); ICmisObject obj = (Object != null) ? Object : navigation.Get(Path); /* * if (Properties != null || !String.IsNullOrEmpty(Name)) * { * var props = Utilities.HashtableToDict(Properties); * if (!String.IsNullOrEmpty(Name)) * { * props[PropertyIds.Name] = Name; * } * obj = obj.UpdateProperties(props); * } */ if (!String.IsNullOrEmpty(Name)) { var props = new Dictionary <string, object>() { { PropertyIds.Name, Name } }; obj = obj.UpdateProperties(props); } // check if we should update content if (LocalFile == null && !HasContent()) { WriteObject(obj); return; } // otherwise the object must be a document var doc = obj as IDocument; if (doc == null) { var ex = new CmisObjectNotFoundException("The provided object is not a Document"); ThrowTerminatingError(new ErrorRecord(ex, "UpdateObjNotDocument", ErrorCategory.InvalidArgument, Object)); } var stream = GetContentStream(); stream.FileName = obj.Name; // important, as may not set try { var result = doc.SetContentStream(stream, true); WriteObject(result == null ? doc : result); } finally { stream.Stream.Close(); } }
public static bool?CanGetFolderTree(this ICmisObject obj) { if (obj.IsActionAllowed(Actions.CanGetDescendants) == true) { return(true); } else { return(obj.IsActionAllowed(Actions.CanGetFolderTree)); } }
/// <summary> /// Removes all sync ignores flags from the given cmis object /// </summary> /// <param name="obj">Remote CMIS Object.</param> public static void RemoveAllSyncIgnores(this ICmisObject obj) { Dictionary <string, object> properties = new Dictionary <string, object>(); var ids = obj.SecondaryObjectTypeIds(); if (ids.Remove("gds:sync")) { properties.Add(PropertyIds.SecondaryObjectTypeIds, ids); obj.UpdateProperties(properties, true); } }
/// <summary> /// Ignore folders and documents with a name that contains a slash. /// While it is very rare, Documentum is known to allow that and mistakenly present theses as CMIS object, violating the CMIS specification. /// </summary> public bool RemoteObjectWorthSyncing(ICmisObject cmisObject) { if (cmisObject.Name.Contains('/')) { Logger.Warn("Ignoring remote object " + cmisObject.Name + " as it contains a slash. The CMIS specification forbids slashes in path elements (paragraph 2.1.5.3), please report the bug to your server vendor"); return(false); } else { return(true); } }
private string GetCmisObjectPath(ICmisObject obj) { if (obj is IFolder) { return(((IFolder)obj).Path); } else if (obj is IDocument) { return(((IDocument)obj).Paths[0]); } return("unknown"); }
/// <summary> /// Indicates if all children are ignored. /// </summary> /// <returns><c>true</c>, if all children are ignored, <c>false</c> otherwise.</returns> /// <param name="obj">Remote cmis object.</param> public static bool AreAllChildrenIgnored(this ICmisObject obj) { IList <string> devices = obj.IgnoredDevices(); if (devices.Contains("*") || devices.Contains(ConfigManager.CurrentConfig.DeviceId.ToString().ToLower())) { return(true); } else { return(false); } }
/// <summary> /// Removes the sync ignore flags of the given device Ids from the given cmis object. /// </summary> /// <param name="obj">Remote CMIS Object.</param> /// <param name="deviceIds">Device identifiers which should be removed from ignore list.</param> public static void RemoveSyncIgnore(this ICmisObject obj, params string[] deviceIds) { var ids = obj.SecondaryObjectTypeIds(); if (ids.Contains("gds:sync")) { var devices = obj.IgnoredDevices(); if (deviceIds == null || deviceIds.Length == 0) { if (devices.Remove("*") || devices.Remove(ConfigManager.CurrentConfig.DeviceId.ToString().ToLower())) { if (devices.Count > 0) { Dictionary <string, object> properties = new Dictionary <string, object>(); properties.Add("gds:ignoreDeviceIds", devices); obj.UpdateProperties(properties, true); } else { obj.RemoveAllSyncIgnores(); } } } else { bool changed = false; foreach (var removeId in deviceIds) { if (devices.Remove(removeId)) { changed = true; } } if (changed) { if (devices.Count > 0) { Dictionary <string, object> properties = new Dictionary <string, object>(); properties.Add("gds:ignoreDeviceIds", devices); obj.UpdateProperties(properties, true); } else { obj.RemoveAllSyncIgnores(); } } } } }
protected override void ProcessRecord() { var cmisPath = new CmisPath(Path); var navigation = new CmisNavigation(CmisSession, WorkingFolder); ICmisObject obj = null; try { obj = navigation.Get(cmisPath); } catch (CmisBaseException e) { ThrowTerminatingError(new ErrorRecord(e, "GetObjectFailed", ErrorCategory.ResourceUnavailable, Path)); return; } var nameIsEmpty = String.IsNullOrEmpty(Name); if (!(obj is IFolder) || (!cmisPath.HasTrailingSlash() && nameIsEmpty && RecursionDepth < 1)) { WriteObject(obj); return; } WildcardPattern wildcard = new WildcardPattern("*"); if (!nameIsEmpty) { wildcard = Exact.IsPresent ? new WildcardPattern(Name) : new WildcardPattern(Name + "*", WildcardOptions.IgnoreCase); } int depth = RecursionDepth == 0 ? 1 : RecursionDepth; //otherwise we want the descendants of the folder var folder = obj as IFolder; IList <ITree <IFileableCmisObject> > descendants; try { descendants = folder.GetDescendants(depth); } catch (CmisBaseException e) { ThrowTerminatingError(new ErrorRecord(e, "GetDescendatnsFailed", ErrorCategory.ResourceUnavailable, Path)); return; } WriteTreeList(descendants, wildcard); }
/// <inheritdoc/> public void PutPath(string path, ICmisObject cmisObject, string cacheKey) { // no path, no object, no id, no cache key - no cache if (path == null || cmisObject == null || cmisObject.Id == null || cacheKey == null) { return; } lock (cacheLock) { Put(cmisObject, cacheKey); pathToIdCache.Add(path, cmisObject.Id); } }
/// <summary> /// Apply a remote change for Deleted. /// </summary> private bool ApplyRemoteChangeDelete(IChangeEvent change) { try { ICmisObject remoteObject = session.GetObject(change.ObjectId); if (null != remoteObject) { // should be moveObject Logger.Info("Ignore moveObject for id " + change.ObjectId); return(true); } } catch (CmisObjectNotFoundException) { } catch (Exception e) { Logger.Warn("Exception when GetObject for " + change.ObjectId + " : ", e); } string savedDocumentPath = database.GetRemoteFilePath(change.ObjectId); // FIXME use SyncItem to differentiate between local path and remote path if (null != savedDocumentPath) { Logger.Info("Remove local document: " + savedDocumentPath); if (File.Exists(savedDocumentPath)) { File.Delete(savedDocumentPath); } database.RemoveFile(SyncItemFactory.CreateFromRemotePath(savedDocumentPath, repoinfo)); Logger.Info("Removed local document: " + savedDocumentPath); return(true); } string savedFolderPath = database.GetFolderPath(change.ObjectId); if (null != savedFolderPath) { Logger.Info("Remove local folder: " + savedFolderPath); if (Directory.Exists(savedFolderPath)) { Directory.Delete(savedFolderPath, true); database.RemoveFolder(SyncItemFactory.CreateFromRemotePath(savedFolderPath, repoinfo)); } Logger.Info("Removed local folder: " + savedFolderPath); return(true); } return(true); }
private bool isLink(ICmisObject cmisObject) { IObjectType parent = cmisObject.ObjectType.GetParentType(); while (parent != null) { if (parent.Id.Equals("I:cm:link")) { return(true); } parent = parent.GetParentType(); } return(false); }
/// <summary> /// Secondary object type identifiers. /// </summary> /// <returns>The object type identifiers.</returns> /// <param name="obj">Cmis object.</param> public static IList <string> SecondaryObjectTypeIds(this ICmisObject obj) { IList <string> ids = new List <string>(); if (obj.SecondaryTypes != null) { foreach (var secondaryType in obj.SecondaryTypes) { ids.Add(secondaryType.Id); } } return(ids); }
public bool TryGet(CmisPath cmisPath, out ICmisObject obj) { var path = _curDir.Combine(cmisPath).ToString(); obj = null; try { obj = _session.GetObjectByPath(path); } catch (CmisObjectNotFoundException) { return(false); } return(true); }
public void PutPath(string path, ICmisObject cmisObject, string cacheKey) { }
public void Put(ICmisObject cmisObject, string cacheKey) { }
public bool TryGet(CmisPath cmisPath, out ICmisObject obj) { var path = _curDir.Combine(cmisPath).ToString(); obj = null; try { obj = _session.GetObjectByPath(path); } catch (CmisObjectNotFoundException) { return false; } return true; }
/// <summary> /// Synchronize changes made to a particular CMIS object. /// </summary> private void CrawlCmisObject(ICmisObject cmisObject) { if (cmisObject is DotCMIS.Client.Impl.Folder) { var remoteSubFolder = cmisObject as IFolder; // Look for the local equivalent. var localFolderItem = database.GetFolderSyncItemFromRemotePath(remoteSubFolder.Path); while (true) { // If other local folders have the same id, they are obsolete and must be deteled. var foldersToDelete = database.GetAllFoldersWithCmisId(cmisObject.Id).Where(p => p.RemotePath != remoteSubFolder.Path); foreach (var folderToDelete in foldersToDelete) { RemoveFolderLocally(folderToDelete.LocalPath); }; if (localFolderItem != null || remoteSubFolder.IsRootFolder) break; // Go up one level before performing the same thing. remoteSubFolder = remoteSubFolder.Parents[0]; //TODO: Fix Parents[0] for multi-parent repositories localFolderItem = database.GetFolderSyncItemFromRemotePath(remoteSubFolder.Path); }; CrawlSync(remoteSubFolder, remoteSubFolder.Path, localFolderItem.LocalPath); } else if (cmisObject is DotCMIS.Client.Impl.Document) { var remoteDocument = cmisObject as IDocument; // Apply the change on all paths via which it is applicable. foreach (IFolder remoteIFolder in remoteDocument.Parents) { if (PathIsApplicable(remoteIFolder.Path)) { Logger.Debug("Document change is applicable:" + remoteIFolder); var localFolderItem = database.GetFolderSyncItemFromRemotePath(remoteIFolder.Path); var localFolder = localFolderItem.LocalPath; var remoteDocumentPath = CmisUtils.PathCombine(remoteIFolder.Path, repoInfo.CmisProfile.localFilename(remoteDocument)); var documentItem = SyncItemFactory.CreateFromRemoteDocument(remoteDocumentPath, remoteDocument, repoInfo, database); CrawlRemoteDocument(remoteDocument, documentItem.RemotePath, localFolder, null); } } } }
/// <summary> /// Set the last modification date of a local file or folder to whatever a remote cmisObject's last modfication date is. /// </summary> private void SetLastModifiedDate(ICmisObject remoteObject, string filepath, Dictionary<string, string[]> metadata) { try { DateTime? lastModificationDate = getUtcLastModificationDate(remoteObject, metadata); if (lastModificationDate != null) { File.SetLastWriteTimeUtc(filepath, lastModificationDate.Value); if (Logger.IsDebugEnabled) { if (!File.GetLastWriteTimeUtc(filepath).Equals(lastModificationDate)) { throw new InvalidOperationException("SetLastWriteTimeUtc failed"); } } } else { throw new ArgumentException("The remote object Last Modification Date could not be determined"); } } catch (Exception e) { Logger.Debug(String.Format("Failed to set last modified date for the local file: {0}", filepath), e); } }
private DateTime? getUtcLastModificationDate(ICmisObject remoteObject, Dictionary<string, string[]> metadata = null) { DateTime? date = remoteObject.LastModificationDate; if (date == null && metadata != null) { string[] cmisModDate; if (metadata.TryGetValue("cmis:lastModificationDate", out cmisModDate) && cmisModDate.Length == 3) // TODO explain 3 and 2 in following line { date = DateTime.Parse(cmisModDate[2]); } } if (date != null) { return ((DateTime)date).ToUniversalTime(); } else { return null; } }
private void VerifyThatRenameSolverIsCalled( IFileSystemInfo localObject, ICmisObject remoteObject, ContentChangeType localChange = ContentChangeType.NONE, ContentChangeType remoteChange = ContentChangeType.NONE) { this.changeSolver.Verify(s => s.Solve(It.IsAny<IFileSystemInfo>(), It.IsAny<IObjectId>(), It.IsAny<ContentChangeType>(), It.IsAny<ContentChangeType>()), Times.Never()); this.renameSolver.Verify(s => s.Solve(localObject, remoteObject, localChange, remoteChange), Times.Once()); }
public CmisCollectionContainsObjectConstraint(ICmisObject obj) { _object = obj; }
public CmisObjectEqualityConstraint(ICmisObject obj) { _object = obj; }
private string GetCmisObjectPath(ICmisObject obj) { if (obj is IFolder) { return ((IFolder)obj).Path; } else if (obj is IDocument) { return ((IDocument)obj).Paths[0]; } return "unknown"; }
private bool isLink(ICmisObject cmisObject) { IObjectType parent = cmisObject.ObjectType.GetParentType(); while (parent != null) { if(parent.Id.Equals("I:cm:link")){ return true; } parent = parent.GetParentType(); } return false; }
public RemoteObjectException(ICmisObject cmisObject, Exception e) : base("Could not access remote object", e) { CmisObject = cmisObject; }
public static Mock<ISession> AddRemoteObject(this Mock<ISession> session, ICmisObject remoteObject) { session.Setup(s => s.GetObject(It.Is<string>(id => id == remoteObject.Id))).Returns(remoteObject); session.Setup(s => s.GetObject(It.Is<IObjectId>(o => o.Id == remoteObject.Id))).Returns(remoteObject); session.Setup(s => s.GetObject(It.Is<IObjectId>(o => o.Id == remoteObject.Id), It.IsAny<IOperationContext>())).Returns(remoteObject); HashSet<string> paths = new HashSet<string>(); if (remoteObject is IFolder) { paths.Add((remoteObject as IFolder).Path); if ((remoteObject as IFolder).Paths != null) { foreach (string path in (remoteObject as IFolder).Paths) { paths.Add(path); } } } else if (remoteObject is IDocument) { if ((remoteObject as IDocument).Paths != null) { foreach (string path in (remoteObject as IDocument).Paths) { paths.Add(path); } } } foreach (string path in paths) { session.Setup(s => s.GetObjectByPath(It.Is<string>(p => p == path))).Returns(remoteObject); } return session; }
public Constraint IsEqualObject(ICmisObject expected) { return new CmisObjectEqualityConstraint(expected); }
/// <summary> /// Retrieve the CMIS metadata of a document. /// </summary> /// <returns>a dictionary in which each key is a type id and each value is a couple indicating the mode ("readonly" or "ReadWrite") and the value itself.</returns> public static Dictionary<string, string[]> FetchMetadata(ICmisObject o, IObjectType typeDef) { Dictionary<string, string[]> metadata = new Dictionary<string, string[]>(); IList<IPropertyDefinition> propertyDefs = typeDef.PropertyDefinitions; // Get metadata. foreach (IProperty property in o.Properties) { // Mode string mode = "readonly"; foreach (IPropertyDefinition propertyDef in propertyDefs) { if (propertyDef.Id.Equals("cmis:name")) { Updatability updatability = propertyDef.Updatability; mode = updatability.ToString(); } } // Value if (property.IsMultiValued) { metadata.Add(property.Id, new string[] { property.DisplayName, mode, property.ValuesAsString }); } else { metadata.Add(property.Id, new string[] { property.DisplayName, mode, property.ValueAsString }); } } return metadata; }
public Constraint ContainsObject(ICmisObject expected) { return new CmisCollectionContainsObjectConstraint(expected); }
private void SetPermissions(ICmisObject remoteObject, string filepath, Dictionary<string, string[]> metadata) { // Should the local file be made read-only? // Check ther permissions of the current user to the remote document. bool readOnly = !remoteObject.AllowableActions.Actions.Contains(Actions.CanSetContentStream); new FileInfo(filepath).IsReadOnly = readOnly; }
public IList<string> Delete(ICmisObject obj, bool recursive) { if (recursive && obj is IFolder) { return ((IFolder)obj).DeleteTree(false, UnfileObject.Delete, true); } try { obj.Delete(false); } catch (CmisBaseException) { return new string[] { GetCmisObjectPath(obj) }; } return null; }
public void Put(ICmisObject cmisObject, string cacheKey) { // no object, no id, no cache key - no cache if (cmisObject == null || cmisObject.Id == null || cacheKey == null) { return; } Lock(); try { IDictionary<string, ICmisObject> cacheKeyDict = objectCache.Get(cmisObject.Id); if (cacheKeyDict == null) { cacheKeyDict = new Dictionary<string, ICmisObject>(); objectCache.Add(cmisObject.Id, cacheKeyDict); } cacheKeyDict[cacheKey] = cmisObject; // folders may have a path, use it! string path = cmisObject.GetPropertyValue(PropertyIds.Path) as string; if (path != null) { pathToIdCache.Add(path, cmisObject.Id); } } finally { Unlock(); } }
public void PutPath(string path, ICmisObject cmisObject, string cacheKey) { // no path, no object, no id, no cache key - no cache if (path == null || cmisObject == null || cmisObject.Id == null || cacheKey == null) { return; } Lock(); try { Put(cmisObject, cacheKey); pathToIdCache.Add(path, cmisObject.Id); } finally { Unlock(); } }
/// <summary> /// Updates the object. /// </summary> /// <param name='session'> /// Session from where the object should be requested. /// </param> public void UpdateObject(ISession session) { this.CmisObject = session.GetObject(this.ObjectId, OperationContextFactory.CreateNonCachingPathIncludingContext(session)); }
private void SetRemoteObject(ISyncEvent e, ICmisObject remote) { if (e is FileEvent) { (e as FileEvent).RemoteFile = remote as IDocument; } else if (e is CrawlRequestEvent) { (e as CrawlRequestEvent).RemoteFolder = remote as IFolder; } else { (e as FolderEvent).RemoteFolder = remote as IFolder; } }