PortCMIS: ported a few features from OpenCMIS
git-svn-id: https://svn.apache.org/repos/asf/chemistry/portcmis/trunk@1789499 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/PortCMIS/binding/atompub/AtomPubBinding.cs b/PortCMIS/binding/atompub/AtomPubBinding.cs
index c812773..41f6de8 100644
--- a/PortCMIS/binding/atompub/AtomPubBinding.cs
+++ b/PortCMIS/binding/atompub/AtomPubBinding.cs
@@ -3129,6 +3129,30 @@
{
ReturnVersion returnVersion = (major == true ? ReturnVersion.LatestMajor : ReturnVersion.Latest);
+ // workaround for SharePoint - use the version series ID instead of the object ID
+ if (Session.GetValue(SessionParameter.LatestVersionWithVersionSeriesId, false))
+ {
+ if (versionSeriesId != null)
+ {
+ objectId = versionSeriesId;
+ }
+ else
+ {
+ IObjectData obj = GetObjectInternal(repositoryId, IdentifierType.ID, objectId, null,
+ PropertyIds.ObjectId + "," + PropertyIds.VersionSeriesId, false,
+ IncludeRelationships.None, "cmis:none", false, false, extension);
+
+ if (obj.Properties != null)
+ {
+ IPropertyData versionSeriesProp = obj.Properties[PropertyIds.VersionSeriesId];
+ if (versionSeriesProp != null && versionSeriesProp.FirstValue is string)
+ {
+ objectId = (string)versionSeriesProp.FirstValue;
+ }
+ }
+ }
+ }
+
return GetObjectInternal(repositoryId, IdentifierType.ID, objectId, returnVersion, filter,
includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension);
}
diff --git a/PortCMIS/client/ClientIntf.cs b/PortCMIS/client/ClientIntf.cs
index 8fea575..4ab089a 100644
--- a/PortCMIS/client/ClientIntf.cs
+++ b/PortCMIS/client/ClientIntf.cs
@@ -1661,11 +1661,18 @@
void RemovePolicy(params IObjectId[] policyId);
/// <summary>
- /// Gets a list of policies applied to this object.
+ /// Returns the applied policies if they have been fetched for this object.
+ /// This method fetches the policy objects from the repository when this method is called for the first time. Policy objects that don't exist are ignored.
/// </summary>
IList<IPolicy> Policies { get; }
/// <summary>
+ /// Returns the applied policy IDs if they have been fetched for this object.
+ /// All applied policy IDs are returned, even IDs of policies that don't exist.
+ /// </summary>
+ IList<string> PolicyIds { get; }
+
+ /// <summary>
/// Adds and removes ACEs to this object.
/// </summary>
/// <returns>the new ACL of this object</returns>
@@ -1773,6 +1780,11 @@
bool? IsLatestMajorVersion { get; }
/// <value>
+ /// Gets if this CMIS object is the PWC (CMIS property <c>cmis:isPrivateWorkingCopy</c>).
+ /// </value>
+ bool? IsPrivateWorkingCopy { get; }
+
+ /// <value>
/// Gets the version label (CMIS property <c>cmis:versionLabel</c>).
/// </value>
string VersionLabel { get; }
@@ -1826,6 +1838,11 @@
/// Gets the content stream hashes or <c>null</c> if the document has no content or the repository hasn't provided content hashes (CMIS property <c>cmis:contentStreamHash</c>).
/// </value>
IList<IContentStreamHash> ContentStreamHashes { get; }
+
+ /// <value>
+ /// Gets the latest accessible state ID (CMIS property <c>cmis:latestAccessibleStateId</c>).
+ /// </value>
+ string LatestAccessibleStateId { get; }
}
/// <summary>
@@ -1834,6 +1851,22 @@
public interface IDocument : IFileableCmisObject, IDocumentProperties
{
/// <summary>
+ /// Returns the object type as a document type.
+ /// </summary>
+ IDocumentType DocumentType { get; }
+
+ /// <summary>
+ /// Returns whether the document is versionable or not.
+ /// </summary>
+ bool IsVersionable { get; }
+
+ /// <summary>
+ /// Determines whether this document is the PWC in the version series or not.
+ /// </summary>
+ /// <returns> <c>true</c> if it is the PWC, <c>false</c> if it is not the PWC, or <c>null</c> if it can't be determined</returns>
+ bool? IsVersionSeriesPrivateWorkingCopy { get; }
+
+ /// <summary>
/// Deletes all versions of this document.
/// </summary>
void DeleteAllVersions();
@@ -2006,6 +2039,11 @@
public interface IFolder : IFileableCmisObject, IFolderProperties
{
/// <summary>
+ /// Returns the object type as a folder type.
+ /// </summary>
+ IFolderType FolderType { get; }
+
+ /// <summary>
/// Creates a new document in this folder.
/// </summary>
/// <returns>the new document object</returns>
@@ -2184,6 +2222,10 @@
/// </summary>
public interface IPolicy : IFileableCmisObject, IPolicyProperties
{
+ /// <summary>
+ /// Returns the object type as a policy type.
+ /// </summary>
+ IPolicyType PolicyType { get; }
}
/// <summary>
@@ -2208,6 +2250,11 @@
public interface IRelationship : ICmisObject, IRelationshipProperties
{
/// <summary>
+ /// Returns the object type as a relationship type.
+ /// </summary>
+ IRelationshipType RelationshipType { get; }
+
+ /// <summary>
/// Gets the relationship source object.
/// </summary>
/// <remarks>
@@ -2252,6 +2299,10 @@
/// </summary>
public interface IItem : IFileableCmisObject, ItemProperties
{
+ /// <summary>
+ /// Returns the object type as an item type.
+ /// </summary>
+ IItemType ItemType { get; }
}
/// <summary>
diff --git a/PortCMIS/client/ClientObjects.cs b/PortCMIS/client/ClientObjects.cs
index 7c42c53..cc5ba4c 100644
--- a/PortCMIS/client/ClientObjects.cs
+++ b/PortCMIS/client/ClientObjects.cs
@@ -101,6 +101,7 @@
private IAllowableActions allowableActions;
private IList<IRendition> renditions;
private IAcl acl;
+ private IList<string> policyIds;
private IList<IPolicy> policies;
private IList<IRelationship> relationships;
private IDictionary<ExtensionLevel, IList<ICmisExtensionElement>> extensions;
@@ -231,22 +232,22 @@
}
// handle policies
+ policies = null;
if (objectData.PolicyIds != null && objectData.PolicyIds.PolicyIds != null)
{
- policies = new List<IPolicy>();
- foreach (string pid in objectData.PolicyIds.PolicyIds)
+ if (objectData.PolicyIds.PolicyIds.Count == 0)
{
- IPolicy policy = Session.GetObject(Session.CreateObjectId(pid)) as IPolicy;
- if (policy != null)
- {
- policies.Add(policy);
- }
+ policyIds = null;
+ }
+ else
+ {
+ policyIds = objectData.PolicyIds.PolicyIds;
}
extensions[ExtensionLevel.Policies] = objectData.PolicyIds.Extensions;
}
else
{
- policies = null;
+ policyIds = null;
}
// handle relationships
@@ -644,11 +645,47 @@
{
lock (objectLock)
{
+ if (policies != null || policyIds == null)
+ {
+ return policies;
+ }
+
+ policies = new List<IPolicy>();
+ foreach (string pid in policyIds)
+ {
+ try
+ {
+ ICmisObject policy = Session.GetObject(pid);
+
+ if (policy is IPolicy)
+ {
+ policies.Add((IPolicy)policy);
+ }
+ }
+ catch (CmisObjectNotFoundException)
+ {
+ // ignore
+ }
+ }
+
return policies;
}
}
}
+ /// <inheritdoc/>
+ public virtual IList<string> PolicyIds
+ {
+ get
+ {
+ lock (objectLock)
+ {
+ return policyIds;
+ }
+ }
+ }
+
+
// --- relationships ---
/// <inheritdoc/>
@@ -886,6 +923,64 @@
Initialize(session, objectType, objectData, context);
}
+ /// <inheritdoc/>
+ public virtual IDocumentType DocumentType
+ {
+ get
+ {
+ if (ObjectType is IDocumentType)
+ {
+ return (IDocumentType)ObjectType;
+ }
+ else
+ {
+ throw new InvalidCastException("Object type is not a document type.");
+ }
+ }
+ }
+
+ /// <inheritdoc/>
+ public virtual bool IsVersionable
+ {
+ get
+ {
+ return DocumentType.IsVersionable == true;
+ }
+ }
+
+ /// <inheritdoc/>
+ public virtual bool? IsVersionSeriesPrivateWorkingCopy
+ {
+ get
+ {
+ if (DocumentType.IsVersionable == false)
+ {
+ return false;
+ }
+
+ if (IsVersionSeriesCheckedOut == false)
+ {
+ return false;
+ }
+
+ bool? isPWC = IsPrivateWorkingCopy;
+ if (isPWC != null)
+ {
+ return isPWC;
+ }
+
+ string vsCoId = VersionSeriesCheckedOutId;
+ if (vsCoId == null)
+ {
+ // we don't know ...
+ return null;
+ }
+
+ return vsCoId == Id;
+ }
+ }
+
+
// properties
/// <inheritdoc/>
@@ -901,6 +996,9 @@
public virtual bool? IsLatestMajorVersion { get { return GetPropertyAsBoolValue(PropertyIds.IsLatestMajorVersion); } }
/// <inheritdoc/>
+ public virtual bool? IsPrivateWorkingCopy { get { return GetPropertyAsBoolValue(PropertyIds.IsPrivateWorkingCopy); } }
+
+ /// <inheritdoc/>
public virtual string VersionLabel { get { return GetPropertyAsStringValue(PropertyIds.VersionLabel); } }
/// <inheritdoc/>
@@ -931,6 +1029,9 @@
public virtual string ContentStreamId { get { return GetPropertyAsStringValue(PropertyIds.ContentStreamId); } }
/// <inheritdoc/>
+ public virtual string LatestAccessibleStateId { get { return GetPropertyAsStringValue(PropertyIds.LatestAccessibleStateId); } }
+
+ /// <inheritdoc/>
public virtual IList<IContentStreamHash> ContentStreamHashes
{
get
@@ -1364,6 +1465,22 @@
}
/// <inheritdoc/>
+ public virtual IFolderType FolderType
+ {
+ get
+ {
+ if (ObjectType is IFolderType)
+ {
+ return (IFolderType)ObjectType;
+ }
+ else
+ {
+ throw new InvalidCastException("Object type is not a folder type.");
+ }
+ }
+ }
+
+ /// <inheritdoc/>
public virtual IDocument CreateDocument(IDictionary<string, object> properties, IContentStream contentStream, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context)
{
@@ -1518,7 +1635,7 @@
IObjectFactory of = Session.ObjectFactory;
IOperationContext ctxt = new OperationContext(context);
- PageFetcher<IDocument>.FetchPage fetchPageDelegate = delegate(BigInteger maxNumItems, BigInteger skipCount)
+ PageFetcher<IDocument>.FetchPage fetchPageDelegate = delegate (BigInteger maxNumItems, BigInteger skipCount)
{
// get checked out documents for this folder
IObjectList checkedOutDocs = service.GetCheckedOutDocs(RepositoryId, objectId, ctxt.FilterString, ctxt.OrderBy, ctxt.IncludeAllowableActions,
@@ -1561,7 +1678,7 @@
IObjectFactory of = Session.ObjectFactory;
IOperationContext ctxt = new OperationContext(context);
- PageFetcher<ICmisObject>.FetchPage fetchPageDelegate = delegate(BigInteger maxNumItems, BigInteger skipCount)
+ PageFetcher<ICmisObject>.FetchPage fetchPageDelegate = delegate (BigInteger maxNumItems, BigInteger skipCount)
{
// get the children
IObjectInFolderList children = service.GetChildren(RepositoryId, objectId, ctxt.FilterString, ctxt.OrderBy, ctxt.IncludeAllowableActions,
@@ -1780,6 +1897,22 @@
}
/// <inheritdoc/>
+ public virtual IPolicyType PolicyType
+ {
+ get
+ {
+ if (ObjectType is IPolicyType)
+ {
+ return (IPolicyType)ObjectType;
+ }
+ else
+ {
+ throw new InvalidCastException("Object type is not a policy type.");
+ }
+ }
+ }
+
+ /// <inheritdoc/>
public virtual string PolicyText { get { return GetPropertyAsStringValue(PropertyIds.PolicyText); } }
}
@@ -1801,6 +1934,22 @@
}
/// <inheritdoc/>
+ public virtual IRelationshipType RelationshipType
+ {
+ get
+ {
+ if (ObjectType is IRelationshipType)
+ {
+ return (IRelationshipType)ObjectType;
+ }
+ else
+ {
+ throw new InvalidCastException("Object type is not a relationship type.");
+ }
+ }
+ }
+
+ /// <inheritdoc/>
public virtual ICmisObject GetSource()
{
return GetSource(Session.DefaultContext);
@@ -1889,6 +2038,22 @@
{
Initialize(session, objectType, objectData, context);
}
+
+ /// <inheritdoc/>
+ public virtual IItemType ItemType
+ {
+ get
+ {
+ if (ObjectType is IItemType)
+ {
+ return (IItemType)ObjectType;
+ }
+ else
+ {
+ throw new InvalidCastException("Object type is not an item type.");
+ }
+ }
+ }
}
/// <summary>
diff --git a/PortCMIS/client/SessionParameter.cs b/PortCMIS/client/SessionParameter.cs
index cc5e303..06fbb52 100644
--- a/PortCMIS/client/SessionParameter.cs
+++ b/PortCMIS/client/SessionParameter.cs
@@ -144,5 +144,9 @@
/// <summary>Defines if the document name should be added to the properties on check in if no properties are updated
/// (Workaround for SharePoint 2010 and SharePoint 2013)</summary>
public const string AddNameOnCheckIn = "org.apache.chemistry.portcmis.workaround.addNameOnCheckIn";
+
+ /// <summary>Defines if getObjectOfLatestVersion should use the version series ID instead of the object ID
+ /// (Workaround for SharePoint 2010 and SharePoint 2013)</summary>
+ public const string LatestVersionWithVersionSeriesId = "org.apache.chemistry.portcmis.workaround.getLatestVersionWithVersionSeriesId";
}
}
\ No newline at end of file
diff --git a/PortCMISTests/SimpleCmisTest.cs b/PortCMISTests/SimpleCmisTest.cs
index a631f43..fa43b59 100644
--- a/PortCMISTests/SimpleCmisTest.cs
+++ b/PortCMISTests/SimpleCmisTest.cs
@@ -332,6 +332,7 @@
IObjectId pwcId = doc.CheckOut();
IDocument pwc = (IDocument)Session.GetObject(pwcId, noCacheOC);
+ Assert.AreEqual(true, pwc.IsPrivateWorkingCopy);
pwc.Rename(name2);