PortCMIS: more documentation and other stuff
git-svn-id: https://svn.apache.org/repos/asf/chemistry/portcmis/trunk@1743509 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/PortCMIS/PortCMIS.csproj b/PortCMIS/PortCMIS.csproj
index 3969e35..d6c55dd 100644
--- a/PortCMIS/PortCMIS.csproj
+++ b/PortCMIS/PortCMIS.csproj
@@ -58,6 +58,7 @@
<Compile Include="binding\browser\BrowserConverter.cs" />
<Compile Include="binding\browser\BrowserUtils.cs" />
<Compile Include="binding\browser\json\Json.cs" />
+ <Compile Include="const\ClientVersion.cs" />
<Compile Include="binding\DateTimeHelper.cs" />
<Compile Include="binding\HttpPortable.cs" />
<Compile Include="binding\Http.cs" />
diff --git a/PortCMIS/PortCMIS.shfbproj b/PortCMIS/PortCMIS.shfbproj
index 3aea2d3..d8fbde6 100644
--- a/PortCMIS/PortCMIS.shfbproj
+++ b/PortCMIS/PortCMIS.shfbproj
@@ -95,9 +95,14 @@
<ApiFilter>
<Filter entryType="Namespace" fullName="PortCMIS.Binding" isExposed="False" xmlns="">
<Filter entryType="Class" fullName="PortCMIS.Binding.AbstractAuthenticationProvider" filterName="AbstractAuthenticationProvider" isExposed="True" />
+ <Filter entryType="Interface" fullName="PortCMIS.Binding.IPortableAuthenticationProvider" filterName="IPortableAuthenticationProvider" isExposed="True" />
<Filter entryType="Interface" fullName="PortCMIS.Binding.IAuthenticationProvider" filterName="IAuthenticationProvider" isExposed="True" />
<Filter entryType="Class" fullName="PortCMIS.Binding.StandardAuthenticationProvider" filterName="StandardAuthenticationProvider" isExposed="True" />
- </Filter>
+ <Filter entryType="Interface" fullName="PortCMIS.Binding.IBindingSession" filterName="IBindingSession" isExposed="True" />
+ <Filter entryType="Interface" fullName="PortCMIS.Binding.ICmisBinding" filterName="ICmisBinding" isExposed="True" />
+ <Filter entryType="Class" fullName="PortCMIS.Binding.UrlBuilder" filterName="UrlBuilder" isExposed="True" />
+ </Filter>
+ <Filter entryType="Namespace" fullName="PortCMIS.Binding.Http" isExposed="True" xmlns="" />
<Filter entryType="Namespace" fullName="PortCMIS.Binding.Browser" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="PortCMIS.Binding.Browser.Json" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="PortCMIS.Binding.Http" isExposed="False" xmlns="" />
diff --git a/PortCMIS/binding/BindingIntf.cs b/PortCMIS/binding/BindingIntf.cs
index a45431e..5e19fec 100644
--- a/PortCMIS/binding/BindingIntf.cs
+++ b/PortCMIS/binding/BindingIntf.cs
@@ -28,7 +28,6 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
-using System.Threading.Tasks;
namespace PortCMIS.Binding
{
@@ -253,7 +252,7 @@
public interface IAuthenticationProvider
{
/// <value>
- /// Gets the binding session instance
+ /// Gets the binding session instance.
/// </value>
IBindingSession Session { get; set; }
}
@@ -283,7 +282,7 @@
}
/// <summary>
- /// Base implementation of an authentication provider.
+ /// Base implementation of a portable authentication provider.
/// </summary>
public abstract class AbstractAuthenticationProvider : IPortableAuthenticationProvider
{
diff --git a/PortCMIS/binding/HttpPortable.cs b/PortCMIS/binding/HttpPortable.cs
index 44d10af..a9a1276 100644
--- a/PortCMIS/binding/HttpPortable.cs
+++ b/PortCMIS/binding/HttpPortable.cs
@@ -135,7 +135,10 @@
HttpRequestMessage request = new HttpRequestMessage(method, url.ToString());
// set additional headers
- request.Headers.UserAgent.Add(new ProductInfoHeaderValue("ApacheChemistryPortCMIS", "0.1"));
+
+ string userAgent = session.GetValue(SessionParameter.UserAgent) as string;
+ request.Headers.UserAgent.Add(ProductInfoHeaderValue.Parse(userAgent ?? ClientVersion.UserAgentName));
+
if (headers != null)
{
foreach (KeyValuePair<string, string> header in headers)
diff --git a/PortCMIS/binding/Services.cs b/PortCMIS/binding/Services.cs
index e96f1f4..63a934b 100644
--- a/PortCMIS/binding/Services.cs
+++ b/PortCMIS/binding/Services.cs
@@ -38,20 +38,42 @@
/// </remarks>
IList<IRepositoryInfo> GetRepositoryInfos(IExtensionsData extension);
+ /// <summary>
+ /// Returns information about the CMIS repository, the optional capabilities it supports and its
+ /// access control information if applicable.
+ /// </summary>
IRepositoryInfo GetRepositoryInfo(string repositoryId, IExtensionsData extension);
+ /// <summary>
+ /// Returns the list of object types defined for the repository that are children of the specified type.
+ /// </summary>
ITypeDefinitionList GetTypeChildren(string repositoryId, string typeId, bool? includePropertyDefinitions,
BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension);
+ /// <summary>
+ /// Returns the set of descendant object type defined for the repository under the specified type.
+ /// </summary>
IList<ITypeDefinitionContainer> GetTypeDescendants(string repositoryId, string typeId, BigInteger? depth,
bool? includePropertyDefinitions, IExtensionsData extension);
+ /// <summary>
+ /// Gets the definition of the specified object type.
+ /// </summary>
ITypeDefinition GetTypeDefinition(string repositoryId, string typeId, IExtensionsData extension);
+ /// <summary>
+ /// Creates a new type.
+ /// </summary>
ITypeDefinition CreateType(string repositoryId, ITypeDefinition type, IExtensionsData extension);
-
+
+ /// <summary>
+ /// Updates a type.
+ /// </summary>
ITypeDefinition UpdateType(string repositoryId, ITypeDefinition type, IExtensionsData extension);
+ /// <summary>
+ /// Deletes a type.
+ /// </summary>
void DeleteType(string repositoryId, string typeId, IExtensionsData extension);
}
@@ -60,24 +82,42 @@
/// </summary>
public interface INavigationService
{
+ /// <summary>
+ /// Gets the list of child objects contained in the specified folder.
+ /// </summary>
IObjectInFolderList GetChildren(string repositoryId, string folderId, string filter, string orderBy,
bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
bool? includePathSegment, BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension);
+ /// <summary>
+ /// Gets the set of descendant objects contained in the specified folder or any of its child folders.
+ /// </summary>
IList<IObjectInFolderContainer> GetDescendants(string repositoryId, string folderId, BigInteger? depth, string filter,
bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
bool? includePathSegment, IExtensionsData extension);
+ /// <summary>
+ /// Gets the set of descendant folder objects contained in the specified folder.
+ /// </summary>
IList<IObjectInFolderContainer> GetFolderTree(string repositoryId, string folderId, BigInteger? depth, string filter,
bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
bool? includePathSegment, IExtensionsData extension);
+ /// <summary>
+ /// Gets the parent folder(s) for the specified non-folder, fileable object.
+ /// </summary>
IList<IObjectParentData> GetObjectParents(string repositoryId, string objectId, string filter,
bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
bool? includeRelativePathSegment, IExtensionsData extension);
- IObjectData GetFolderParent(string repositoryId, string folderId, string filter, ExtensionsData extension);
+ /// <summary>
+ /// Gets the parent folder object for the specified folder object.
+ /// </summary>
+ IObjectData GetFolderParent(string repositoryId, string folderId, string filter, IExtensionsData extension);
+ /// <summary>
+ /// Gets the list of documents that are checked out that the user has access to.
+ /// </summary>
IObjectList GetCheckedOutDocs(string repositoryId, string folderId, string filter, string orderBy,
bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension);
@@ -88,62 +128,126 @@
/// </summary>
public interface IObjectService
{
+ /// <summary>
+ /// Creates a document object of the specified type (given by the cmis:objectTypeId property) in the (optionally) specified location.
+ /// </summary>
string CreateDocument(string repositoryId, IProperties properties, string folderId, IContentStream contentStream,
VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension);
+ /// <summary>
+ /// Creates a document object as a copy of the given source document in the (optionally) specified location.
+ /// </summary>
string CreateDocumentFromSource(string repositoryId, string sourceId, IProperties properties, string folderId,
VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension);
+ /// <summary>
+ /// Creates a folder object of the specified type (given by the cmis:objectTypeId property) in the specified location.
+ /// </summary>
string CreateFolder(string repositoryId, IProperties properties, string folderId, IList<string> policies,
IAcl addAces, IAcl removeAces, IExtensionsData extension);
+ /// <summary>
+ /// Creates a relationship object of the specified type (given by the cmis:objectTypeId property).
+ /// </summary>
string CreateRelationship(string repositoryId, IProperties properties, IList<string> policies, IAcl addAces,
IAcl removeAces, IExtensionsData extension);
+ /// <summary>
+ /// Creates a policy object of the specified type (given by the cmis:objectTypeId property).
+ /// </summary>
string CreatePolicy(string repositoryId, IProperties properties, string folderId, IList<string> policies,
IAcl addAces, IAcl removeAces, IExtensionsData extension);
+ /// <summary>
+ /// Creates an item object of the specified type (given by the cmis:objectTypeId property).
+ /// </summary>
string CreateItem(string repositoryId, IProperties properties, string folderId, IList<string> policies,
IAcl addAces, IAcl removeAces, IExtensionsData extension);
+ /// <summary>
+ /// Gets the list of allowable actions for an object.
+ /// </summary>
IAllowableActions GetAllowableActions(string repositoryId, string objectId, IExtensionsData extension);
+ /// <summary>
+ /// Gets the list of properties for an object.
+ /// </summary>
IProperties GetProperties(string repositoryId, string objectId, string filter, IExtensionsData extension);
+ /// <summary>
+ /// Gets the list of associated renditions for the specified object.
+ /// </summary>
+ /// <remarks>
+ /// Only rendition attributes are returned, not rendition stream.
+ /// </remarks>
IList<IRenditionData> GetRenditions(string repositoryId, string objectId, string renditionFilter,
BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension);
+ /// <summary>
+ /// Gets the specified information for the object specified by ID.
+ /// </summary>
IObjectData GetObject(string repositoryId, string objectId, string filter, bool? includeAllowableActions,
IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds,
bool? includeAcl, IExtensionsData extension);
+ /// <summary>
+ /// Gets the specified information for the object specified by path.
+ /// </summary>
IObjectData GetObjectByPath(string repositoryId, string path, string filter, bool? includeAllowableActions,
IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds, bool? includeAcl,
IExtensionsData extension);
+ /// <summary>
+ /// Gets the content stream for the specified document object, or gets a rendition stream
+ /// for a specified rendition of a document or folder object.
+ /// </summary>
IContentStream GetContentStream(string repositoryId, string objectId, string streamId, BigInteger? offset, BigInteger? length,
IExtensionsData extension);
+ /// <summary>
+ /// Updates properties of the specified object.
+ /// </summary>
void UpdateProperties(string repositoryId, ref string objectId, ref string changeToken, IProperties properties,
IExtensionsData extension);
+ /// <summary>
+ /// Updates properties and secondary types of one or more objects.
+ /// </summary>
IList<IBulkUpdateObjectIdAndChangeToken> BulkUpdateProperties(string repositoryId,
IList<IBulkUpdateObjectIdAndChangeToken> objectIdAndChangeToken, IProperties properties,
IList<string> addSecondaryTypeIds, IList<string> removeSecondaryTypeIds, IExtensionsData extension);
+ /// <summary>
+ /// Moves the specified file-able object from one folder to another.
+ /// </summary>
void MoveObject(string repositoryId, ref string objectId, string targetFolderId, string sourceFolderId,
IExtensionsData extension);
+ /// <summary>
+ /// Deletes the specified object.
+ /// </summary>
void DeleteObject(string repositoryId, string objectId, bool? allVersions, IExtensionsData extension);
+ /// <summary>
+ /// Deletes the specified folder object and all of its child- and descendant-objects.
+ /// </summary>
IFailedToDeleteData DeleteTree(string repositoryId, string folderId, bool? allVersions, UnfileObject? unfileObjects,
- bool? continueOnFailure, ExtensionsData extension);
+ bool? continueOnFailure, IExtensionsData extension);
+ /// <summary>
+ /// Sets the content stream for the specified document object.
+ /// </summary>
void SetContentStream(string repositoryId, ref string objectId, bool? overwriteFlag, ref string changeToken,
IContentStream contentStream, IExtensionsData extension);
+ /// <summary>
+ /// Deletes the content stream for the specified document object.
+ /// </summary>
void DeleteContentStream(string repositoryId, ref string objectId, ref string changeToken, IExtensionsData extension);
+ /// <summary>
+ /// Appends the content stream to the content of the document.
+ /// </summary>
void AppendContentStream(string repositoryId, ref string objectId, bool? isLastChunk, ref string changeToken,
IContentStream contentStream, IExtensionsData extension);
}
@@ -153,21 +257,39 @@
/// </summary>
public interface IVersioningService
{
+ /// <summary>
+ /// Create a private working copy of the document.
+ /// </summary>
void CheckOut(string repositoryId, ref string objectId, IExtensionsData extension, out bool? contentCopied);
+ /// <summary>
+ /// Reverses the effect of a check-out.
+ /// </summary>
void CancelCheckOut(string repositoryId, string objectId, IExtensionsData extension);
+ /// <summary>
+ /// Checks-in the private working copy (PWC) document.
+ /// </summary>
void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties,
IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces,
IExtensionsData extension);
+ /// <summary>
+ /// Get the latest document object in the version series.
+ /// </summary>
IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
string filter, bool? includeAllowableActions, IncludeRelationships? includeRelationships,
string renditionFilter, bool? includePolicyIds, bool? includeAcl, IExtensionsData extension);
+ /// <summary>
+ /// Get a subset of the properties for the latest document object in the version series.
+ /// </summary>
IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
string filter, IExtensionsData extension);
+ /// <summary>
+ /// Returns the list of all document objects in the specified version series, sorted by the property "cmis:creationDate" descending.
+ /// </summary>
IList<IObjectData> GetAllVersions(string repositoryId, string objectId, string versionSeriesId, string filter,
bool? includeAllowableActions, IExtensionsData extension);
}
@@ -177,6 +299,9 @@
/// </summary>
public interface IRelationshipService
{
+ /// <summary>
+ /// Gets all or a subset of relationships associated with an independent object.
+ /// </summary>
IObjectList GetObjectRelationships(string repositoryId, string objectId, bool? includeSubRelationshipTypes,
RelationshipDirection? relationshipDirection, string typeId, string filter, bool? includeAllowableActions,
BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension);
@@ -187,10 +312,16 @@
/// </summary>
public interface IDiscoveryService
{
+ /// <summary>
+ /// Executes a CMIS query statement against the contents of the repository.
+ /// </summary>
IObjectList Query(string repositoryId, string statement, bool? searchAllVersions,
bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension);
+ /// <summary>
+ /// Gets a list of content changes.
+ /// </summary>
IObjectList GetContentChanges(string repositoryId, ref string changeLogToken, bool? includeProperties,
string filter, bool? includePolicyIds, bool? includeAcl, BigInteger? maxItems, IExtensionsData extension);
}
@@ -200,8 +331,14 @@
/// </summary>
public interface IMultiFilingService
{
+ /// <summary>
+ /// Adds an existing fileable non-folder object to a folder.
+ /// </summary>
void AddObjectToFolder(string repositoryId, string objectId, string folderId, bool? allVersions, IExtensionsData extension);
+ /// <summary>
+ /// Removes an existing fileable non-folder object from a folder.
+ /// </summary>
void RemoveObjectFromFolder(string repositoryId, string objectId, string folderId, IExtensionsData extension);
}
@@ -210,8 +347,14 @@
/// </summary>
public interface IAclService
{
+ /// <summary>
+ /// Get the ACL currently applied to the specified object.
+ /// </summary>
IAcl GetAcl(string repositoryId, string objectId, bool? onlyBasicPermissions, IExtensionsData extension);
+ /// <summary>
+ /// Adds or removes the given ACEs to or from the ACL of the object.
+ /// </summary>
IAcl ApplyAcl(string repositoryId, string objectId, IAcl addAces, IAcl removeAces, AclPropagation? aclPropagation,
IExtensionsData extension);
}
@@ -221,10 +364,19 @@
/// </summary>
public interface IPolicyService
{
+ /// <summary>
+ /// Applies a specified policy to an object.
+ /// </summary>
void ApplyPolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension);
+ /// <summary>
+ /// Removes a specified policy from an object.
+ /// </summary>
void RemovePolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension);
+ /// <summary>
+ /// Gets the list of policies currently applied to the specified object.
+ /// </summary>
IList<IObjectData> GetAppliedPolicies(string repositoryId, string objectId, string filter, IExtensionsData extension);
}
}
diff --git a/PortCMIS/binding/atompub/AtomPubBinding.cs b/PortCMIS/binding/atompub/AtomPubBinding.cs
index 61a824b..5ccf7e6 100644
--- a/PortCMIS/binding/atompub/AtomPubBinding.cs
+++ b/PortCMIS/binding/atompub/AtomPubBinding.cs
@@ -1909,7 +1909,7 @@
return result;
}
- public IObjectData GetFolderParent(string repositoryId, string folderId, string filter, ExtensionsData extension)
+ public IObjectData GetFolderParent(string repositoryId, string folderId, string filter, IExtensionsData extension)
{
IObjectData result = null;
@@ -2683,7 +2683,7 @@
}
public IFailedToDeleteData DeleteTree(string repositoryId, string folderId, bool? allVersions, UnfileObject? unfileObjects,
- bool? continueOnFailure, ExtensionsData extension)
+ bool? continueOnFailure, IExtensionsData extension)
{
// find the down links
string link = LoadLink(repositoryId, folderId, BindingConstants.RelDown, null);
diff --git a/PortCMIS/binding/browser/BrowserBinding.cs b/PortCMIS/binding/browser/BrowserBinding.cs
index c746b55..a3de610 100644
--- a/PortCMIS/binding/browser/BrowserBinding.cs
+++ b/PortCMIS/binding/browser/BrowserBinding.cs
@@ -1263,7 +1263,7 @@
return JsonConverter.ConvertObjectParents(json, typeCache);
}
- public IObjectData GetFolderParent(string repositoryId, string folderId, string filter, ExtensionsData extension)
+ public IObjectData GetFolderParent(string repositoryId, string folderId, string filter, IExtensionsData extension)
{
// build URL
UrlBuilder url = GetObjectUrl(repositoryId, folderId, BindingConstants.SelectorParent);
@@ -1722,7 +1722,7 @@
}
public IFailedToDeleteData DeleteTree(string repositoryId, string folderId, bool? allVersions, UnfileObject? unfileObjects,
- bool? continueOnFailure, ExtensionsData extension)
+ bool? continueOnFailure, IExtensionsData extension)
{
// build URL
UrlBuilder url = GetObjectUrl(repositoryId, folderId);
diff --git a/PortCMIS/client/ClientImpl.cs b/PortCMIS/client/ClientImpl.cs
index 59d18b7..59abe28 100644
--- a/PortCMIS/client/ClientImpl.cs
+++ b/PortCMIS/client/ClientImpl.cs
@@ -249,6 +249,7 @@
/// </value>
public string RepositoryId { get { return RepositoryInfo.Id; } }
+ /// <inheritdoc/>
public IObjectFactory ObjectFactory { get; protected set; }
/// <summary>
@@ -997,6 +998,7 @@
// create
+ /// <inheritdoc/>
public IObjectId CreateDocument(IDictionary<string, object> properties, IObjectId folderId, IContentStream contentStream,
VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces)
{
diff --git a/PortCMIS/client/ClientIntf.cs b/PortCMIS/client/ClientIntf.cs
index 060a54f..a6c73ff 100644
--- a/PortCMIS/client/ClientIntf.cs
+++ b/PortCMIS/client/ClientIntf.cs
@@ -24,10 +24,7 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Numerics;
-using System.Text;
-using System.Threading.Tasks;
namespace PortCMIS.Client
{
@@ -108,16 +105,27 @@
/// </summary>
/// <remarks>
/// <para>
- /// Not all operations might be supported by the connected repository. Either PortCMIS or the repository will
- /// throw an exception if an unsupported operation is called.
- /// The capabilities of the repository can be discovered by evaluating the repository info
+ /// CMIS itself is stateless. PortCMIS uses the concept of a session to cache
+ /// data across calls and to deal with user authentication. The session object is
+ /// also used as entry point to all CMIS operations and objects. Because a
+ /// session is only a client side concept, the session object needs not to be
+ /// closed or released when it's not needed anymore.
+ /// </para>
+ /// <para>
+ /// Not all operations provided by this API might be supported by the connected
+ /// repository. Either PortCMIS or the repository will throw an exception if an
+ /// unsupported operation is called. The capabilities of the repository can be
+ /// discovered by evaluating the repository info
/// (see <see cref="RepositoryInfo"/>).
/// </para>
/// <para>
- /// Almost all methods might throw exceptions derived from <see cref="PortCMIS.Exceptions.CmisBaseException"/>!
+ /// Almost all methods might throw exceptions derived from <see cref="PortCMIS.Exceptions.CmisBaseException"/>.
+ /// See the CMIS specification for a list of all operations and their exceptions. Note that
+ /// some incompliant repositories might throw other exception than you expect.
/// </para>
/// <para>
- /// (Please refer to the <a href="http://docs.oasis-open.org/cmis/CMIS/v1.0/os/">CMIS specification</a>
+ /// (Please refer to the <a href="http://docs.oasis-open.org/cmis/CMIS/v1.0/os/">CMIS 1.0 specification</a>
+ /// or the <a href="http://docs.oasis-open.org/cmis/CMIS/v1.0/os/">CMIS 1.1 specification</a>
/// for details about the domain model, terms, concepts, base types, properties, IDs and query names,
/// query language, etc.)
/// </para>
@@ -413,6 +421,16 @@
/// <returns>query results</returns>
/// <cmis>1.0</cmis>
IItemEnumerable<IQueryResult> Query(string statement, bool searchAllVersions);
+
+ /// <summary>
+ /// Performs a query that returns objects.
+ /// </summary>
+ /// <param name="typeId">a type ID</param>
+ /// <param name="where">WHERE part of the query, may be <c>null</c></param>
+ /// <param name="searchAllVersions">indicates whether all versions should searched or not</param>
+ /// <param name="context">the operation context</param>
+ /// <returns>query results</returns>
+ /// <cmis>1.0</cmis>
IItemEnumerable<ICmisObject> QueryObjects(string typeId, string where, bool searchAllVersions, IOperationContext context);
/// <summary>
@@ -438,33 +456,127 @@
/// Gets the latest change log token from the repository.
/// </summary>
/// <returns>the latest change log token</returns>
+ /// <cmis>1.0</cmis>
string GetLatestChangeLogToken();
+
+ /// <summary>
+ /// Gets the change log.
+ /// </summary>
+ /// <param name="changeLogToken">the change log token, may be <c>null</c></param>
+ /// <param name="includeProperties">indicates whether properties should be included or</param>
+ /// <param name="maxNumItems">max number of changes</param>
+ /// <returns>the change events</returns>
+ /// <cmis>1.0</cmis>
IChangeEvents GetContentChanges(string changeLogToken, bool includeProperties, long maxNumItems);
+
+ /// <summary>
+ /// Gets the change log.
+ /// </summary>
+ /// <param name="changeLogToken">the change log token, may be <c>null</c></param>
+ /// <param name="includeProperties">indicates whether properties should be included or</param>
+ /// <param name="maxNumItems">max number of changes</param>
+ /// <param name="context">the operation context</param>
+ /// <returns>the change events</returns>
+ /// <cmis>1.0</cmis>
IChangeEvents GetContentChanges(string changeLogToken, bool includeProperties, long maxNumItems, IOperationContext context);
// create
+ /// <summary>
+ /// Creates a new document.
+ /// </summary>
+ /// <returns>the object ID of the new document</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreateDocument(IDictionary<string, object> properties, IObjectId folderId, IContentStream contentStream,
VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces);
+
+ /// <summary>
+ /// Creates a new document.
+ /// </summary>
+ /// <returns>the object ID of the new document</returns>
IObjectId CreateDocument(IDictionary<string, object> properties, IObjectId folderId, IContentStream contentStream,
VersioningState? versioningState);
+
+ /// <summary>
+ /// Creates a new document from a source document.
+ /// </summary>
+ /// <returns>the object ID of the new document</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, IObjectId folderId,
VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces);
+
+ /// <summary>
+ /// Creates a new document from a source document.
+ /// </summary>
+ /// <returns>the object ID of the new document</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, IObjectId folderId,
VersioningState? versioningState);
+
+ /// <summary>
+ /// Creates a new folder.
+ /// </summary>
+ /// <returns>the object ID of the new folder</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreateFolder(IDictionary<string, object> properties, IObjectId folderId, IList<IPolicy> policies, IList<IAce> addAces,
IList<IAce> removeAces);
+
+ /// <summary>
+ /// Creates a new folder.
+ /// </summary>
+ /// <returns>the object ID of the new folder</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreateFolder(IDictionary<string, object> properties, IObjectId folderId);
+
+ /// <summary>
+ /// Creates a new policy.
+ /// </summary>
+ /// <returns>the object ID of the new policy</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreatePolicy(IDictionary<string, object> properties, IObjectId folderId, IList<IPolicy> policies, IList<IAce> addAces,
IList<IAce> removeAces);
+
+ /// <summary>
+ /// Creates a new policy.
+ /// </summary>
+ /// <returns>the object ID of the new policy</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreatePolicy(IDictionary<string, object> properties, IObjectId folderId);
+
+ /// <summary>
+ /// Creates a new relationship.
+ /// </summary>
+ /// <returns>the object ID of the new relationship</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreateRelationship(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces,
IList<IAce> removeAces);
+
+ /// <summary>
+ /// Creates a new relationship.
+ /// </summary>
+ /// <returns>the object ID of the new relationship</returns>
+ /// <cmis>1.0</cmis>
IObjectId CreateRelationship(IDictionary<string, object> properties);
+
+ /// <summary>
+ /// Creates a new item.
+ /// </summary>
+ /// <returns>the object ID of the new item</returns>
+ /// <cmis>1.1</cmis>
IObjectId CreateItem(IDictionary<string, object> properties, IObjectId folderId, IList<IPolicy> policies, IList<IAce> addAces,
IList<IAce> removeAces);
+
+ /// <summary>
+ /// Creates a new item.
+ /// </summary>
+ /// <returns>the object ID of the new item</returns>
+ /// <cmis>1.1</cmis>
IObjectId CreateItem(IDictionary<string, object> properties, IObjectId folderId);
+ /// <summary>
+ /// Fetches the relationships from or to an object from the repository.
+ /// </summary>
+ /// <cmis>1.0</cmis>
IItemEnumerable<IRelationship> GetRelationships(IObjectId objectId, bool includeSubRelationshipTypes,
RelationshipDirection? relationshipDirection, IObjectType type, IOperationContext context);
@@ -748,6 +860,9 @@
int MaxItemsPerPage { get; set; }
}
+ /// <summary>
+ /// A tree node.
+ /// </summary>
public interface ITree<T>
{
/// <value>
@@ -766,6 +881,7 @@
/// Query Statement.
/// </summary>
/// <example>
+ /// <code>
/// DateTime cal = ...
/// IFolder folder = ...
///
@@ -785,6 +901,7 @@
/// qs.SetString(8, "bob", "tom", "lisa");
///
/// string statement = qs.ToQueryString();
+ /// </code>
/// </example>
public interface IQueryStatement
{
@@ -856,12 +973,13 @@
/// *, ? and - are interpreted as text search operators and are not escaped
/// on first level. If *, ?, - shall be used as literals, they must be passed
/// escaped with \*, \? and \- to this method.
- /// <p>
+ /// <para>
/// For all statements in a CONTAINS() clause it is required to isolate those
/// from a query statement. Therefore a second level escaping is performed.
/// On the second level grammar ", ', - and \ are escaped with a \. See the
/// spec for further details.
- /// <p>
+ /// </para>
+ /// <para>
/// Summary:
/// <table summary="Escaping Summary">
/// <tr>
@@ -887,7 +1005,7 @@
/// <tr>
/// <td>\</td>
/// <td>\\</td>
- /// <td>\\\\<br>
+ /// <td>\\\\<br/>
/// <em>(for any other character following other than///?-)</em></td>
/// </tr>
/// <tr>
@@ -916,6 +1034,7 @@
/// <td>\\\"</td>
/// </tr>
/// </table>
+ /// </para>
/// </remarks>
/// <param name='parameterIndex'>the parameter index (one-based)</param>
/// <param name='str'>the CONTAINS string</param>
@@ -939,21 +1058,21 @@
/// Sets the designated parameter to the given boolean.
/// </summary>
/// <param name='parameterIndex'>the parameter index (one-based)</param>
- /// <param name='bool'>the boolean</param>
+ /// <param name='boolean'>the boolean</param>
void SetBoolean(int parameterIndex, params bool[] boolean);
/// <summary>
/// Sets the designated parameter to the given DateTime value.
/// </summary>
/// <param name='parameterIndex'>the parameter index (one-based)</param>
- /// <param name='cal'>the DateTime value as Calendar object</param>
+ /// <param name='dt'>the DateTime value as Calendar object</param>
void SetDateTime(int parameterIndex, params DateTime[] dt);
/// <summary>
/// Sets the designated parameter to the given DateTime value.
/// </summary>
/// <param name='parameterIndex'>the parameter index (one-based)</param>
- /// <param name='cal'>the DateTime value in milliseconds from midnight, January 1, 1970 UTC.</param>
+ /// <param name='ms'>the DateTime value in milliseconds from midnight, January 1, 1970 UTC.</param>
void SetDateTime(int parameterIndex, params long[] ms);
/// <summary>
@@ -961,7 +1080,7 @@
/// 'TIMESTAMP '.
/// </summary>
/// <param name='parameterIndex'>the parameter index (one-based)</param>
- /// <param name='cal'>the DateTime value as Calendar object
+ /// <param name='dt'>the DateTime value as Calendar object</param>
void SetDateTimeTimestamp(int parameterIndex, params DateTime[] dt);
/// <summary>
@@ -969,7 +1088,7 @@
/// 'TIMESTAMP '.
/// </summary>
/// <param name='parameterIndex'>the parameter index (one-based)</param>
- /// <param name='cal'>the DateTime value in milliseconds from midnight, January 1, 1970 UTC.</param>
+ /// <param name='ms'>the DateTime value in milliseconds from midnight, January 1, 1970 UTC.</param>
void SetDateTimeTimestamp(int parameterIndex, params long[] ms);
/// <summary>
@@ -1092,6 +1211,9 @@
{
}
+ /// <summary>
+ /// Enumerable that allows to skip and page.
+ /// </summary>
public interface IItemEnumerable<T> : IEnumerable<T>
{
/// <summary>
@@ -1750,7 +1872,19 @@
/// <returns>the object ID of the new created document</returns>
IObjectId CheckIn(bool major, IDictionary<string, object> properties, IContentStream contentStream, string checkinComment);
+ /// <summary>
+ /// Fetches the latest major or minor version of this document.
+ /// </summary>
+ /// <param name="major">indicates if the latest major or the very last version should be returned</param>
+ /// <returns>the latest document object</returns>
IDocument GetObjectOfLatestVersion(bool major);
+
+ /// <summary>
+ /// Fetches the latest major or minor version of this document with the given operation context.
+ /// </summary>
+ /// <param name="major">indicates if the latest major or the very last version should be returned</param>
+ /// <param name="context">the operation context</param>
+ /// <returns>the latest document object</returns>
IDocument GetObjectOfLatestVersion(bool major, IOperationContext context);
/// <summary>
@@ -1759,11 +1893,20 @@
IList<IDocument> GetAllVersions();
/// <summary>
- /// Gets a list of all versions in this version series using the given <see cref="PortCMIS.Client.IOperationContext"/>.
+ /// Gets a list of all versions in this version series using the given operation context.
/// </summary>
IList<IDocument> GetAllVersions(IOperationContext context);
+ /// <summary>
+ /// Creates a copy of this document, including content.
+ /// </summary>
+ /// <returns>the new document object</returns>
IDocument Copy(IObjectId targetFolderId);
+
+ /// <summary>
+ /// Creates a copy of this document, including content.
+ /// </summary>
+ /// <returns>the new document object</returns>
IDocument Copy(IObjectId targetFolderId, IDictionary<string, object> properties, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addACEs, IList<IAce> removeACEs, IOperationContext context);
}
@@ -1789,20 +1932,69 @@
/// </summary>
public interface IFolder : IFileableCmisObject, IFolderProperties
{
+ /// <summary>
+ /// Creates a new document in this folder.
+ /// </summary>
+ /// <returns>the new document object</returns>
IDocument CreateDocument(IDictionary<string, object> properties, IContentStream contentStream, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context);
+
+ /// <summary>
+ /// Creates a new document in this folder.
+ /// </summary>
+ /// <returns>the new document object</returns>
IDocument CreateDocument(IDictionary<string, object> properties, IContentStream contentStream, VersioningState? versioningState);
+
+ /// <summary>
+ /// Creates a new document from a source document in this folder.
+ /// </summary>
+ /// <returns>the new document object</returns>
IDocument CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context);
+
+ /// <summary>
+ /// Creates a new document from a source document in this folder.
+ /// </summary>
+ /// <returns>the new document object</returns>
IDocument CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, VersioningState? versioningState);
+
+ /// <summary>
+ /// Creates a new subfolder in this folder.
+ /// </summary>
+ /// <returns>the new folder object</returns>
IFolder CreateFolder(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
IOperationContext context);
+
+ /// <summary>
+ /// Creates a new subfolder in this folder.
+ /// </summary>
+ /// <returns>the new folder object</returns>
IFolder CreateFolder(IDictionary<string, object> properties);
+
+ /// <summary>
+ /// Creates a new policy in this folder.
+ /// </summary>
+ /// <returns>the new policy object</returns>
IPolicy CreatePolicy(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
IOperationContext context);
+
+ /// <summary>
+ /// Creates a new policy in this folder.
+ /// </summary>
+ /// <returns>the new policy object</returns>
IPolicy CreatePolicy(IDictionary<string, object> properties);
+
+ /// <summary>
+ /// Creates a new item in this folder.
+ /// </summary>
+ /// <returns>the new item object</returns>
IItem CreateItem(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
IOperationContext context);
+
+ /// <summary>
+ /// Creates a new item in this folder.
+ /// </summary>
+ /// <returns>the new item object</returns>
IItem CreateItem(IDictionary<string, object> properties);
/// <summary>
@@ -2033,7 +2225,7 @@
/// <remarks>
/// Since repositories are not obligated to add property IDs to their
/// query result properties, this method might not always work as expected with
- /// some repositories. Use <see cref="P:this[string]"/> instead.
+ /// some repositories. Use <see cref="this[string]"/> instead.
/// </remarks>
IPropertyData GetPropertyById(string propertyId);
diff --git a/PortCMIS/client/ClientObjects.cs b/PortCMIS/client/ClientObjects.cs
index 0a2afcf..a1ea256 100644
--- a/PortCMIS/client/ClientObjects.cs
+++ b/PortCMIS/client/ClientObjects.cs
@@ -2060,11 +2060,21 @@
private IDictionary<string, IPropertyData> propertiesById;
private IDictionary<string, IPropertyData> propertiesByQueryName;
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="session">the current session</param>
+ /// <param name="objectData">the query hit</param>
public QueryResult(ISession session, IObjectData objectData)
{
Initialize(session, objectData);
}
+ /// <summary>
+ /// Initializes the query result object.
+ /// </summary>
+ /// <param name="session">the current session</param>
+ /// <param name="objectData">the query hit</param>
protected void Initialize(ISession session, IObjectData objectData)
{
if (objectData != null)
diff --git a/PortCMIS/client/ClientUtils.cs b/PortCMIS/client/ClientUtils.cs
index 03af80d..2070473 100644
--- a/PortCMIS/client/ClientUtils.cs
+++ b/PortCMIS/client/ClientUtils.cs
@@ -26,7 +26,7 @@
using System.Numerics;
using System.Text;
-namespace PortCMIS.Client.Impl
+namespace PortCMIS.Client
{
/// <summary>
/// Operation context implementation.
@@ -70,8 +70,6 @@
orderBy = null;
cacheEnabled = false;
maxItemsPerPage = 100;
-
- GenerateCacheKey();
}
/// <summary>
@@ -89,8 +87,6 @@
orderBy = source.OrderBy;
cacheEnabled = source.CacheEnabled;
maxItemsPerPage = source.MaxItemsPerPage;
-
- GenerateCacheKey();
}
/// <summary>
@@ -110,8 +106,6 @@
this.orderBy = orderBy;
this.cacheEnabled = cacheEnabled;
this.maxItemsPerPage = maxItemsPerPage;
-
- GenerateCacheKey();
}
/// <inheritdoc/>
@@ -328,7 +322,14 @@
/// <inheritdoc/>
public virtual string CacheKey
{
- get { return cacheKey; }
+ get
+ {
+ if (cacheKey == null)
+ {
+ GenerateCacheKey();
+ }
+ return cacheKey;
+ }
}
/// <inheritdoc/>
@@ -576,7 +577,7 @@
/// <summary>
/// Tree implementation.
/// </summary>
- public class Tree<T> : ITree<T>
+ internal class Tree<T> : ITree<T>
{
/// <inheritdoc/>
public T Item { get; set; }
@@ -588,9 +589,13 @@
/// <summary>
/// Base class for IItemEnumerable's.
/// </summary>
- public abstract class AbstractEnumerable<T> : IItemEnumerable<T>
+ internal abstract class AbstractEnumerable<T> : IItemEnumerable<T>
{
private AbstractEnumerator<T> enumerator;
+
+ /// <value>
+ /// Gets the enumerator to creates one if it hasn't been set up, yet.
+ /// </value>
protected AbstractEnumerator<T> Enumerator
{
get
@@ -600,70 +605,106 @@
}
}
+ /// <value>
+ /// Gets the delegate that fetches a page.
+ /// </value>
protected PageFetcher<T> PageFetcher { get; set; }
+
+ /// <value>
+ /// Gets the skip count.
+ /// </value>
protected BigInteger SkipCount { get; private set; }
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="pageFetcher">>the delegate that fetches a page</param>
public AbstractEnumerable(PageFetcher<T> pageFetcher) :
this(0, pageFetcher) { }
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="position">the skip count</param>
+ /// <param name="pageFetcher">>the delegate that fetches a page</param>
protected AbstractEnumerable(BigInteger position, PageFetcher<T> pageFetcher)
{
this.PageFetcher = pageFetcher;
this.SkipCount = position;
}
+ /// <summary>
+ /// Creates an enumerator.
+ /// </summary>
protected abstract AbstractEnumerator<T> CreateEnumerator();
+ /// <inheritdoc/>
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return GetEnumerator();
}
+ /// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
+ /// <inheritdoc/>
public IEnumerator<T> GetEnumerator()
{
return Enumerator;
}
+ /// <inheritdoc/>
public IItemEnumerable<T> SkipTo(BigInteger position)
{
return new CollectionEnumerable<T>(position, PageFetcher);
}
+ /// <inheritdoc/>
public IItemEnumerable<T> GetPage()
{
return new CollectionPageEnumerable<T>(SkipCount, PageFetcher);
}
+ /// <inheritdoc/>
public IItemEnumerable<T> GetPage(int maxNumItems)
{
PageFetcher.MaxNumItems = maxNumItems;
return new CollectionPageEnumerable<T>(SkipCount, PageFetcher);
}
+ /// <inheritdoc/>
public BigInteger PageNumItems { get { return Enumerator.PageNumItems; } }
+ /// <inheritdoc/>
public bool HasMoreItems { get { return Enumerator.HasMoreItems; } }
+ /// <inheritdoc/>
public BigInteger TotalNumItems { get { return Enumerator.TotalNumItems; } }
}
/// <summary>
/// Abstract Enumerator implementation.
/// </summary>
- public abstract class AbstractEnumerator<T> : IEnumerator<T>
+ internal abstract class AbstractEnumerator<T> : IEnumerator<T>
{
private PageFetcher<T> pageFetcher;
private PageFetcher<T>.Page<T> page = null;
private BigInteger? totalNumItems = null;
private bool? hasMoreItems = null;
+ /// <summary>
+ /// The current element.
+ /// </summary>
protected T current;
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="skipCount">the skip count</param>
+ /// <param name="pageFetcher">the delegate that fetches a page</param>
public AbstractEnumerator(BigInteger skipCount, PageFetcher<T> pageFetcher)
{
this.SkipCount = skipCount;
@@ -702,12 +743,24 @@
{
}
+ /// <values>
+ /// Gets the skip count.
+ /// </values>
public BigInteger SkipCount { get; protected set; }
+ /// <values>
+ /// Gets the skip offset.
+ /// </values>
public int SkipOffset { get; protected set; }
+ /// <values>
+ /// Gets the current position.
+ /// </values>
public BigInteger Position { get { return SkipCount + SkipOffset; } }
+ /// <values>
+ /// Gets the number of items of the current page.
+ /// </values>
public BigInteger PageNumItems
{
get
@@ -725,6 +778,9 @@
}
}
+ /// <values>
+ /// Gets the total number of items.
+ /// </values>
public BigInteger TotalNumItems
{
get
@@ -742,6 +798,9 @@
}
}
+ /// <values>
+ /// Gets whether there are more items or not.
+ /// </values>
public bool HasMoreItems
{
get
@@ -762,11 +821,19 @@
}
}
+ /// <summary>
+ /// Increments the skip offset.
+ /// </summary>
+ /// <returns>the new offset</returns>
protected int IncrementSkipOffset()
{
return SkipOffset++;
}
+ /// <summary>
+ /// Returns the current page.
+ /// </summary>
+ /// <returns></returns>
protected PageFetcher<T>.Page<T> GetCurrentPage()
{
if (page == null)
@@ -776,6 +843,10 @@
return page;
}
+ /// <summary>
+ /// Fetches the next page.
+ /// </summary>
+ /// <returns>the next page</returns>
protected PageFetcher<T>.Page<T> IncrementPage()
{
SkipCount += SkipOffset;
@@ -790,27 +861,55 @@
/// <summary>
/// Page fetcher.
/// </summary>
- public class PageFetcher<T>
+ internal class PageFetcher<T>
{
+ /// <summary>
+ /// A delegate that fetches a page.
+ /// </summary>
+ /// <param name="maxNumItems">max number of items</param>
+ /// <param name="skipCount">the skip count</param>
+ /// <returns>a page</returns>
public delegate Page<T> FetchPage(BigInteger maxNumItems, BigInteger skipCount);
private FetchPage fetchPageDelegate;
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="maxNumItems">max number of items</param>
+ /// <param name="fetchPageDelegate">the delegate that fetches a page</param>
public PageFetcher(BigInteger maxNumItems, FetchPage fetchPageDelegate)
{
MaxNumItems = maxNumItems;
this.fetchPageDelegate = fetchPageDelegate;
}
+ /// <value>
+ /// Gets the max number of items.
+ /// </value>
public BigInteger MaxNumItems { get; set; }
+ /// <summary>
+ /// Fetches the next page.
+ /// </summary>
+ /// <param name="skipCount">the skip count</param>
+ /// <returns>the next page</returns>
public Page<T> FetchNextPage(BigInteger skipCount)
{
return fetchPageDelegate(MaxNumItems, skipCount);
}
+ /// <summary>
+ /// A page.
+ /// </summary>
public class Page<P>
{
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="items">list of items</param>
+ /// <param name="totalNumItems">total number of items, if known</param>
+ /// <param name="hasMoreItems">a flag whether there are more items, if known</param>
public Page(IList<P> items, BigInteger? totalNumItems, bool? hasMoreItems)
{
Items = items;
@@ -818,8 +917,19 @@
HasMoreItems = hasMoreItems;
}
+ /// <values>
+ /// Gets the items of the page.
+ /// </values>
public IList<P> Items { get; private set; }
+
+ /// <values>
+ /// Gets the total number of items, if known.
+ /// </values>
public BigInteger? TotalNumItems { get; private set; }
+
+ /// <values>
+ /// Gets whether there are more items or not, if known.
+ /// </values>
public bool? HasMoreItems { get; private set; }
}
}
@@ -827,14 +937,24 @@
/// <summary>
/// CMIS Collection Enumerable.
/// </summary>
- public class CollectionEnumerable<T> : AbstractEnumerable<T>
+ internal class CollectionEnumerable<T> : AbstractEnumerable<T>
{
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="pageFetcher">the delegate that fetches a page</param>
public CollectionEnumerable(PageFetcher<T> pageFetcher) :
this(0, pageFetcher) { }
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="position">the position</param>
+ /// <param name="pageFetcher">the delegate that fetches a page</param>
public CollectionEnumerable(BigInteger position, PageFetcher<T> pageFetcher) :
base(position, pageFetcher) { }
+ /// <inheritdoc/>
protected override AbstractEnumerator<T> CreateEnumerator()
{
return new CollectionEnumerator<T>(SkipCount, PageFetcher);
@@ -844,11 +964,20 @@
/// <summary>
/// Enumerator for iterating over all items in a CMIS Collection.
/// </summary>
- public class CollectionEnumerator<T> : AbstractEnumerator<T>
+ internal class CollectionEnumerator<T> : AbstractEnumerator<T>
{
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="skipCount">the skip count</param>
+ /// <param name="pageFetcher">the delegate that fetches a page</param>
public CollectionEnumerator(BigInteger skipCount, PageFetcher<T> pageFetcher) :
base(skipCount, pageFetcher) { }
+ /// <summary>
+ /// Move to the next items.
+ /// </summary>
+ /// <returns><c>true</c> if there is a next item, <c>false</c> otherwise</returns>
public override bool MoveNext()
{
PageFetcher<T>.Page<T> page = GetCurrentPage();
@@ -888,14 +1017,24 @@
/// <summary>
/// Enumerable for a CMIS Collection Page.
/// </summary>
- public class CollectionPageEnumerable<T> : AbstractEnumerable<T>
+ internal class CollectionPageEnumerable<T> : AbstractEnumerable<T>
{
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="pageFetcher">the delegate that fetches a page</param>
public CollectionPageEnumerable(PageFetcher<T> pageFetcher) :
this(0, pageFetcher) { }
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="position">the position</param>
+ /// <param name="pageFetcher">the delegate that fetches a page</param>
public CollectionPageEnumerable(BigInteger position, PageFetcher<T> pageFetcher) :
base(position, pageFetcher) { }
+ /// <inheritdoc/>
protected override AbstractEnumerator<T> CreateEnumerator()
{
return new CollectionPageEnumerator<T>(SkipCount, PageFetcher);
@@ -905,11 +1044,20 @@
/// <summary>
/// Enumerator for iterating over a page of items in a CMIS Collection.
/// </summary>
- public class CollectionPageEnumerator<T> : AbstractEnumerator<T>
+ internal class CollectionPageEnumerator<T> : AbstractEnumerator<T>
{
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="skipCount">the skip count</param>
+ /// <param name="pageFetcher">the delegate that fetches a page</param>
public CollectionPageEnumerator(BigInteger skipCount, PageFetcher<T> pageFetcher) :
base(skipCount, pageFetcher) { }
+ /// <summary>
+ /// Move to the next items.
+ /// </summary>
+ /// <returns><c>true</c> if there is a next item, <c>false</c> otherwise</returns>
public override bool MoveNext()
{
PageFetcher<T>.Page<T> page = GetCurrentPage();
diff --git a/PortCMIS/client/SessionParameter.cs b/PortCMIS/client/SessionParameter.cs
index fa96d80..2d6080f 100644
--- a/PortCMIS/client/SessionParameter.cs
+++ b/PortCMIS/client/SessionParameter.cs
@@ -87,6 +87,9 @@
/// <summary>CSRF HTTP header</summary>
public const string CsrfHeader = "org.apache.chemistry.portcmis.binding.csrfheader";
+ /// <summary>User agent</summary>
+ public const string UserAgent = "org.apache.chemistry.portcmis.binding.useragent";
+
// ---- binding caches ----
/// <summary>Size of the repositories cache</summary>
diff --git a/PortCMIS/client/SessionParameterDefaults.cs b/PortCMIS/client/SessionParameterDefaults.cs
index e781791..b465754 100644
--- a/PortCMIS/client/SessionParameterDefaults.cs
+++ b/PortCMIS/client/SessionParameterDefaults.cs
@@ -17,12 +17,6 @@
* under the License.
*/
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
namespace PortCMIS.Client
{
/// <summary>
diff --git a/PortCMIS/const/ClientVersion.cs b/PortCMIS/const/ClientVersion.cs
new file mode 100644
index 0000000..699e796
--- /dev/null
+++ b/PortCMIS/const/ClientVersion.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PortCMIS
+{
+ /// <summary>
+ /// PortCMIS client version.
+ /// </summary>
+ public class ClientVersion
+ {
+ /// <summary>PortCMIS user agent name</summary>
+ public const string UserAgentName = "ApacheChemistryPortCMIS";
+
+ /// <summary>PortCMIS version</summary>
+ public const string Version = "0.1";
+
+ /// <summary>PortCMIS user agent name</summary>
+ public const string UserAgent = UserAgentName + "/" + Version;
+ }
+}
\ No newline at end of file
diff --git a/PortCMISTests/ContentStreamTest.cs b/PortCMISTests/ContentStreamTest.cs
index ee1648f..ae60763 100644
--- a/PortCMISTests/ContentStreamTest.cs
+++ b/PortCMISTests/ContentStreamTest.cs
@@ -1,4 +1,22 @@
-using System;
+/*
+* 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.
+*/
+
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PortCMIS.Client.Impl;
diff --git a/PortCMISTests/JsonTest.cs b/PortCMISTests/JsonTest.cs
index b904852..e6b9b53 100644
--- a/PortCMISTests/JsonTest.cs
+++ b/PortCMISTests/JsonTest.cs
@@ -1,7 +1,26 @@
-using System;
+/*
+* 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.
+*/
+
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.IO;
using PortCMIS.Binding.Browser.Json;
+using System;
+using System.IO;
using System.Numerics;
namespace PortCMISTests
diff --git a/PortCMISTests/QueryStatementTest.cs b/PortCMISTests/QueryStatementTest.cs
index e955521..2652b17 100644
--- a/PortCMISTests/QueryStatementTest.cs
+++ b/PortCMISTests/QueryStatementTest.cs
@@ -1,4 +1,23 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+/*
+* 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.
+*/
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using PortCMIS.Binding;
using PortCMIS.Client;
using PortCMIS.Client.Impl;
diff --git a/PortCMISTests/SimpleCmisTest.cs b/PortCMISTests/SimpleCmisTest.cs
index 11568af..d603743 100644
--- a/PortCMISTests/SimpleCmisTest.cs
+++ b/PortCMISTests/SimpleCmisTest.cs
@@ -1,17 +1,34 @@
-using System;
+/*
+* 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.
+*/
+
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using PortCMIS.Client.Impl;
-using System.Collections.Generic;
using PortCMIS;
using PortCMIS.Client;
-using PortCMIS.Exceptions;
+using PortCMIS.Client.Impl;
using PortCMIS.Data;
-using System.IO;
using PortCMIS.Enums;
-using System.Text;
+using PortCMIS.Exceptions;
using PortCMIS.Utils;
using PortCMISTests.Framework;
+using System.Collections.Generic;
using System.Linq;
+using System.Text;
namespace PortCMISTests
{
diff --git a/PortCMISTests/framework/DefaultTestValues.cs b/PortCMISTests/framework/DefaultTestValues.cs
index a6d3f8c..14a3476 100644
--- a/PortCMISTests/framework/DefaultTestValues.cs
+++ b/PortCMISTests/framework/DefaultTestValues.cs
@@ -19,11 +19,7 @@
using PortCMIS;
using PortCMIS.Client;
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace PortCMISTests.Framework
{
diff --git a/PortCMISTests/framework/TestFramework.cs b/PortCMISTests/framework/TestFramework.cs
index 3970878..66e9652 100644
--- a/PortCMISTests/framework/TestFramework.cs
+++ b/PortCMISTests/framework/TestFramework.cs
@@ -23,13 +23,9 @@
using PortCMIS.Client.Impl;
using PortCMIS.Data;
using PortCMIS.Enums;
-using PortCMIS.Exceptions;
-using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Text;
-using System.Threading.Tasks;
namespace PortCMISTests.Framework
{
diff --git a/PortCMISWin/binding/WindowsBindingIntf.cs b/PortCMISWin/binding/WindowsBindingIntf.cs
index b447104..3502510 100644
--- a/PortCMISWin/binding/WindowsBindingIntf.cs
+++ b/PortCMISWin/binding/WindowsBindingIntf.cs
@@ -26,6 +26,9 @@
namespace PortCMIS.Binding
{
+ /// <summary>
+ /// Authentication provider interface for the Windows HTTP client.
+ /// </summary>
public interface IWindowsAuthenticationProvider : IAuthenticationProvider
{
void PrepareHttpClientFilter(HttpBaseProtocolFilter httpClientFilter);
@@ -33,6 +36,9 @@
void HandleResponse(HttpResponseMessage httpResponseMessage);
}
+ /// <summary>
+ /// Base implementation of a Windows authentication provider.
+ /// </summary>
public abstract class AbstractWindowsAuthenticationProvider : IWindowsAuthenticationProvider
{
public IBindingSession Session { get; set; }
@@ -63,6 +69,9 @@
}
}
+ /// <summary>
+ /// Standard Authentication Provider for Windows.
+ /// </summary>
public class StandardWindowsAuthenticationProvider : AbstractWindowsAuthenticationProvider
{
public string BearerToken { get { return Session.GetValue(SessionParameter.OAuthBearerToken) as string; } }
diff --git a/PortCMISWin/binding/WindowsHttp.cs b/PortCMISWin/binding/WindowsHttp.cs
index 3b89030..3bc588c 100644
--- a/PortCMISWin/binding/WindowsHttp.cs
+++ b/PortCMISWin/binding/WindowsHttp.cs
@@ -36,6 +36,9 @@
namespace PortCMIS.Binding.Http
{
+ /// <summary>
+ /// Windows HTTP invoker.
+ /// </summary>
public class WindowsHttpInvoker : IHttpInvoker
{
private const string InvokerHttpClient = "org.apache.chemistry.portcmis.invoker.httpclient";
@@ -122,7 +125,10 @@
HttpRequestMessage request = new HttpRequestMessage(method, new Uri(url.ToString()));
// set additional headers
- request.Headers.UserAgent.Add(new HttpProductInfoHeaderValue("ApacheChemistryPortCMIS", "0.1"));
+
+ string userAgent = session.GetValue(SessionParameter.UserAgent) as string;
+ request.Headers.UserAgent.Add(HttpProductInfoHeaderValue.Parse(userAgent ?? ClientVersion.UserAgentName));
+
if (headers != null)
{
foreach (KeyValuePair<string, string> header in headers)