PortCMIS: more code,more test, more documentation
git-svn-id: https://svn.apache.org/repos/asf/chemistry/portcmis/trunk@1743666 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/PortCMIS/client/ClientCaches.cs b/PortCMIS/client/ClientCaches.cs
index fdfdc9e..9494ba4 100644
--- a/PortCMIS/client/ClientCaches.cs
+++ b/PortCMIS/client/ClientCaches.cs
@@ -83,12 +83,25 @@
ICmisObject GetByPath(string path, string cacheKey);
/// <summary>
+ /// Gets the object ID by path.
+ /// </summary>
+ /// <param name="path">the path</param>
+ /// <returns>the object ID</returns>
+ string GetObjectIdByPath(string path);
+
+ /// <summary>
/// Removes an object from the cache.
/// </summary>
/// <param name="objectId">the object ID</param>
void Remove(string objectId);
/// <summary>
+ /// Removes a path from the cache.
+ /// </summary>
+ /// <param name="path">the path</param>
+ void RemovePath(string path);
+
+ /// <summary>
/// Clears the cache.
/// </summary>
void Clear();
@@ -126,9 +139,15 @@
public ICmisObject GetByPath(string path, string cacheKey) { return null; }
/// <inheritdoc/>
+ public string GetObjectIdByPath(string path) { return null; }
+
+ /// <inheritdoc/>
public void Remove(string objectId) { }
/// <inheritdoc/>
+ public void RemovePath(string path) { }
+
+ /// <inheritdoc/>
public void Clear() { }
/// <inheritdoc/>
@@ -343,6 +362,16 @@
}
/// <inheritdoc/>
+ public string GetObjectIdByPath(string path)
+ {
+ lock (cacheLock)
+ {
+ return pathToIdCache.Get(path);
+ }
+ }
+
+
+ /// <inheritdoc/>
public void Remove(string objectId)
{
if (objectId == null)
@@ -357,6 +386,20 @@
}
/// <inheritdoc/>
+ public void RemovePath(string path)
+ {
+ if (path == null)
+ {
+ return;
+ }
+
+ lock (cacheLock)
+ {
+ pathToIdCache.Remove(path);
+ }
+ }
+
+ /// <inheritdoc/>
public int CacheSize
{
get { return cacheSize; }
diff --git a/PortCMIS/client/ClientImpl.cs b/PortCMIS/client/ClientImpl.cs
index 59abe28..693cdd5 100644
--- a/PortCMIS/client/ClientImpl.cs
+++ b/PortCMIS/client/ClientImpl.cs
@@ -642,10 +642,8 @@
/// <inheritdoc/>
public ICmisObject GetObjectByPath(string path, IOperationContext context)
{
- if (path == null)
- {
- throw new ArgumentNullException("path");
- }
+ CheckPath(path);
+
if (context == null)
{
throw new ArgumentNullException("context");
@@ -835,6 +833,89 @@
}
/// <inheritdoc/>
+ public bool Exists(IObjectId objectId)
+ {
+ if (objectId == null)
+ {
+ throw new ArgumentNullException("objectId");
+ }
+ return Exists(objectId.Id);
+ }
+
+ /// <inheritdoc/>
+ public bool Exists(string objectId)
+ {
+ if (objectId == null)
+ {
+ throw new ArgumentNullException(objectId);
+ }
+
+ try
+ {
+ Binding.GetObjectService().GetObject(RepositoryId, objectId, "cmis:objectId", false,
+ IncludeRelationships.None, "cmis:none", false, false, null);
+ return true;
+ }
+ catch (CmisObjectNotFoundException)
+ {
+ RemoveObjectFromCache(objectId);
+ return false;
+ }
+ }
+
+ /// <inheritdoc/>
+ public bool ExistsPath(string path)
+ {
+ CheckPath(path);
+
+ try
+ {
+ IObjectData obj = Binding.GetObjectService().GetObjectByPath(RepositoryId, path, "cmis:objectId",
+ false, IncludeRelationships.None, "cmis:none", false, false, null);
+
+ string cacheObjectId = Cache.GetObjectIdByPath(path);
+ if (cacheObjectId != obj.Id)
+ {
+ Cache.RemovePath(path);
+ }
+
+ return true;
+ }
+ catch (CmisObjectNotFoundException)
+ {
+ Cache.RemovePath(path);
+ return false;
+ }
+ }
+
+ /// <inheritdoc/>
+ public bool ExistsPath(string parentPath, string name)
+ {
+ if (parentPath == null || parentPath.Length < 1)
+ {
+ throw new ArgumentException("Parent path must be set!", "parentPath");
+ }
+ if (parentPath[0] != '/')
+ {
+ throw new ArgumentException("Parent path must start with a '/'!", "parentPath");
+ }
+ if (name == null || name.Length < 1)
+ {
+ throw new ArgumentException("Name must be set!", "name");
+ }
+
+ StringBuilder path = new StringBuilder(parentPath.Length + name.Length + 2);
+ path.Append(parentPath);
+ if (!parentPath.EndsWith("/"))
+ {
+ path.Append('/');
+ }
+ path.Append(name);
+
+ return ExistsPath(path.ToString());
+ }
+
+ /// <inheritdoc/>
public void RemoveObjectFromCache(IObjectId objectId)
{
if (objectId == null || objectId.Id == null)
@@ -1352,6 +1433,21 @@
Binding.GetPolicyService().RemovePolicy(RepositoryId, id, objectId.Id, null);
}
}
+
+ /// <summary>
+ /// Checks if the given string is a valid path.
+ /// </summary>
+ protected void CheckPath(string path)
+ {
+ if (path == null || path.Length < 1)
+ {
+ throw new ArgumentException("Invalid path!");
+ }
+ if (path[0] != '/')
+ {
+ throw new ArgumentException("Path must start with a '/'!");
+ }
+ }
}
internal class QueryStatement : IQueryStatement
diff --git a/PortCMIS/client/ClientIntf.cs b/PortCMIS/client/ClientIntf.cs
index a6c73ff..0fee33e 100644
--- a/PortCMIS/client/ClientIntf.cs
+++ b/PortCMIS/client/ClientIntf.cs
@@ -400,6 +400,43 @@
IDocument GetLatestDocumentVersion(IObjectId objectId, bool major, IOperationContext context);
/// <summary>
+ /// Checks if an object with given object ID exists in the repository and is visible for the current user.
+ /// </summary>
+ /// <remarks>If the object doesn't exist (anymore), it is removed from the cache.</remarks>
+ /// <param name="objectId">the object ID</param>
+ /// <returns><c>true</c> if the object exists in the repository, <c>false</c> otherwise</returns>
+ /// <cmis>1.0</cmis>
+ bool Exists(IObjectId objectId);
+
+ /// <summary>
+ /// Checks if an object with given object ID exists in the repository and is visible for the current user.
+ /// </summary>
+ /// <remarks>If the object doesn't exist (anymore), it is removed from the cache.</remarks>
+ /// <param name="objectId">the object ID</param>
+ /// <returns><c>true</c> if the object exists in the repository, <c>false</c> otherwise</returns>
+ /// <cmis>1.0</cmis>
+ bool Exists(string objectId);
+
+ /// <summary>
+ /// Checks if an object with given path exists in the repository and is visible for the current user.
+ /// </summary>
+ /// <remarks>If the object doesn't exist (anymore), it is removed from the cache.</remarks>
+ /// <param name="path">the path</param>
+ /// <returns><c>true</c> if the object exists in the repository, <c>false</c> otherwise</returns>
+ /// <cmis>1.0</cmis>
+ bool ExistsPath(string path);
+
+ /// <summary>
+ /// Checks if an object with given path exists in the repository and is visible for the current user.
+ /// </summary>
+ /// <remarks>If the object doesn't exist (anymore), it is removed from the cache.</remarks>
+ /// <param name="parentPath">the path of the parent folder</param>
+ /// <param name="name">the (path segment) name of the object in the folder</param>
+ /// <returns><c>true</c> if the object exists in the repository, <c>false</c> otherwise</returns>
+ /// <cmis>1.0</cmis>
+ bool ExistsPath(string parentPath, string name);
+
+ /// <summary>
/// Removes the given object from the cache.
/// </summary>
/// <param name="objectId">the object ID</param>
@@ -1529,6 +1566,11 @@
IAcl Acl { get; }
/// <summary>
+ /// Checks whether the given allowable action is set or not.
+ /// </summary>
+ bool HasAllowableAction(PortCMIS.Enums.Action action);
+
+ /// <summary>
/// Deletes this object.
/// </summary>
/// <remarks>
diff --git a/PortCMIS/client/ClientObjects.cs b/PortCMIS/client/ClientObjects.cs
index a1ea256..1f964a3 100644
--- a/PortCMIS/client/ClientObjects.cs
+++ b/PortCMIS/client/ClientObjects.cs
@@ -25,6 +25,7 @@
using PortCMIS.Exceptions;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Numerics;
using System.Text;
@@ -544,6 +545,18 @@
}
}
+ /// <inheritdoc/>
+ public virtual bool HasAllowableAction(PortCMIS.Enums.Action action)
+ {
+ IAllowableActions currentAllowableActions = AllowableActions;
+ if (currentAllowableActions == null || currentAllowableActions.Actions == null)
+ {
+ throw new Exception("Allowable Actions are not available!");
+ }
+
+ return currentAllowableActions.Actions.Contains(action);
+ }
+
// --- renditions ---
/// <inheritdoc/>
@@ -696,6 +709,20 @@
}
}
}
+
+ /// <inheritdoc/>
+ public override string ToString()
+ {
+ lock (objectLock)
+ {
+ if (objectType == null)
+ {
+ return "<unknown>";
+ }
+
+ return objectType.BaseTypeId + " (" + objectType.Id + "): " + Id;
+ }
+ }
}
/// <summary>
@@ -930,8 +957,15 @@
public virtual IDocument Copy(IObjectId targetFolderId, IDictionary<string, object> properties, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context)
{
-
- IObjectId newId = Session.CreateDocumentFromSource(this, properties, targetFolderId, versioningState, policies, addAces, removeAces);
+ IObjectId newId;
+ try
+ {
+ newId = Session.CreateDocumentFromSource(this, properties, targetFolderId, versioningState, policies, addAces, removeAces);
+ }
+ catch (CmisNotSupportedException nse)
+ {
+ newId = CopyViaClient(targetFolderId, properties, versioningState, policies, addAces, removeAces);
+ }
// if no context is provided the object will not be fetched
if (context == null || newId == null)
@@ -954,6 +988,61 @@
return Copy(targetFolderId, null, null, null, null, null, Session.DefaultContext);
}
+
+ /// <summary>
+ /// Copies the document manually. The content is streamed from the repository and back.
+ /// </summary>
+ protected IObjectId CopyViaClient(IObjectId targetFolderId, IDictionary<string, object> properties,
+ VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces)
+ {
+ IDictionary<string, object> newProperties = new Dictionary<string, object>();
+
+ IOperationContext allPropsContext = Session.CreateOperationContext();
+ allPropsContext.FilterString = "*";
+ allPropsContext.IncludeAcls = false;
+ allPropsContext.IncludeAllowableActions = false;
+ allPropsContext.IncludePathSegments = false;
+ allPropsContext.IncludePolicies = false;
+ allPropsContext.IncludeRelationships = IncludeRelationships.None;
+ allPropsContext.RenditionFilterString = "cmis:none";
+
+ IDocument allPropsDoc = (IDocument)Session.GetObject(this, allPropsContext);
+
+ foreach (IProperty prop in allPropsDoc.Properties)
+ {
+ if (prop.PropertyDefinition.Updatability == Updatability.ReadWrite
+ || prop.PropertyDefinition.Updatability == Updatability.OnCreate)
+ {
+ newProperties.Add(prop.Id, prop.Value);
+ }
+ }
+
+ if (properties != null)
+ {
+ foreach (KeyValuePair<string, object> prop in properties)
+ {
+ newProperties[prop.Key] = prop.Value;
+ }
+ }
+
+ IContentStream contentStream = allPropsDoc.GetContentStream();
+ try
+ {
+ return Session.CreateDocument(newProperties, targetFolderId, contentStream, versioningState, policies, addAces, removeAces);
+ }
+ finally
+ {
+ if (contentStream != null)
+ {
+ Stream stream = contentStream.Stream;
+ if (stream != null)
+ {
+ stream.Dispose();
+ }
+ }
+ }
+ }
+
/// <inheritdoc/>
public virtual void DeleteAllVersions()
{
@@ -1902,6 +1991,12 @@
return value.ToString();
}
+
+ /// <inheritdoc/>
+ public override string ToString()
+ {
+ return Id + ": " + ValuesAsString;
+ }
}
/// <summary>
diff --git a/PortCMIS/client/ClientUtils.cs b/PortCMIS/client/ClientUtils.cs
index 2070473..f7f48b9 100644
--- a/PortCMIS/client/ClientUtils.cs
+++ b/PortCMIS/client/ClientUtils.cs
@@ -572,6 +572,59 @@
{
Id = id;
}
+
+ /// <inheritdoc/>
+ public override string ToString()
+ {
+ return Id;
+ }
+
+ /// <inheritdoc/>
+ public override int GetHashCode()
+ {
+ return Id.GetHashCode();
+ }
+
+ /// <inheritdoc/>
+ public override bool Equals(object obj)
+ {
+ return this.Equals(obj as ObjectId);
+ }
+
+ public bool Equals(ObjectId oid)
+ {
+ if (Object.ReferenceEquals(oid, null))
+ {
+ return false;
+ }
+
+ if (Object.ReferenceEquals(this, oid))
+ {
+ return true;
+ }
+
+ if (this.GetType() != oid.GetType())
+ {
+ return false;
+ }
+
+ return Id == oid.Id;
+ }
+
+ public static bool operator ==(ObjectId id1, ObjectId id2)
+ {
+ if (object.ReferenceEquals(id1, null))
+ {
+ return object.ReferenceEquals(id2, null);
+ }
+
+ return id1.Id == id2.Id;
+ }
+
+ public static bool operator !=(ObjectId id1, ObjectId id2)
+ {
+ return !(id1 == id2);
+ }
}
/// <summary>
diff --git a/PortCMIS/const/ClientVersion.cs b/PortCMIS/const/ClientVersion.cs
index 699e796..12625d5 100644
--- a/PortCMIS/const/ClientVersion.cs
+++ b/PortCMIS/const/ClientVersion.cs
@@ -1,8 +1,21 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* Kind, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
namespace PortCMIS
{
diff --git a/PortCMIS/data/DataImpl.cs b/PortCMIS/data/DataImpl.cs
index 1e67cfc..e3693dd 100644
--- a/PortCMIS/data/DataImpl.cs
+++ b/PortCMIS/data/DataImpl.cs
@@ -1144,6 +1144,12 @@
/// <inheritdoc/>
public bool IsDirect { get; set; }
+
+ /// <inheritdoc/>
+ public override string ToString()
+ {
+ return PrincipalId + ": " + (Permissions == null ? "?" : String.Join(", ", Permissions));
+ }
}
/// <summary>
@@ -1156,6 +1162,12 @@
/// <inheritdoc/>
public bool? IsExact { get; set; }
+
+ /// <inheritdoc/>
+ public override string ToString()
+ {
+ return "ACL: " + (Aces == null ? "empty" : String.Join(" | ", Aces));
+ }
}
/// <summary>
@@ -1174,6 +1186,14 @@
/// <inheritdoc/>
public Stream Stream { get; set; }
+
+ /// <inheritdoc/>
+ public override string ToString()
+ {
+ return "Content Stream : " + FileName + " (" +MimeType +") " +
+ (Length == null ? "" : Length + " bytes" +
+ (Stream == null ? " no stream" : Stream.ToString()));
+ }
}
/// <summary>
/// Simple Content Stream implementation that indicates a partial stream.
diff --git a/PortCMISTests/SimpleCmisTest.cs b/PortCMISTests/SimpleCmisTest.cs
index d603743..a2b300b 100644
--- a/PortCMISTests/SimpleCmisTest.cs
+++ b/PortCMISTests/SimpleCmisTest.cs
@@ -87,9 +87,9 @@
Assert.IsNotNull(root.AllowableActions);
Assert.IsNotNull(root.AllowableActions.Actions);
Assert.IsTrue(root.AllowableActions.Actions.Count > 0);
- Assert.IsTrue(root.AllowableActions.Actions.Contains(PortCMIS.Enums.Action.CanGetProperties));
- Assert.IsFalse(root.AllowableActions.Actions.Contains(PortCMIS.Enums.Action.CanGetFolderParent));
- Assert.IsFalse(root.AllowableActions.Actions.Contains(PortCMIS.Enums.Action.CanMoveObject));
+ Assert.IsTrue(root.HasAllowableAction(PortCMIS.Enums.Action.CanGetProperties));
+ Assert.IsFalse(root.HasAllowableAction(PortCMIS.Enums.Action.CanGetFolderParent));
+ Assert.IsFalse(root.HasAllowableAction(PortCMIS.Enums.Action.CanMoveObject));
foreach (ICmisObject child in root.GetChildren(oc))
{
@@ -105,31 +105,31 @@
Assert.IsNotNull(child.AllowableActions);
Assert.IsNotNull(child.AllowableActions.Actions);
Assert.IsTrue(child.AllowableActions.Actions.Count > 0);
- Assert.IsTrue(child.AllowableActions.Actions.Contains(PortCMIS.Enums.Action.CanGetProperties));
+ Assert.IsTrue(child.HasAllowableAction(PortCMIS.Enums.Action.CanGetProperties));
}
}
[TestMethod]
public void TestCreate()
{
- try
+ string testFolderName = "porttest";
+
+ if (Session.ExistsPath("/", testFolderName))
{
- ICmisObject obj = Session.GetObjectByPath("/porttest");
- obj.Delete();
- }
- catch (CmisConstraintException)
- {
- IFolder folder = Session.GetObjectByPath("/porttest") as IFolder;
- folder.DeleteTree(true, UnfileObject.Delete, true);
- }
- catch (CmisObjectNotFoundException)
- {
- // ignore
+ ICmisObject obj = Session.GetObjectByPath("/", testFolderName, OperationContextUtils.CreateMinimumOperationContext());
+ if (obj is IFolder)
+ {
+ ((IFolder)obj).DeleteTree(true, UnfileObject.Delete, true);
+ }
+ else
+ {
+ obj.Delete();
+ }
}
// create folder
IFolder root = Session.GetRootFolder();
- IFolder newFolder = CreateFolder(root, "porttest");
+ IFolder newFolder = CreateFolder(root, testFolderName);
Assert.IsNotNull(newFolder);
@@ -146,8 +146,7 @@
Assert.AreEqual(contentString, ConvertStreamToString(newContent.Stream));
// fetch it again to get the updated content stream length property
- IOperationContext ctxt = Session.CreateOperationContext();
- ctxt.FilterString = "*";
+ IOperationContext ctxt = OperationContextUtils.CreateMaximumOperationContext();
ICmisObject newObj = Session.GetObject(newDoc, ctxt);
Assert.IsTrue(newObj is IDocument);
@@ -173,15 +172,7 @@
newFolder.Delete();
- try
- {
- Session.GetObject(newFolder);
- Assert.Fail("Folder still exists.");
- }
- catch (CmisObjectNotFoundException)
- {
- // expected
- }
+ Assert.IsFalse(Session.Exists(newFolder));
}
[TestMethod]
@@ -226,6 +217,7 @@
if (newFolder != null)
{
newFolder.DeleteTree(true, UnfileObject.Delete, true);
+ Assert.IsFalse(Session.Exists(newFolder));
}
}
}
@@ -258,16 +250,95 @@
Assert.IsNotNull(content2.Stream);
Assert.AreEqual(contentString2, ConvertStreamToString(content2.Stream));
+
+ // delete the content stream
+ doc.DeleteContentStream(true);
+ Assert.IsNull(doc.ContentStreamLength);
}
finally
{
if (doc != null)
{
doc.Delete();
+ Assert.IsFalse(Session.Exists(doc));
}
}
}
+ [TestMethod]
+ public void TestVersioning()
+ {
+ IOperationContext noCacheOC = OperationContextUtils.CreateMaximumOperationContext();
+ noCacheOC.CacheEnabled = false;
+
+ IFolder rootFolder = Session.GetRootFolder();
+ IDocument doc = null;
+
+ try
+ {
+ // create document
+ string name1 = "versioned1.txt";
+ IContentStream contentStream1 = ContentStreamUtils.CreateTextContentStream(name1, "v1");
+
+ IDictionary<string, object> props = new Dictionary<string, object>();
+ props[PropertyIds.Name] = name1;
+ props[PropertyIds.ObjectTypeId] = "VersionableType";
+
+ doc = rootFolder.CreateDocument(props, contentStream1, VersioningState.Major);
+
+ // create next version
+ string name2 = "versioned2.txt";
+ IContentStream contentStream2 = ContentStreamUtils.CreateTextContentStream(name2, "v2");
+
+ IObjectId pwcId = doc.CheckOut();
+ IDocument pwc = (IDocument)Session.GetObject(pwcId, noCacheOC);
+
+ pwc.Rename(name2);
+
+ IObjectId newVersId = pwc.CheckIn(true, null, contentStream2, "version 2");
+ IDocument newVers = (IDocument)Session.GetObject(newVersId, noCacheOC);
+
+ Assert.AreEqual(name2, newVers.Name);
+ Assert.AreEqual("v2", ConvertStreamToString(newVers.GetContentStream().Stream));
+
+ IDocument latestVersion = Session.GetLatestDocumentVersion(doc);
+ Assert.AreEqual(newVers.Id, latestVersion.Id);
+
+ // create next version
+ string name3 = "versioned3.txt";
+ IContentStream contentStream3 = ContentStreamUtils.CreateTextContentStream(name3, "v3");
+
+ pwcId = doc.CheckOut();
+ pwc = (IDocument)Session.GetObject(pwcId, noCacheOC);
+
+ pwc.Rename(name3);
+
+ newVersId = pwc.CheckIn(true, null, contentStream3, "version 3");
+ newVers = (IDocument)Session.GetObject(newVersId);
+
+ Assert.AreEqual(name3, newVers.Name);
+ Assert.AreEqual("v3", ConvertStreamToString(newVers.GetContentStream().Stream));
+
+ latestVersion = Session.GetLatestDocumentVersion(doc);
+ Assert.AreEqual(newVers.Id, latestVersion.Id);
+
+ // check version history
+
+ IList<IDocument> versions = doc.GetAllVersions();
+ Assert.AreEqual(3, versions.Count);
+
+ Assert.AreEqual(latestVersion.Id, versions[0].Id);
+ Assert.AreEqual(doc.Id, versions[2].Id);
+ }
+ finally
+ {
+ if (doc != null)
+ {
+ doc.Delete();
+ Assert.IsFalse(Session.Exists(doc));
+ }
+ }
+ }
[TestMethod]
public void TestQuery()
@@ -357,6 +428,94 @@
Session.Delete(item);
Session.Delete(folder1);
Session.Delete(folder2);
+
+ Assert.IsFalse(Session.Exists(item));
+ Assert.IsFalse(Session.Exists(folder1));
+ Assert.IsFalse(Session.Exists(folder2));
+ }
+
+ [TestMethod]
+ public void TestCopy()
+ {
+ IFolder rootFolder = Session.GetRootFolder();
+ IFolder folder1 = null;
+ IFolder folder2 = null;
+ IDocument doc1 = null;
+ IDocument doc2 = null;
+
+ string content = "I'm unique!";
+
+ try
+ {
+ folder1 = CreateFolder(rootFolder, "copy1");
+ folder2 = CreateFolder(rootFolder, "copy2");
+ doc1 = CreateTextDocument(folder1, "copydoc.xt", content);
+
+ doc2 = doc1.Copy(folder2);
+
+ Assert.IsNotNull(doc2);
+ Assert.AreEqual(doc1.Name, doc2.Name);
+ Assert.AreEqual(ConvertStreamToString(doc1.GetContentStream().Stream), ConvertStreamToString(doc2.GetContentStream().Stream));
+ Assert.AreEqual(folder2.Id, doc2.Parents[0].Id);
+ }
+ finally
+ {
+ if (folder1 != null)
+ {
+ folder1.DeleteTree(true, UnfileObject.Delete, true);
+ Assert.IsFalse(Session.Exists(folder1));
+ }
+ if (folder2 != null)
+ {
+ folder2.DeleteTree(true, UnfileObject.Delete, true);
+ Assert.IsFalse(Session.Exists(folder2));
+ }
+ }
+ }
+
+
+
+ [TestMethod]
+ public void TestAcl()
+ {
+ IDocument doc = null;
+
+ try
+ {
+ doc = CreateTextDocument(Session.GetRootFolder(), "acl.txt", "Hello Joe!");
+
+ Ace joeAce = new Ace()
+ {
+ Principal = new Principal() { Id = "joe" },
+ Permissions = new List<string> { "cmis:write" }
+ };
+
+ // apply ACL and test result
+ IAcl newAcl = doc.ApplyAcl(new List<IAce> { joeAce }, null, AclPropagation.RepositoryDetermined);
+ Assert.IsNotNull(newAcl);
+ Assert.IsNotNull(newAcl.Aces);
+ Assert.IsTrue(newAcl.Aces.Count > 0);
+
+ // retrieve ACL and test
+ IAcl acl2 = Session.GetAcl(doc, true);
+ Assert.IsNotNull(acl2);
+ Assert.IsNotNull(acl2.Aces);
+ Assert.IsTrue(acl2.Aces.Count > 0);
+
+ // fetch document and test
+ IDocument doc2 = (IDocument)Session.GetObject(doc, OperationContextUtils.CreateMaximumOperationContext());
+ Assert.IsNotNull(doc2.Acl);
+ Assert.IsNotNull(doc2.Acl.Aces);
+ Assert.IsTrue(doc2.Acl.Aces.Count > 0);
+ }
+ finally
+ {
+ if (doc != null)
+ {
+ doc.Delete();
+ Assert.IsFalse(Session.Exists(doc));
+ }
+ }
}
}
}