You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2015/07/20 10:48:59 UTC
svn commit: r1691890 [5/14] - in /chemistry/portcmis: ./ PortCMIS/
PortCMIS/Properties/ PortCMIS/binding/ PortCMIS/binding/atompub/
PortCMIS/binding/browser/ PortCMIS/binding/browser/json/ PortCMIS/client/
PortCMIS/const/ PortCMIS/data/ PortCMIS/enum/ ...
Added: chemistry/portcmis/PortCMIS/binding/browser/BrowserBinding.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/browser/BrowserBinding.cs?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/PortCMIS/binding/browser/BrowserBinding.cs (added)
+++ chemistry/portcmis/PortCMIS/binding/browser/BrowserBinding.cs Mon Jul 20 08:48:57 2015
@@ -0,0 +1,2216 @@
+/*
+* 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 PortCMIS.binding;
+using PortCMIS.Binding.Browser.Json;
+using PortCMIS.Binding.Http;
+using PortCMIS.Binding.Impl;
+using PortCMIS.Binding.Services;
+using PortCMIS.Client;
+using PortCMIS.Data;
+using PortCMIS.Data.Extensions;
+using PortCMIS.Enums;
+using PortCMIS.Exceptions;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PortCMIS.Binding.Browser
+{
+ public class RepositoryInfoBrowserBinding : RepositoryInfo
+ {
+ public string RepositoryUrl { get; set; }
+ public string RootUrl { get; set; }
+ }
+
+ /// <summary>
+ /// Browser binding SPI.
+ /// </summary>
+ internal class CmisBrowserSpi : ICmisSpi
+ {
+ public const string RepositoryUrlCache = "org.apache.chemistry.portcmis.binding.browser.repositoryurls";
+
+ private BindingSession session;
+ private RepositoryService repositoryService;
+ private NavigationService navigationService;
+ private ObjectService objectService;
+ private VersioningService versioningService;
+ private DiscoveryService discoveryService;
+ private MultiFilingService multiFilingService;
+ private RelationshipService relationshipService;
+ private PolicyService policyService;
+ private AclService aclService;
+
+ public void Initialize(IBindingSession session)
+ {
+ this.session = session as BindingSession;
+ if (this.session == null)
+ {
+ throw new ArgumentException("Inavlid binding session!");
+ }
+
+ repositoryService = new RepositoryService(this.session);
+ navigationService = new NavigationService(this.session);
+ objectService = new ObjectService(this.session);
+ versioningService = new VersioningService(this.session);
+ discoveryService = new DiscoveryService(this.session);
+ multiFilingService = new MultiFilingService(this.session);
+ relationshipService = new RelationshipService(this.session);
+ policyService = new PolicyService(this.session);
+ aclService = new AclService(this.session);
+ }
+
+ public IRepositoryService GetRepositoryService()
+ {
+ return repositoryService;
+ }
+
+ public INavigationService GetNavigationService()
+ {
+ return navigationService;
+ }
+
+ public IObjectService GetObjectService()
+ {
+ return objectService;
+ }
+
+ public IVersioningService GetVersioningService()
+ {
+ return versioningService;
+ }
+
+ public IRelationshipService GetRelationshipService()
+ {
+ return relationshipService;
+ }
+
+ public IDiscoveryService GetDiscoveryService()
+ {
+ return discoveryService;
+ }
+
+ public IMultiFilingService GetMultiFilingService()
+ {
+ return multiFilingService;
+ }
+
+ public IAclService GetAclService()
+ {
+ return aclService;
+ }
+
+ public IPolicyService GetPolicyService()
+ {
+ return policyService;
+ }
+
+ public void ClearAllCaches()
+ {
+ session.RemoveValue(RepositoryUrlCache);
+ }
+
+ public void ClearRepositoryCache(string repositoryId)
+ {
+ RepositoryUrlCache repUrlCache = session.GetValue(RepositoryUrlCache) as RepositoryUrlCache;
+ if (repUrlCache != null)
+ {
+ repUrlCache.RemoveRepository(repositoryId);
+ }
+ }
+
+ public void Dispose()
+ {
+ // nothing to do
+ }
+ }
+
+ internal class ClientTypeCache : ITypeCache
+ {
+ private string RepositoryId { get; set; }
+ private AbstractBrowserBindingService Service { get; set; }
+
+ public ClientTypeCache(string repositoryId, AbstractBrowserBindingService service)
+ {
+ this.RepositoryId = repositoryId;
+ this.Service = service;
+ }
+
+ public ITypeDefinition GetTypeDefinition(string typeId)
+ {
+ TypeDefinitionCache cache = Service.Session.GetTypeDefinitionCache();
+
+ ITypeDefinition type = cache.Get(RepositoryId, typeId);
+ if (type == null)
+ {
+ type = Service.GetTypeDefinitionInternal(RepositoryId, typeId);
+ if (type != null)
+ {
+ cache.Put(RepositoryId, type);
+ }
+ }
+
+ return type;
+ }
+
+ public ITypeDefinition ReloadTypeDefinition(string typeId)
+ {
+ TypeDefinitionCache cache = Service.Session.GetTypeDefinitionCache();
+
+ ITypeDefinition type = Service.GetTypeDefinitionInternal(RepositoryId, typeId);
+ if (type != null)
+ {
+ cache.Put(RepositoryId, type);
+ }
+
+ return type;
+ }
+
+ public ITypeDefinition GetTypeDefinitionForObject(string objectId)
+ {
+ return null;
+ }
+
+ public IPropertyDefinition GetPropertyDefinition(string propId)
+ {
+ return null;
+ }
+ }
+
+ internal class FormDataComposer
+ {
+ public string CmisAction { get; private set; }
+
+ public IContentStream Stream { get; set; }
+
+ public IProperties Properties { get; set; }
+ public bool Succinct { get; set; }
+ public DateTimeFormat DateTimeFormat { get; set; }
+
+ public IAcl AddAces { get; set; }
+ public IAcl RemoveAces { get; set; }
+
+ public IList<string> Policies { get; set; }
+ public string PolicyId { get; set; }
+
+ public IList<string> AddSecondaryTypeIds { get; set; }
+ public IList<string> RemoveSecondaryTypeIds { get; set; }
+
+ public IList<IBulkUpdateObjectIdAndChangeToken> ObjectIdsAndChangeTokens { get; set; }
+
+ private IDictionary<string, object> parameters;
+
+ public IDictionary<string, object> Parameters
+ {
+ get
+ {
+ if (parameters == null)
+ {
+ parameters = new Dictionary<string, object>();
+ }
+ return parameters;
+ }
+ set { parameters = value; }
+ }
+
+ public FormDataComposer(string cmisAction)
+ {
+ CmisAction = cmisAction;
+ }
+
+ public HttpContent CreateHttpContent()
+ {
+ if (Stream == null)
+ {
+ return CreateFormUrlEncodedContent();
+ }
+ else
+ {
+ return CreateMultipartFormDataContent();
+ }
+ }
+
+ protected FormUrlEncodedContent CreateFormUrlEncodedContent()
+ {
+ return new FormUrlEncodedContent(CreateContent());
+ }
+
+ protected MultipartFormDataContent CreateMultipartFormDataContent()
+ {
+ MultipartFormDataContent content = new MultipartFormDataContent();
+
+ IList<KeyValuePair<string, string>> parameters = CreateContent();
+ foreach (KeyValuePair<string, string> p in parameters)
+ {
+ content.Add(new StringContent(p.Value, Encoding.UTF8), p.Key);
+ }
+
+ if (Stream.Stream != null)
+ {
+ StreamContent streamContent = new StreamContent(Stream.Stream);
+ streamContent.Headers.ContentType = new MediaTypeHeaderValue(Stream.MimeType ?? "applictaion/octet-stream");
+
+ content.Add(streamContent, "content", Stream.FileName ?? "content");
+ }
+
+ return content;
+ }
+
+ protected IList<KeyValuePair<string, string>> CreateContent()
+ {
+ IList<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>();
+
+ // set cmisaction
+ result.Add(new KeyValuePair<string, string>(BindingConstants.ControlCmisAction, CmisAction));
+
+ // set parameters
+ if (parameters != null)
+ {
+ foreach (KeyValuePair<string, object> p in parameters)
+ {
+ if (p.Value != null)
+ {
+ result.Add(new KeyValuePair<string, string>(p.Key, UrlBuilder.NormalizeParameter(p.Value)));
+ }
+ }
+ }
+
+ // set succinct
+ if (Succinct)
+ {
+ result.Add(new KeyValuePair<string, string>(BindingConstants.ControlSuccinct, "true"));
+ }
+
+ // set properties
+ AddPropertiesParameters(Properties, result);
+
+ // set Aces
+ AddAcesParameters(AddAces, BindingConstants.ControlAddAcePrincipal, BindingConstants.ControlRemoveAcePermission, result);
+ AddAcesParameters(RemoveAces, BindingConstants.ControlRemoveAcePrincipal, BindingConstants.ControlRemoveAcePermission, result);
+
+ // set policies
+ AddPoliciesParameters(Policies, result);
+ AddPolicyIdParameter(PolicyId, result);
+
+ // set secondary type IDs
+ AddSecondaryTypeIdParameters(AddSecondaryTypeIds, BindingConstants.ControlAddSecondaryType, result);
+ AddSecondaryTypeIdParameters(RemoveSecondaryTypeIds, BindingConstants.ControlRemoveSecondaryType, result);
+
+ // set bulk update values
+ AddObjectIdsAndChangeTokens(ObjectIdsAndChangeTokens, result);
+
+ return result;
+ }
+
+ private void AddPropertiesParameters(IProperties properties, IList<KeyValuePair<string, string>> result)
+ {
+ if (properties == null || properties.PropertyList == null)
+ {
+ return;
+ }
+
+ int idx = 0;
+ foreach (PropertyData prop in properties.PropertyList)
+ {
+ if (prop == null)
+ {
+ continue;
+ }
+
+ string idxStr = "[" + idx + "]";
+ result.Add(new KeyValuePair<string, string>(BindingConstants.ControlPropId + idxStr, prop.Id));
+
+ if (prop.Values != null && prop.Values.Count > 0)
+ {
+ if (prop.Values.Count == 1)
+ {
+ result.Add(new KeyValuePair<string, string>(
+ BindingConstants.ControlPropValue + idxStr, ConvertPropertyValue(prop.FirstValue, DateTimeFormat)));
+ }
+ else
+ {
+ int vidx = 0;
+ foreach (object obj in prop.Values)
+ {
+ string vidxStr = "[" + vidx + "]";
+ result.Add(new KeyValuePair<string, string>(
+ BindingConstants.ControlPropValue + idxStr + vidxStr, ConvertPropertyValue(obj, DateTimeFormat)));
+ vidx++;
+ }
+ }
+ }
+ idx++;
+ }
+ }
+
+ private void AddAcesParameters(IAcl acl, string principalControl, string permissionControl, IList<KeyValuePair<string, string>> result)
+ {
+ if (acl == null || acl.Aces == null)
+ {
+ return;
+ }
+
+ int idx = 0;
+ foreach (IAce ace in acl.Aces)
+ {
+ if (ace.PrincipalId != null && ace.Permissions != null && ace.Permissions.Count > 0)
+ {
+ string idxStr = "[" + idx + "]";
+ result.Add(new KeyValuePair<string, string>(principalControl + idxStr, ace.PrincipalId));
+
+ int permIdx = 0;
+ foreach (string perm in ace.Permissions)
+ {
+ if (perm != null)
+ {
+ string permIdxStr = "[" + permIdx + "]";
+ result.Add(new KeyValuePair<string, string>(permissionControl + idxStr + permIdxStr, perm));
+ permIdx++;
+ }
+ }
+ idx++;
+ }
+ }
+ }
+
+ private void AddPoliciesParameters(IList<string> policies, IList<KeyValuePair<string, string>> result)
+ {
+ if (policies == null)
+ {
+ return;
+ }
+
+ int idx = 0;
+ foreach (string policy in policies)
+ {
+ if (policy != null)
+ {
+ string idxStr = "[" + idx + "]";
+ result.Add(new KeyValuePair<string, string>(BindingConstants.ControlPolicy + idxStr, policy));
+ idx++;
+ }
+ }
+ }
+
+ private void AddPolicyIdParameter(string policyId, IList<KeyValuePair<string, string>> result)
+ {
+ if (policyId == null)
+ {
+ return;
+ }
+
+ result.Add(new KeyValuePair<string, string>(BindingConstants.ControlPolicyId, policyId));
+ }
+
+ private void AddSecondaryTypeIdParameters(IList<string> secondaryTypeIds, string secondaryTypeIdControl, IList<KeyValuePair<string, string>> result)
+ {
+ if (secondaryTypeIds == null || secondaryTypeIds.Count == 0)
+ {
+ return;
+ }
+
+ int idx = 0;
+ foreach (string typeId in secondaryTypeIds)
+ {
+ if (typeId == null || typeId.Length == 0)
+ {
+ continue;
+ }
+
+ string idxStr = "[" + idx + "]";
+ result.Add(new KeyValuePair<string, string>(secondaryTypeIdControl + idxStr, typeId));
+
+ idx++;
+ }
+ }
+
+ public void AddObjectIdsAndChangeTokens(IList<IBulkUpdateObjectIdAndChangeToken> objectIdsAndChangeTokens, IList<KeyValuePair<string, string>> result)
+ {
+ if (objectIdsAndChangeTokens == null || objectIdsAndChangeTokens.Count == 0)
+ {
+ return;
+ }
+
+ int idx = 0;
+ foreach (IBulkUpdateObjectIdAndChangeToken oc in objectIdsAndChangeTokens)
+ {
+ if (oc == null || oc.Id == null || oc.Id.Length == 0)
+ {
+ continue;
+ }
+
+ string idxStr = "[" + idx + "]";
+ result.Add(new KeyValuePair<string, string>(BindingConstants.ControlObjectId + idxStr, oc.Id));
+ result.Add(new KeyValuePair<string, string>(BindingConstants.ControlChangeToken + idxStr, oc.ChangeToken ?? ""));
+
+ idx++;
+ }
+ }
+
+ private string ConvertPropertyValue(object value, DateTimeFormat dateTimeFormat)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+ else if (value is DateTime)
+ {
+ if (DateTimeFormat == DateTimeFormat.Extended)
+ {
+ return DateTimeHelper.FormatISO8601((DateTime)value);
+ }
+ else
+ {
+ return DateTimeHelper.ConvertDateTimeToMillis((DateTime)value).ToString();
+ }
+ }
+ else if (value is decimal)
+ {
+ return ((decimal)value).ToString("#", CultureInfo.InvariantCulture);
+ }
+ else if (value is BigInteger)
+ {
+ return ((BigInteger)value).ToString("#", CultureInfo.InvariantCulture);
+ }
+ else
+ {
+ return value.ToString();
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Common service data and operations.
+ /// </summary>
+ internal abstract class AbstractBrowserBindingService
+ {
+ private BindingSession session;
+
+ public BindingSession Session
+ {
+ get
+ {
+ return session;
+ }
+ protected set
+ {
+ session = value;
+
+ Succinct = true;
+ object succintObj = session.GetValue(SessionParameter.BrowserSuccinct);
+ if (succintObj is string)
+ {
+ Succinct = Convert.ToBoolean((string)succintObj);
+ }
+
+ DateTimeFormat = DateTimeFormat.Simple;
+ object dateTimeFormatObj = session.GetValue(SessionParameter.BrowserDateTimeFormat);
+ if (dateTimeFormatObj is string)
+ {
+ DateTimeFormat? dtf = ((string)dateTimeFormatObj).GetCmisEnum<DateTimeFormat>();
+ DateTimeFormat = dtf ?? DateTimeFormat.Simple;
+ }
+ }
+ }
+ protected bool Succinct { get; private set; }
+ protected string SuccinctParameter { get { return Succinct ? "true" : null; } }
+
+ protected DateTimeFormat DateTimeFormat { get; private set; }
+ protected string DateTimeFormatParameter { get { return DateTimeFormat == DateTimeFormat.Simple ? null : DateTimeFormat.GetCmisValue(); } }
+
+ protected string GetServiceUrl()
+ {
+ return Session.GetValue(SessionParameter.BrowserUrl) as string;
+ }
+
+ protected UrlBuilder GetRepositoryUrl(string repositoryId, string selector)
+ {
+ UrlBuilder result = GetRepositoryUrlCache().GetRepositoryUrl(repositoryId, selector);
+
+ if (result == null)
+ {
+ GetRepositoriesInternal(repositoryId);
+ result = GetRepositoryUrlCache().GetRepositoryUrl(repositoryId, selector);
+ }
+
+ if (result == null)
+ {
+ throw new CmisObjectNotFoundException("Unknown repository!");
+ }
+
+ return result;
+ }
+
+ protected UrlBuilder GetRepositoryUrl(string repositoryId)
+ {
+ UrlBuilder result = GetRepositoryUrlCache().GetRepositoryUrl(repositoryId);
+
+ if (result == null)
+ {
+ GetRepositoriesInternal(repositoryId);
+ result = GetRepositoryUrlCache().GetRepositoryUrl(repositoryId);
+ }
+
+ if (result == null)
+ {
+ throw new CmisObjectNotFoundException("Unknown repository!");
+ }
+
+ return result;
+ }
+
+ protected UrlBuilder GetObjectUrl(string repositoryId, string objectId, string selector)
+ {
+ UrlBuilder result = GetRepositoryUrlCache().GetObjectUrl(repositoryId, objectId, selector);
+
+ if (result == null)
+ {
+ GetRepositoriesInternal(repositoryId);
+ result = GetRepositoryUrlCache().GetObjectUrl(repositoryId, objectId, selector);
+ }
+
+ if (result == null)
+ {
+ throw new CmisObjectNotFoundException("Unknown repository!");
+ }
+
+ return result;
+ }
+
+ protected UrlBuilder GetObjectUrl(string repositoryId, string objectId)
+ {
+ UrlBuilder result = GetRepositoryUrlCache().GetObjectUrl(repositoryId, objectId);
+
+ if (result == null)
+ {
+ GetRepositoriesInternal(repositoryId);
+ result = GetRepositoryUrlCache().GetObjectUrl(repositoryId, objectId);
+ }
+
+ if (result == null)
+ {
+ throw new CmisObjectNotFoundException("Unknown repository!");
+ }
+
+ return result;
+ }
+
+ protected UrlBuilder GetPathUrl(string repositoryId, string path, string selector)
+ {
+ UrlBuilder result = GetRepositoryUrlCache().GetPathUrl(repositoryId, path, selector);
+
+ if (result == null)
+ {
+ GetRepositoriesInternal(repositoryId);
+ result = GetRepositoryUrlCache().GetPathUrl(repositoryId, path, selector);
+ }
+
+ if (result == null)
+ {
+ throw new CmisObjectNotFoundException("Unknown repository!");
+ }
+
+ return result;
+ }
+
+
+ protected RepositoryUrlCache GetRepositoryUrlCache()
+ {
+ RepositoryUrlCache repositoryUrlCache = Session.GetValue(CmisBrowserSpi.RepositoryUrlCache) as RepositoryUrlCache;
+ if (repositoryUrlCache == null)
+ {
+ repositoryUrlCache = new RepositoryUrlCache();
+ Session.PutValue(CmisBrowserSpi.RepositoryUrlCache, repositoryUrlCache);
+ }
+
+ return repositoryUrlCache;
+ }
+
+ protected void SetChangeToken(ref string changeToken, IObjectData obj)
+ {
+ if (changeToken == null)
+ {
+ return;
+ }
+
+ changeToken = null;
+
+ if (obj == null || obj.Properties == null)
+ {
+ return;
+ }
+
+ IPropertyData ct = obj.Properties[PropertyIds.ChangeToken];
+ if (ct != null && ct.PropertyType == PropertyType.String)
+ {
+ changeToken = (string)ct.FirstValue;
+ }
+ }
+
+ // ---- exceptions ----
+
+ /// <summary>
+ /// Converts an error message or a HTTP status code into an Exception.
+ /// </summary>
+ protected CmisBaseException ConvertStatusCode(int code, string message, string errorContent, Exception e)
+ {
+ object obj = null;
+ try
+ {
+ if (errorContent != null)
+ {
+ JsonParser parser = new JsonParser();
+ obj = parser.Parse(new StringReader(errorContent));
+ }
+ }
+ catch (JsonParseException)
+ {
+ // error content is not valid JSON -> ignore
+ }
+
+ if (obj is JsonObject)
+ {
+ JsonObject json = (JsonObject)obj;
+ object jsonError = json[BrowserConstants.ErrorException];
+ if (jsonError is string)
+ {
+ object jsonMessage = json[BrowserConstants.ErrorMessage];
+ if (jsonMessage != null)
+ {
+ message = jsonMessage.ToString();
+ }
+
+ if (CmisConstraintException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisConstraintException(message, errorContent, e);
+ }
+ else if (CmisContentAlreadyExistsException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisContentAlreadyExistsException(message, errorContent, e);
+ }
+ else if (CmisFilterNotValidException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisFilterNotValidException(message, errorContent, e);
+ }
+ else if (CmisInvalidArgumentException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisInvalidArgumentException(message, errorContent, e);
+ }
+ else if (CmisNameConstraintViolationException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisNameConstraintViolationException(message, errorContent, e);
+ }
+ else if (CmisNotSupportedException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisNotSupportedException(message, errorContent, e);
+ }
+ else if (CmisObjectNotFoundException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisObjectNotFoundException(message, errorContent, e);
+ }
+ else if (CmisPermissionDeniedException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisPermissionDeniedException(message, errorContent, e);
+ }
+ else if (CmisStorageException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisStorageException(message, errorContent, e);
+ }
+ else if (CmisStreamNotSupportedException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisStreamNotSupportedException(message, errorContent, e);
+ }
+ else if (CmisUpdateConflictException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisUpdateConflictException(message, errorContent, e);
+ }
+ else if (CmisVersioningException.ExceptionName.Equals((string)jsonError, StringComparison.OrdinalIgnoreCase))
+ {
+ return new CmisVersioningException(message, errorContent, e);
+ }
+ else if (code == 503)
+ {
+ return new CmisServiceUnavailableException(message, errorContent, e);
+ }
+ }
+ }
+
+ // fall back to status code
+ switch (code)
+ {
+ case 301:
+ case 302:
+ case 303:
+ case 307:
+ return new CmisConnectionException("Redirects are not supported (HTTP status code " + code + "): " + message, errorContent, e);
+ case 400:
+ return new CmisInvalidArgumentException(message, errorContent, e);
+ case 401:
+ return new CmisUnauthorizedException(message, errorContent, e);
+ case 403:
+ return new CmisPermissionDeniedException(message, errorContent, e);
+ case 404:
+ return new CmisObjectNotFoundException(message, errorContent, e);
+ case 405:
+ return new CmisNotSupportedException(message, errorContent, e);
+ case 407:
+ return new CmisProxyAuthenticationException(message, errorContent, e);
+ case 409:
+ return new CmisConstraintException(message, errorContent, e);
+ case 503:
+ return new CmisServiceUnavailableException(message, errorContent, e);
+ default:
+ return new CmisRuntimeException(message, errorContent, e);
+ }
+ }
+
+
+ // ---- helpers ----
+
+ /// <summary>
+ /// Parses an object from an input stream.
+ /// </summary>
+ protected JsonObject ParseObject(Stream stream, string charset)
+ {
+ object obj = Parse(stream, charset);
+
+ if (obj is JsonObject)
+ {
+ return (JsonObject)obj;
+ }
+
+ throw new CmisConnectionException("Unexpected object!");
+ }
+
+ /// <summary>
+ /// Parses an array from an input stream.
+ /// </summary>
+ protected JsonArray ParseArray(Stream stream, string charset)
+ {
+ object obj = Parse(stream, charset);
+
+ if (obj is JsonArray)
+ {
+ return (JsonArray)obj;
+ }
+
+ throw new CmisConnectionException("Unexpected object!");
+ }
+
+ /// <summary>
+ /// Parses an input stream.
+ /// </summary>
+ protected object Parse(Stream stream, string charset)
+ {
+ Encoding enc;
+ if (charset == null)
+ {
+ enc = Encoding.UTF8;
+ }
+ else
+ {
+ try
+ {
+ enc = Encoding.GetEncoding(charset);
+ }
+ catch (Exception e)
+ {
+ throw new CmisConnectionException("Unsupported charset: " + charset, e);
+ }
+ }
+
+ StreamReader reader = null;
+
+ object obj = null;
+ try
+ {
+ reader = new StreamReader(stream, enc);
+ JsonParser parser = new JsonParser();
+ obj = parser.Parse(reader);
+ }
+ catch (Exception e)
+ {
+ throw new CmisConnectionException("Parsing exception!", e);
+ }
+ finally
+ {
+ IOUtils.ConsumeAndClose(reader);
+ if (reader == null)
+ {
+ stream.Dispose();
+ }
+ }
+
+ return obj;
+ }
+
+ /// <summary>
+ /// Performs a GET on an URL, checks the response code and returns the
+ /// result.
+ /// </summary>
+ protected IResponse Read(UrlBuilder url)
+ {
+ // make the call
+ IResponse resp = Session.GetHttpInvoker().InvokeGET(url, session);
+
+ // check response code
+ if (resp.StatusCode != 200)
+ {
+ throw ConvertStatusCode(resp.StatusCode, resp.Message, resp.ErrorContent, null);
+ }
+
+ return resp;
+ }
+
+
+ /// <summary>
+ /// Performs a POST on an URL, checks the response code and returns the
+ /// result.
+ /// </summary>
+ protected IResponse Post(UrlBuilder url, HttpContent content)
+ {
+ // make the call
+ IResponse resp = Session.GetHttpInvoker().InvokePOST(url, content, session);
+
+ // check response code
+ if (resp.StatusCode != 200 && resp.StatusCode != 201)
+ {
+ throw ConvertStatusCode(resp.StatusCode, resp.Message, resp.ErrorContent, null);
+ }
+
+ return resp;
+ }
+
+ /// <summary>
+ /// Performs a POST on an URL, checks the response code and returns the
+ /// result.
+ /// </summary>
+ protected void PostAndConsume(UrlBuilder url, HttpContent content)
+ {
+ IResponse resp = Post(url, content);
+ IOUtils.ConsumeAndClose(resp.Stream);
+ }
+
+ // -----
+
+ protected IList<IRepositoryInfo> GetRepositoriesInternal(string repositoryId)
+ {
+ UrlBuilder url = null;
+
+ if (repositoryId == null)
+ {
+ // no repository id provided -> get all
+ url = new UrlBuilder(GetServiceUrl());
+ }
+ else
+ {
+ // use URL of the specified repository
+ url = GetRepositoryUrlCache().GetRepositoryUrl(repositoryId, BindingConstants.SelectorRepositoryInfo);
+ if (url == null)
+ {
+ // repository infos haven't been fetched yet -> get them all
+ url = new UrlBuilder(GetServiceUrl());
+ }
+ }
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ IList<IRepositoryInfo> repInfos = new List<IRepositoryInfo>();
+
+ foreach (KeyValuePair<string, object> jri in json)
+ {
+ if (jri.Value is JsonObject)
+ {
+ IRepositoryInfo ri = JsonConverter.ConvertRepositoryInfo((JsonObject)jri.Value);
+ string id = ri.Id;
+
+ if (ri is RepositoryInfoBrowserBinding)
+ {
+ string repositoryUrl = ((RepositoryInfoBrowserBinding)ri).RepositoryUrl;
+ string rootUrl = ((RepositoryInfoBrowserBinding)ri).RootUrl;
+
+ if (id == null || repositoryUrl == null || rootUrl == null)
+ {
+ throw new CmisConnectionException("Found invalid Repository Info! (id: " + id + ")");
+ }
+
+ GetRepositoryUrlCache().AddRepository(id, repositoryUrl, rootUrl);
+ }
+
+ repInfos.Add(ri);
+ }
+ else
+ {
+ throw new CmisConnectionException("Found invalid Repository Info!");
+ }
+ }
+
+ return repInfos;
+ }
+
+ /**
+ * Retrieves a type definition.
+ */
+ public ITypeDefinition GetTypeDefinitionInternal(string repositoryId, string typeId)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId, BindingConstants.SelectorTypeDefinition);
+ url.AddParameter(BindingConstants.ParamTypeId, typeId);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertTypeDefinition(json);
+ }
+ }
+
+ internal class RepositoryService : AbstractBrowserBindingService, IRepositoryService
+ {
+ public RepositoryService(BindingSession session)
+ {
+ Session = session;
+ }
+
+ public IList<IRepositoryInfo> GetRepositoryInfos(IExtensionsData extension)
+ {
+ return GetRepositoriesInternal(null);
+ }
+
+ public IRepositoryInfo GetRepositoryInfo(string repositoryId, IExtensionsData extension)
+ {
+ IList<IRepositoryInfo> repositoryInfos = GetRepositoriesInternal(repositoryId);
+
+ if (repositoryInfos.Count == 0)
+ {
+ throw new CmisObjectNotFoundException("Repository '" + repositoryId + "'not found!");
+ }
+
+ if (repositoryInfos.Count == 1)
+ {
+ return repositoryInfos[0];
+ }
+
+ // find the repository
+ foreach (IRepositoryInfo info in repositoryInfos)
+ {
+ if (info.Id == null)
+ {
+ continue;
+ }
+
+ if (info.Id == repositoryId)
+ {
+ return info;
+ }
+ }
+
+ throw new CmisObjectNotFoundException("Repository '" + repositoryId + "'not found!");
+ }
+
+ public ITypeDefinitionList GetTypeChildren(string repositoryId, string typeId, bool? includePropertyDefinitions,
+ BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId, BindingConstants.SelectorTypeChildren);
+ url.AddParameter(BindingConstants.ParamTypeId, typeId);
+ url.AddParameter(BindingConstants.ParamPropertyDefinitions, includePropertyDefinitions);
+ url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+ url.AddParameter(BindingConstants.ParamSkipCount, skipCount);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertTypeChildren(json);
+ }
+
+ public IList<ITypeDefinitionContainer> GetTypeDescendants(string repositoryId, string typeId, BigInteger? depth,
+ bool? includePropertyDefinitions, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId, BindingConstants.SelectorTypeDecendants);
+ url.AddParameter(BindingConstants.ParamTypeId, typeId);
+ url.AddParameter(BindingConstants.ParamDepth, depth);
+ url.AddParameter(BindingConstants.ParamPropertyDefinitions, includePropertyDefinitions);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonArray json = ParseArray(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertTypeDescendants(json);
+ }
+
+ public ITypeDefinition GetTypeDefinition(string repositoryId, string typeId, IExtensionsData extension)
+ {
+ return GetTypeDefinitionInternal(repositoryId, typeId);
+ }
+
+
+ public ITypeDefinition CreateType(string repositoryId, ITypeDefinition type, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCreateType);
+ if (type != null)
+ {
+ StringWriter sw = new StringWriter();
+ JsonConverter.Convert(type, DateTimeFormat).WriteJsonString(sw);
+
+ composer.Parameters[BindingConstants.ControlType] = sw.ToString();
+ }
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertTypeDefinition(json);
+ }
+
+ public ITypeDefinition UpdateType(string repositoryId, ITypeDefinition type, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionUpdateType);
+ if (type != null)
+ {
+ StringWriter sw = new StringWriter();
+ JsonConverter.Convert(type, DateTimeFormat).WriteJsonString(sw);
+
+ composer.Parameters[BindingConstants.ControlType] = sw.ToString();
+ }
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertTypeDefinition(json);
+ }
+
+ public void DeleteType(string repositoryId, string typeId, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionDeleteType);
+ composer.Parameters[BindingConstants.ControlTypeId] = typeId;
+
+ // send
+ PostAndConsume(url, composer.CreateHttpContent());
+ }
+ }
+
+ internal class NavigationService : AbstractBrowserBindingService, INavigationService
+ {
+ public NavigationService(BindingSession session)
+ {
+ Session = session;
+ }
+
+ public IObjectInFolderList GetChildren(string repositoryId, string folderId, string filter, string orderBy,
+ bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
+ bool? includePathSegment, BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, folderId, BindingConstants.SelectorChildren);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamOrderBy, orderBy);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamPathSegment, includePathSegment);
+ url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+ url.AddParameter(BindingConstants.ParamSkipCount, skipCount);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObjectInFolderList(json, typeCache);
+ }
+
+ public IList<IObjectInFolderContainer> GetDescendants(string repositoryId, string folderId, BigInteger? depth, string filter,
+ bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
+ bool? includePathSegment, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, folderId, BindingConstants.SelectorDecendants);
+ url.AddParameter(BindingConstants.ParamDepth, depth);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamPathSegment, includePathSegment);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonArray json = ParseArray(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertDescendants(json, typeCache);
+ }
+
+ public IList<IObjectInFolderContainer> GetFolderTree(string repositoryId, string folderId, BigInteger? depth, string filter,
+ bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
+ bool? includePathSegment, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, folderId, BindingConstants.SelectorFolderTree);
+ url.AddParameter(BindingConstants.ParamDepth, depth);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamPathSegment, includePathSegment);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonArray json = ParseArray(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertDescendants(json, typeCache);
+ }
+
+ public IList<IObjectParentData> GetObjectParents(string repositoryId, string objectId, string filter,
+ bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
+ bool? includeRelativePathSegment, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorParents);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamRelativePathSegment, includeRelativePathSegment);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonArray json = ParseArray(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObjectParents(json, typeCache);
+ }
+
+ public IObjectData GetFolderParent(string repositoryId, string folderId, string filter, ExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, folderId, BindingConstants.SelectorParent);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObject(json, typeCache);
+ }
+
+ public IObjectList GetCheckedOutDocs(string repositoryId, string folderId, string filter, string orderBy,
+ bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
+ BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = (folderId != null ? GetObjectUrl(repositoryId, folderId, BindingConstants.SelectorCheckedout)
+ : GetRepositoryUrl(repositoryId, BindingConstants.SelectorCheckedout));
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamOrderBy, orderBy);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+ url.AddParameter(BindingConstants.ParamSkipCount, skipCount);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObjectList(json, typeCache, false);
+ }
+ }
+
+ internal class ObjectService : AbstractBrowserBindingService, IObjectService
+ {
+ public ObjectService(BindingSession session)
+ {
+ Session = session;
+ }
+
+ public string CreateDocument(string repositoryId, IProperties properties, string folderId, IContentStream contentStream,
+ VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = (folderId != null ? GetObjectUrl(repositoryId, folderId) : GetRepositoryUrl(repositoryId));
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCreateDocument);
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Parameters[BindingConstants.ParamVersioningState] = versioningState;
+ composer.Policies = policies;
+ composer.AddAces = addAces;
+ composer.RemoveAces = removeAces;
+ composer.Stream = contentStream;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ return (newObj == null ? null : newObj.Id);
+ }
+
+ public string CreateDocumentFromSource(string repositoryId, string sourceId, IProperties properties, string folderId,
+ VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = (folderId != null ? GetObjectUrl(repositoryId, folderId) : GetRepositoryUrl(repositoryId));
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCreateDocumentFromSource);
+ composer.Parameters[BindingConstants.ParamSourceId] = sourceId;
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Parameters[BindingConstants.ParamVersioningState] = versioningState;
+ composer.Policies = policies;
+ composer.AddAces = addAces;
+ composer.RemoveAces = removeAces;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ return (newObj == null ? null : newObj.Id);
+ }
+
+ public string CreateFolder(string repositoryId, IProperties properties, string folderId, IList<string> policies,
+ IAcl addAces, IAcl removeAces, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, folderId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCreateFolder);
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Policies = policies;
+ composer.AddAces = addAces;
+ composer.RemoveAces = removeAces;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ return (newObj == null ? null : newObj.Id);
+ }
+
+ public string CreateRelationship(string repositoryId, IProperties properties, IList<string> policies, IAcl addAces,
+ IAcl removeAces, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCreateRelationship);
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Policies = policies;
+ composer.AddAces = addAces;
+ composer.RemoveAces = removeAces;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ return (newObj == null ? null : newObj.Id);
+ }
+
+ public string CreatePolicy(string repositoryId, IProperties properties, string folderId, IList<string> policies,
+ IAcl addAces, IAcl removeAces, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = (folderId != null ? GetObjectUrl(repositoryId, folderId) : GetRepositoryUrl(repositoryId));
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCreatePolicy);
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Policies = policies;
+ composer.AddAces = addAces;
+ composer.RemoveAces = removeAces;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ return (newObj == null ? null : newObj.Id);
+ }
+
+ public string CreateItem(string repositoryId, IProperties properties, string folderId, IList<string> policies,
+ IAcl addAces, IAcl removeAces, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = (folderId != null ? GetObjectUrl(repositoryId, folderId) : GetRepositoryUrl(repositoryId));
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCreateItem);
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Policies = policies;
+ composer.AddAces = addAces;
+ composer.RemoveAces = removeAces;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ return (newObj == null ? null : newObj.Id);
+ }
+
+ public IAllowableActions GetAllowableActions(string repositoryId, string objectId, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorAllowableActionS);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertAllowableActions(json);
+ }
+
+ public IProperties GetProperties(string repositoryId, string objectId, string filter, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorProperties);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ if (Succinct)
+ {
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+ return JsonConverter.ConvertSuccinctProperties(json, null, typeCache);
+ }
+ else
+ {
+ return JsonConverter.ConvertProperties(json, null);
+ }
+ }
+
+ public IList<IRenditionData> GetRenditions(string repositoryId, string objectId, string renditionFilter,
+ BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorRenditions);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+ url.AddParameter(BindingConstants.ParamSkipCount, skipCount);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonArray json = ParseArray(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertRenditions(json);
+ }
+
+ public IObjectData GetObject(string repositoryId, string objectId, string filter, bool? includeAllowableActions,
+ IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds,
+ bool? includeAcl, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorObject);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamPolicyIds, includePolicyIds);
+ url.AddParameter(BindingConstants.ParamAcl, includeAcl);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObject(json, typeCache);
+ }
+
+ public IObjectData GetObjectByPath(string repositoryId, string path, string filter, bool? includeAllowableActions,
+ IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds, bool? includeAcl,
+ IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetPathUrl(repositoryId, path, BindingConstants.SelectorObject);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamPolicyIds, includePolicyIds);
+ url.AddParameter(BindingConstants.ParamAcl, includeAcl);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObject(json, typeCache);
+ }
+
+ public IContentStream GetContentStream(string repositoryId, string objectId, string streamId, BigInteger? offset, BigInteger? length,
+ IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorContent);
+ url.AddParameter(BindingConstants.ParamStreamId, streamId);
+
+ // get the content
+ IResponse resp = Session.GetHttpInvoker().InvokeGET(url, Session, (long?)offset, (long?)length);
+
+ // check response code
+ if ((resp.StatusCode != 200) && (resp.StatusCode != 206))
+ {
+ throw ConvertStatusCode(resp.StatusCode, resp.Message, resp.ErrorContent, null);
+ }
+
+ // build result object
+ ContentStream result;
+ if (resp.StatusCode == 206)
+ {
+ result = new PartialContentStream();
+ }
+ else
+ {
+ result = new ContentStream();
+ }
+
+ result.FileName = resp.Filename;
+ result.Length = resp.ContentLength;
+ result.MimeType = resp.ContentType;
+ result.Stream = resp.Stream;
+
+ return result;
+ }
+
+ public void UpdateProperties(string repositoryId, ref string objectId, ref string changeToken, IProperties properties,
+ IExtensionsData extension)
+ {
+ // we need an object ID
+ if (objectId == null || objectId.Length == 0)
+ {
+ throw new CmisInvalidArgumentException("Object ID must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionUpdateProperties);
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Parameters[BindingConstants.ParamChangeToken] =
+ (changeToken == null || Session.GetValue(SessionParameter.OmitChangeTokens, false) ? null : changeToken);
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ objectId = (newObj == null ? null : newObj.Id);
+
+ SetChangeToken(ref changeToken, newObj);
+ }
+
+ public IList<IBulkUpdateObjectIdAndChangeToken> BulkUpdateProperties(string repositoryId,
+ IList<IBulkUpdateObjectIdAndChangeToken> objectIdAndChangeToken, IProperties properties,
+ IList<string> addSecondaryTypeIds, IList<string> removeSecondaryTypeIds, IExtensionsData extension)
+ {
+ // we need object ids
+ if (objectIdAndChangeToken == null || objectIdAndChangeToken.Count == 0)
+ {
+ throw new CmisInvalidArgumentException("Object IDs must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionBulkUpdate);
+ composer.ObjectIdsAndChangeTokens = objectIdAndChangeToken;
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.AddSecondaryTypeIds = addSecondaryTypeIds;
+ composer.RemoveSecondaryTypeIds = removeSecondaryTypeIds;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonArray json = ParseArray(resp.Stream, resp.Charset);
+
+ return JsonConverter.ConvertBulkUpdate(json);
+ }
+
+ public void MoveObject(string repositoryId, ref string objectId, string targetFolderId, string sourceFolderId,
+ IExtensionsData extension)
+ {
+ // we need an object id
+ if (objectId == null || objectId.Length == 0)
+ {
+ throw new CmisInvalidArgumentException("Object ID must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionMove);
+ composer.Parameters[BindingConstants.ParamTargetFolderId] = targetFolderId;
+ composer.Parameters[BindingConstants.ParamSourceFolderId] = sourceFolderId;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ objectId = (newObj == null ? null : newObj.Id);
+ }
+
+ public void DeleteObject(string repositoryId, string objectId, bool? allVersions, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionDelete);
+ composer.Parameters[BindingConstants.ParamAllVersions] = allVersions;
+
+ // send
+ PostAndConsume(url, composer.CreateHttpContent());
+ }
+
+ public IFailedToDeleteData DeleteTree(string repositoryId, string folderId, bool? allVersions, UnfileObject? unfileObjects,
+ bool? continueOnFailure, ExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, folderId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionDeleteTree);
+ composer.Parameters[BindingConstants.ParamAllVersions] = allVersions;
+ composer.Parameters[BindingConstants.ParamUnfileObjects] = unfileObjects;
+ composer.Parameters[BindingConstants.ParamContinueOnFailure] = continueOnFailure;
+
+ // send
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ if (resp.StatusCode == 200 && resp.ContentLength > 0 && (!resp.Stream.CanSeek || resp.Stream.Length > 0))
+ {
+ try
+ {
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+ return JsonConverter.ConvertFailedToDelete(json);
+ }
+ catch (IOException e)
+ {
+ throw new CmisConnectionException("Cannot read response!", e);
+ }
+ }
+
+ return new FailedToDeleteData();
+ }
+
+ public void SetContentStream(string repositoryId, ref string objectId, bool? overwriteFlag, ref string changeToken,
+ IContentStream contentStream, IExtensionsData extension)
+ {
+ // we need an object id
+ if (objectId == null || objectId.Length == 0)
+ {
+ throw new CmisInvalidArgumentException("Object ID must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionSetContent);
+ composer.Stream = contentStream;
+ composer.Parameters[BindingConstants.ParamOverwriteFlag] = overwriteFlag;
+ composer.Succinct = Succinct;
+ composer.Parameters[BindingConstants.ParamChangeToken] =
+ (changeToken == null || Session.GetValue(SessionParameter.OmitChangeTokens, false) ? null : changeToken);
+
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ objectId = (newObj == null ? null : newObj.Id);
+
+ SetChangeToken(ref changeToken, newObj);
+ }
+
+ public void AppendContentStream(string repositoryId, ref string objectId, bool? isLastChunk, ref string changeToken,
+ IContentStream contentStream, IExtensionsData extension)
+ {
+ // we need an object id
+ if (objectId == null || objectId.Length == 0)
+ {
+ throw new CmisInvalidArgumentException("Object ID must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionAppendContent);
+ composer.Stream = contentStream;
+ composer.Parameters[BindingConstants.ControlIsLastChunk] = isLastChunk;
+ composer.Succinct = Succinct;
+ composer.Parameters[BindingConstants.ParamChangeToken] =
+ (changeToken == null || Session.GetValue(SessionParameter.OmitChangeTokens, false) ? null : changeToken);
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ objectId = (newObj == null ? null : newObj.Id);
+
+ SetChangeToken(ref changeToken, newObj);
+ }
+
+ public void DeleteContentStream(string repositoryId, ref string objectId, ref string changeToken, IExtensionsData extension)
+ {
+ // we need an object id
+ if (objectId == null || objectId.Length == 0)
+ {
+ throw new CmisInvalidArgumentException("Object ID must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionDeleteContent);
+ composer.Succinct = Succinct;
+ composer.Parameters[BindingConstants.ParamChangeToken] =
+ (changeToken == null || Session.GetValue(SessionParameter.OmitChangeTokens, false) ? null : changeToken);
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ objectId = (newObj == null ? null : newObj.Id);
+
+ SetChangeToken(ref changeToken, newObj);
+ }
+ }
+
+ internal class VersioningService : AbstractBrowserBindingService, IVersioningService
+ {
+ public VersioningService(BindingSession session)
+ {
+ Session = session;
+ }
+
+ public void CheckOut(string repositoryId, ref string objectId, IExtensionsData extension, out bool? contentCopied)
+ {
+ // we need an object id
+ if (objectId == null || objectId.Length == 0)
+ {
+ throw new CmisInvalidArgumentException("Object ID must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCheckOut);
+ composer.Succinct = Succinct;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ objectId = (newObj == null ? null : newObj.Id);
+
+ contentCopied = null;
+ }
+
+ public void CancelCheckOut(string repositoryId, string objectId, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCancelCheckOut);
+
+ // send
+ PostAndConsume(url, composer.CreateHttpContent());
+ }
+
+ public void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties,
+ IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces,
+ IExtensionsData extension)
+ {
+ // we need an object id
+ if (objectId == null || objectId.Length == 0)
+ {
+ throw new CmisInvalidArgumentException("Object ID must be set!");
+ }
+
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionCheckIn);
+ composer.Stream = contentStream;
+ composer.Parameters[BindingConstants.ParamMajor] = major;
+ composer.Properties = properties;
+ composer.Succinct = Succinct;
+ composer.DateTimeFormat = DateTimeFormat;
+ composer.Parameters[BindingConstants.ParamCheckinComment] = checkinComment;
+ composer.Policies = policies;
+ composer.AddAces = addAces;
+ composer.RemoveAces = removeAces;
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ IObjectData newObj = JsonConverter.ConvertObject(json, typeCache);
+
+ objectId = (newObj == null ? null : newObj.Id);
+ }
+
+ public IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+ string filter, bool? includeAllowableActions, IncludeRelationships? includeRelationships,
+ string renditionFilter, bool? includePolicyIds, bool? includeAcl, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorObject);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamRelationships, includeRelationships);
+ url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
+ url.AddParameter(BindingConstants.ParamPolicyIds, includePolicyIds);
+ url.AddParameter(BindingConstants.ParamAcl, includeAcl);
+ url.AddParameter(BindingConstants.ParamReturnVersion, (!major ? ReturnVersion.Latest : ReturnVersion.LatestMajor));
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObject(json, typeCache);
+ }
+
+ public IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+ string filter, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorProperties);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamReturnVersion, (!major ? ReturnVersion.Latest : ReturnVersion.LatestMajor));
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ if (Succinct)
+ {
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+ return JsonConverter.ConvertSuccinctProperties(json, null, typeCache);
+ }
+ else
+ {
+ return JsonConverter.ConvertProperties(json, null);
+ }
+ }
+
+ public IList<IObjectData> GetAllVersions(string repositoryId, string objectId, string versionSeriesId, string filter,
+ bool? includeAllowableActions, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorVersions);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+
+ JsonArray json = ParseArray(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObjects(json, typeCache);
+ }
+ }
+
+ internal class DiscoveryService : AbstractBrowserBindingService, IDiscoveryService
+ {
+ public DiscoveryService(BindingSession session)
+ {
+ Session = session;
+ }
+
+ public IObjectList Query(string repositoryId, string statement, bool? searchAllVersions,
+ bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
+ BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionQuery);
+ composer.Parameters[BindingConstants.ParamStatement] = statement;
+ composer.Parameters[BindingConstants.ParamSearchAllVersions] = searchAllVersions;
+ composer.Parameters[BindingConstants.ParamAllowableActions] = includeAllowableActions;
+ composer.Parameters[BindingConstants.ParamRelationships] = includeRelationships;
+ composer.Parameters[BindingConstants.ParamRenditionfilter] = renditionFilter;
+ composer.Parameters[BindingConstants.ParamMaxItems] = maxItems;
+ composer.Parameters[BindingConstants.ParamSkipCount] = skipCount;
+ composer.DateTimeFormat = DateTimeFormat;
+ // Important: No succinct flag here!!!
+
+ // send and parse
+ IResponse resp = Post(url, composer.CreateHttpContent());
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+ return JsonConverter.ConvertObjectList(json, typeCache, true);
+ }
+
+ public IObjectList GetContentChanges(string repositoryId, ref string changeLogToken, bool? includeProperties,
+ string filter, bool? includePolicyIds, bool? includeAcl, BigInteger? maxItems, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetRepositoryUrl(repositoryId, BindingConstants.SelectorContentChanges);
+ url.AddParameter(BindingConstants.ParamChangeLogToken, changeLogToken);
+ url.AddParameter(BindingConstants.ParamProperties, includeProperties);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamPolicyIds, includePolicyIds);
+ url.AddParameter(BindingConstants.ParamAcl, includeAcl);
+ url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ if (changeLogToken != null && json != null)
+ {
+ object token = json[BrowserConstants.JsonObjectListChangeLogToken];
+ if (token is string)
+ {
+ changeLogToken = (string)token;
+ }
+ }
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObjectList(json, typeCache, false);
+ }
+ }
+
+ internal class RelationshipService : AbstractBrowserBindingService, IRelationshipService
+ {
+ public RelationshipService(BindingSession session)
+ {
+ Session = session;
+ }
+
+ public IObjectList GetObjectRelationships(string repositoryId, string objectId, bool? includeSubRelationshipTypes,
+ RelationshipDirection? relationshipDirection, string typeId, string filter, bool? includeAllowableActions,
+ BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorRelationships);
+ url.AddParameter(BindingConstants.ParamSubRelationshipTypes, includeSubRelationshipTypes);
+ url.AddParameter(BindingConstants.ParamRelationshipDirection, relationshipDirection);
+ url.AddParameter(BindingConstants.ParamTypeId, typeId);
+ url.AddParameter(BindingConstants.Paramfilter, filter);
+ url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+ url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+ url.AddParameter(BindingConstants.ParamSkipCount, skipCount);
+ url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
+ url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
+
+ // read and parse
+ IResponse resp = Read(url);
+ JsonObject json = ParseObject(resp.Stream, resp.Charset);
+
+ ITypeCache typeCache = new ClientTypeCache(repositoryId, this);
+
+ return JsonConverter.ConvertObjectList(json, typeCache, false);
+ }
+ }
+
+ internal class MultiFilingService : AbstractBrowserBindingService, IMultiFilingService
+ {
+ public MultiFilingService(BindingSession session)
+ {
+ Session = session;
+ }
+
+ public void AddObjectToFolder(string repositoryId, string objectId, string folderId, bool? allVersions, IExtensionsData extension)
+ {
+ // build URL
+ UrlBuilder url = GetObjectUrl(repositoryId, objectId);
+
+ // prepare form data
+ FormDataComposer composer = new FormDataComposer(BindingConstants.CmisActionRemoveObjectToFolder);
+ composer.Parameters[BindingConstants.ParamFolderId] = folderId;
+ composer.Parameters[BindingConstants.ParamAllVersions] = allVersions;
+
+ // send
+ PostAndConsume(url, composer.CreateHttpContent());
+ }
+
+ public void RemoveObjectFromFolder(string repositoryId, string objectId, string folderId, IExtensionsData extension)
+ {
+ // build URL
[... 104 lines stripped ...]