Added: chemistry/portcmis/PortCMIS/binding/BindingIntf.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/BindingIntf.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/BindingIntf.cs (added) +++ chemistry/portcmis/PortCMIS/binding/BindingIntf.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,293 @@ +/* +* 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.Http; +using PortCMIS.Binding.Impl; +using PortCMIS.Binding.Services; +using PortCMIS.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace PortCMIS.Binding +{ + public interface ICmisBinding : IDisposable + { + string BindingType { get; } + IRepositoryService GetRepositoryService(); + INavigationService GetNavigationService(); + IObjectService GetObjectService(); + IVersioningService GetVersioningService(); + IRelationshipService GetRelationshipService(); + IDiscoveryService GetDiscoveryService(); + IMultiFilingService GetMultiFilingService(); + IAclService GetAclService(); + IPolicyService GetPolicyService(); + IAuthenticationProvider GetAuthenticationProvider(); + void ClearAllCaches(); + void ClearRepositoryCache(string repositoryId); + } + + public interface IBindingSession + { + object GetValue(string key); + object GetValue(string key, object defValue); + int GetValue(string key, int defValue); + bool GetValue(string key, bool defValue); + + void PutValue(string key, object value); + void RemoveValue(string key); + + IAuthenticationProvider GetAuthenticationProvider(); + IHttpInvoker GetHttpInvoker(); + } + + /// <summary> + /// SPI interface. + /// </summary> + public interface ICmisSpi : IDisposable + { + void Initialize(IBindingSession session); + IRepositoryService GetRepositoryService(); + INavigationService GetNavigationService(); + IObjectService GetObjectService(); + IVersioningService GetVersioningService(); + IRelationshipService GetRelationshipService(); + IDiscoveryService GetDiscoveryService(); + IMultiFilingService GetMultiFilingService(); + IAclService GetAclService(); + IPolicyService GetPolicyService(); + void ClearAllCaches(); + void ClearRepositoryCache(string repositoryId); + } + + public interface IAuthenticationProvider + { + IBindingSession Session { get; set; } + } + + public interface IPortableAuthenticationProvider : IAuthenticationProvider + { + void PrepareHttpClientHandler(HttpClientHandler httpClientHandler); + void PrepareHttpRequestMessage(HttpRequestMessage httpRequestMessage); + void HandleResponse(HttpResponseMessage httpResponseMessage); + } + + public abstract class AbstractAuthenticationProvider : IPortableAuthenticationProvider + { + public IBindingSession Session { get; set; } + public CookieContainer CookieContainer { get; private set; } + public string User { get { return Session.GetValue(SessionParameter.User) as string; } } + public string Password { get { return Session.GetValue(SessionParameter.Password) as string; } } + + public virtual void PrepareHttpClientHandler(HttpClientHandler httpClientHandler) + { + httpClientHandler.PreAuthenticate = true; + httpClientHandler.UseCookies = true; + httpClientHandler.UseProxy = true; + CookieContainer = new CookieContainer(); + httpClientHandler.CookieContainer = CookieContainer; + } + + public virtual void PrepareHttpRequestMessage(HttpRequestMessage httpRequestMessage) + { + } + + public virtual void HandleResponse(HttpResponseMessage httpResponseMessage) + { + } + } + + public class StandardAuthenticationProvider : AbstractAuthenticationProvider + { + public override void PrepareHttpClientHandler(HttpClientHandler httpClientHandler) + { + base.PrepareHttpClientHandler(httpClientHandler); + + if (User != null) + { + httpClientHandler.Credentials = new NetworkCredential(User, Password); + } + else + { + httpClientHandler.UseDefaultCredentials = true; + } + } + } + + public class CmisBindingFactory + { + // Default CMIS AtomPub binding SPI implementation + public const string BindingSpiAtomPub = "PortCMIS.Binding.AtomPub.CmisAtomPubSpi"; + // Default CMIS Browser binding SPI implementation + public const string BindingSpiBrowser = "PortCMIS.Binding.Browser.CmisBrowserSpi"; + + public const string StandardAuthenticationProviderClass = "PortCMIS.Binding.StandardAuthenticationProvider"; + public const string DefaultHttpInvokerClass = "PortCMIS.Binding.Http.DefaultHttpInvoker"; + + private IDictionary<string, string> defaults; + + private CmisBindingFactory() + { + defaults = CreateNewDefaultParameters(); + } + + public static CmisBindingFactory NewInstance() + { + return new CmisBindingFactory(); + } + + public IDictionary<string, string> GetDefaultSessionParameters() + { + return defaults; + } + + public void SetDefaultSessionParameters(IDictionary<string, string> sessionParameters) + { + if (sessionParameters == null) + { + defaults = CreateNewDefaultParameters(); + } + else + { + defaults = sessionParameters; + } + } + + public ICmisBinding CreateCmisBinding(IDictionary<string, string> sessionParameters, IAuthenticationProvider authenticationProvider) + { + CheckSessionParameters(sessionParameters, true); + AddDefaultParameters(sessionParameters); + + return new CmisBinding(sessionParameters, authenticationProvider); + } + + public ICmisBinding CreateCmisBrowserBinding(IDictionary<string, string> sessionParameters, IAuthenticationProvider authenticationProvider) + { + CheckSessionParameters(sessionParameters, false); + sessionParameters[SessionParameter.BindingSpiClass] = BindingSpiBrowser; + if (authenticationProvider == null) + { + if (!sessionParameters.ContainsKey(SessionParameter.AuthenticationProviderClass)) + { + sessionParameters[SessionParameter.AuthenticationProviderClass] = StandardAuthenticationProviderClass; + } + } + if (!sessionParameters.ContainsKey(SessionParameter.HttpInvokerClass)) + { + sessionParameters[SessionParameter.HttpInvokerClass] = DefaultHttpInvokerClass; + } + + AddDefaultParameters(sessionParameters); + if (!sessionParameters.ContainsKey(SessionParameter.BrowserSuccinct)) + { + sessionParameters.Add(SessionParameter.BrowserSuccinct, "true"); + } + + Check(sessionParameters, SessionParameter.BrowserUrl); + + return new CmisBinding(sessionParameters, authenticationProvider); + } + + public ICmisBinding CreateCmisAtomPubBinding(IDictionary<string, string> sessionParameters, IAuthenticationProvider authenticationProvider) + { + CheckSessionParameters(sessionParameters, false); + sessionParameters[SessionParameter.BindingSpiClass] = BindingSpiAtomPub; + if (authenticationProvider == null) + { + if (!sessionParameters.ContainsKey(SessionParameter.AuthenticationProviderClass)) + { + sessionParameters[SessionParameter.AuthenticationProviderClass] = StandardAuthenticationProviderClass; + } + } + + AddDefaultParameters(sessionParameters); + + Check(sessionParameters, SessionParameter.AtomPubUrl); + + return new CmisBinding(sessionParameters, authenticationProvider); + } + + public ICmisBinding CreateCmisWebServicesBinding(IDictionary<string, string> sessionParameters, IAuthenticationProvider authenticationProvider) + { + throw new ArgumentException("The Web Services binding is not supported!"); + } + + // ---- internals ---- + + private void CheckSessionParameters(IDictionary<string, string> sessionParameters, bool mustContainSpi) + { + // don't accept null + if (sessionParameters == null) + { + throw new ArgumentNullException("sessionParameters"); + } + + // check binding entry + if (mustContainSpi) + { + string spiClass; + + if (sessionParameters.TryGetValue(SessionParameter.BindingSpiClass, out spiClass)) + { + throw new ArgumentException("SPI class entry (" + SessionParameter.BindingSpiClass + ") is missing!"); + } + + if ((spiClass == null) || (spiClass.Trim().Length == 0)) + { + throw new ArgumentException("SPI class entry (" + SessionParameter.BindingSpiClass + ") is invalid!"); + } + } + } + + private void Check(IDictionary<string, string> sessionParameters, String parameter) + { + if (!sessionParameters.ContainsKey(parameter)) + { + throw new ArgumentException("Parameter '" + parameter + "' is missing!"); + } + } + + private void AddDefaultParameters(IDictionary<string, string> sessionParameters) + { + foreach (string key in defaults.Keys) + { + if (!sessionParameters.ContainsKey(key)) + { + sessionParameters[key] = defaults[key]; + } + } + } + + private IDictionary<string, string> CreateNewDefaultParameters() + { + IDictionary<string, string> result = new Dictionary<string, string>(); + + result[SessionParameter.CacheSizeRepositories] = SessionParameterDefaults.CacheSizeRepositories.ToString(); + result[SessionParameter.CacheSizeTypes] = SessionParameterDefaults.CacheSizeTypes.ToString(); + result[SessionParameter.CacheSizeLinks] = SessionParameterDefaults.CacheSizeLinks.ToString(); + + return result; + } + } +}
Added: chemistry/portcmis/PortCMIS/binding/BindingsConstants.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/BindingsConstants.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/BindingsConstants.cs (added) +++ chemistry/portcmis/PortCMIS/binding/BindingsConstants.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,223 @@ +/* +* 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 System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PortCMIS.Binding +{ + internal class BindingConstants + { + // media types + public const string MediaTypeService = "application/atomsvc+xml"; + public const string MediaTypeFeed = "application/atom+xml;type=feed"; + public const string MediaTypeEntry = "application/atom+xml;type=entry"; + public const string MediaTypeChildren = MediaTypeFeed; + public const string MediaTypeDecendants = "application/cmistree+xml"; + public const string MediaTypeQuery = "application/cmisquery+xml"; + public const string MediaTypeAllowableAction = "application/cmisallowableactions+xml"; + public const string MediaTypeAcl = "application/cmisacl+xml"; + public const string MediaTypeCmisAtom = "application/cmisatom+xml"; + public const string MediaTypeOctetStream = "application/octet-stream"; + + // collections + public const string CollectionRoot = "root"; + public const string CollectionTypes = "types"; + public const string CollectionQuery = "query"; + public const string CollectionCheckedout = "checkedout"; + public const string CollectionUnfiled = "unfiled"; + public const string CollectionBulkUpdate = "update"; + + // URI templates + public const string TemplateObjectById = "objectbyid"; + public const string TemplateObjectByPath = "objectbypath"; + public const string TemplateTypeById = "typebyid"; + public const string TemplateQuery = "query"; + + // Link rel + public const string RelSelf = "self"; + public const string RelEnclosure = "enclosure"; + public const string RelService = "service"; + public const string RelDescribedby = "describedby"; + public const string RelAlternate = "alternate"; + public const string RelDown = "down"; + public const string RelUp = "up"; + public const string RelFirst = "first"; + public const string RelLast = "last"; + public const string RelPrev = "previous"; + public const string RelNext = "next"; + public const string RelVia = "via"; + public const string RelEdit = "edit"; + public const string RelEditMedia = "edit-media"; + public const string RelVersionHistory = "version-history"; + public const string RelCurrentVersion = "current-version"; + public const string RelWorkingCopy = "working-copy"; + public const string RelFolderTree = "http://docs.oasis-open.org/ns/cmis/link/200908/foldertree"; + public const string RelAllowableActions = "http://docs.oasis-open.org/ns/cmis/link/200908/allowableactions"; + public const string RelAcl = "http://docs.oasis-open.org/ns/cmis/link/200908/acl"; + public const string RelSource = "http://docs.oasis-open.org/ns/cmis/link/200908/source"; + public const string RelTarget = "http://docs.oasis-open.org/ns/cmis/link/200908/target"; + + public const string RelRelationships = "http://docs.oasis-open.org/ns/cmis/link/200908/relationships"; + public const string RelPolicies = "http://docs.oasis-open.org/ns/cmis/link/200908/policies"; + + public const string RepRelTypeDesc = "http://docs.oasis-open.org/ns/cmis/link/200908/typedescendants"; + public const string RepRelFolderTree = "http://docs.oasis-open.org/ns/cmis/link/200908/foldertree"; + public const string RepRelRootDesc = "http://docs.oasis-open.org/ns/cmis/link/200908/rootdescendants"; + public const string RepRelChanges = "http://docs.oasis-open.org/ns/cmis/link/200908/changes"; + + // browser binding selectors + public const string SelectorLastResult = "lastResult"; + public const string SelectorRepositoryInfo = "repositoryInfo"; + public const string SelectorTypeChildren = "typeChildren"; + public const string SelectorTypeDecendants = "typeDescendants"; + public const string SelectorTypeDefinition = "typeDefinition"; + public const string SelectorContent = "content"; + public const string SelectorObject = "object"; + public const string SelectorProperties = "properties"; + public const string SelectorAllowableActionS = "allowableActions"; + public const string SelectorRenditions = "renditions"; + public const string SelectorChildren = "children"; + public const string SelectorDecendants = "descendants"; + public const string SelectorParents = "parents"; + public const string SelectorParent = "parent"; + public const string SelectorFolderTree = "folderTree"; + public const string SelectorQuery = "query"; + public const string SelectorVersions = "versions"; + public const string SelectorRelationships = "relationships"; + public const string SelectorCheckedout = "checkedout"; + public const string SelectorPolicies = "policies"; + public const string SelectorAcl = "acl"; + public const string SelectorContentChanges = "contentChanges"; + + // browser binding actions + public const string CmisActionCreateType = "createType"; + public const string CmisActionUpdateType = "updateType"; + public const string CmisActionDeleteType = "deleteType"; + public const string CmisActionCreateDocument = "createDocument"; + public const string CmisActionCreateDocumentFromSource = "createDocumentFromSource"; + public const string CmisActionCreateFolder = "createFolder"; + public const string CmisActionCreateRelationship = "createRelationship"; + public const string CmisActionCreatePolicy = "createPolicy"; + public const string CmisActionCreateItem = "createItem"; + public const string CmisActionUpdateProperties = "update"; + public const string CmisActionBulkUpdate = "bulkUpdate"; + public const string CmisActionDeleteContent = "deleteContent"; + public const string CmisActionSetContent = "setContent"; + public const string CmisActionAppendContent = "appendContent"; + public const string CmisActionDelete = "delete"; + public const string CmisActionDeleteTree = "deleteTree"; + public const string CmisActionMove = "move"; + public const string CmisActionRemoveObjectToFolder = "addObjectToFolder"; + public const string CmisActionRemoveObjectFromFolder = "removeObjectFromFolder"; + public const string CmisActionQuery = "query"; + public const string CmisActionCheckOut = "checkOut"; + public const string CmisActionCancelCheckOut = "cancelCheckOut"; + public const string CmisActionCheckIn = "checkIn"; + public const string CmisActionApplyPolicy = "applyPolicy"; + public const string CmisActionRemovePolicy = "removePolicy"; + public const string CmisActionApplyAcl = "applyACL"; + + // browser binding control + public const string ControlCmisAction = "cmisaction"; + public const string ControlSuccinct = "succinct"; + public const string ControlToken = "token"; + public const string ControlObjectId = "objectId"; + public const string ControlPropId = "propertyId"; + public const string ControlPropValue = "propertyValue"; + public const string ControlPolicy = "policy"; + public const string ControlPolicyId = "policyId"; + public const string ControlAddAcePrincipal = "addACEPrincipal"; + public const string ControlAddAcePermission = "addACEPermission"; + public const string ControlRemoveAcePrincipal = "removeACEPrincipal"; + public const string ControlRemoveAcePermission = "removeACEPermission"; + public const string ControlContentType = "contenttype"; + public const string ControlFilename = "filename"; + public const string ControlIsLastChunk = "isLastChunk"; + public const string ControlType = "type"; + public const string ControlTypeId = "typeId"; + public const string ControlChangeToken = "changeToken"; + public const string ControlAddSecondaryType = "addSecondaryTypeId"; + public const string ControlRemoveSecondaryType = "removeSecondaryTypeId"; + + // parameter + public const string ParamAcl = "includeACL"; + public const string ParamAllowableActions = "includeAllowableActions"; + public const string ParamAllVersions = "allVersions"; + public const string ParamAppend = "append"; + public const string ParamChangeLogToken = "changeLogToken"; + public const string ParamChangeToken = "changeToken"; + public const string ParamCheckinComment = "checkinComment"; + public const string ParamCheckIn = "checkin"; + public const string ParamchildTypes = "childTypes"; + public const string ParamContinueOnFailure = "continueOnFailure"; + public const string ParamDepth = "depth"; + public const string Paramdownload = "download"; + public const string Paramfilter = "filter"; + public const string ParamSuccinct = "succinct"; + public const string ParamDateTimeFormat = "dateTimeFormat"; + public const string ParamFolderId = "folderId"; + public const string ParamId = "id"; + public const string ParamIsLastChunk = "isLastChunk"; + public const string ParamMajor = "major"; + public const string ParamMaxItems = "maxItems"; + public const string ParamObjectId = "objectId"; + public const string ParamOnlyBasicPermissions = "onlyBasicPermissions"; + public const string ParamOrderBy = "orderBy"; + public const string ParamOverwriteFlag = "overwriteFlag"; + public const string ParamPath = "path"; + public const string ParamPathSegment = "includePathSegment"; + public const string ParamPolicyId = "policyId"; + public const string ParamPolicyIds = "includePolicyIds"; + public const string ParamProperties = "includeProperties"; + public const string ParamPropertyDefinitions = "includePropertyDefinitions"; + public const string ParamRelationships = "includeRelationships"; + public const string ParamRelationshipDirection = "relationshipDirection"; + public const string ParamRelativePathSegment = "includeRelativePathSegment"; + public const string ParamRemoveFrom = "removeFrom"; + public const string ParamRenditionfilter = "renditionFilter"; + public const string ParamRepositoryId = "repositoryId"; + public const string ParamReturnVersion = "returnVersion"; + public const string ParamSkipCount = "skipCount"; + public const string ParamSourceFolderId = "sourceFolderId"; + public const string ParamTargetFolderId = "targetFolderId"; + public const string ParamStreamId = "streamId"; + public const string ParamSubRelationshipTypes = "includeSubRelationshipTypes"; + public const string ParamTypeId = "typeId"; + public const string ParamUnfileObjects = "unfileObjects"; + public const string ParamVersionSeriesId = "versionSeries"; + public const string ParamVersioningState = "versioningState"; + public const string ParamQ = "q"; + public const string ParamStatement = "statement"; + public const string ParamSearchAllVersions = "searchAllVersions"; + public const string ParamAclPropagation = "ACLPropagation"; + public const string ParamSourceId = "sourceId"; + + public const string ParamSelector = "cmisselector"; + public const string ParamCallback = "callback"; + public const string ParamSuppressResponseCodes = "suppressResponseCodes"; + public const string ParamToken = "token"; + + // rendition filter + public const string RenditionNone = "cmis:none"; + } +} Added: chemistry/portcmis/PortCMIS/binding/DateTimeHelper.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/DateTimeHelper.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/DateTimeHelper.cs (added) +++ chemistry/portcmis/PortCMIS/binding/DateTimeHelper.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,53 @@ +/* +* 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 System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace PortCMIS.Binding +{ + public class DateTimeHelper + { + private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + public static DateTime ConvertMillisToDateTime(long millis) + { + return new DateTime(Jan1st1970.Ticks + millis * TimeSpan.TicksPerMillisecond, DateTimeKind.Utc); + } + + public static long ConvertDateTimeToMillis(DateTime datetime) + { + return (datetime.Ticks - Jan1st1970.Ticks) / TimeSpan.TicksPerMillisecond; + } + + public static DateTime ParseISO8601(string s) { + return DateTime.Parse(s, null, DateTimeStyles.RoundtripKind); + } + + public static string FormatISO8601(DateTime dt) + { + return dt.ToString("o"); + } + } +} Added: chemistry/portcmis/PortCMIS/binding/Http.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/Http.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/Http.cs (added) +++ chemistry/portcmis/PortCMIS/binding/Http.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,54 @@ +/* +* 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.Client; +using PortCMIS.Exceptions; +using PortCMIS.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; + +namespace PortCMIS.Binding.Http +{ + public interface IHttpInvoker + { + IResponse InvokeGET(UrlBuilder url, IBindingSession session); + IResponse InvokeGET(UrlBuilder url, IBindingSession session, long? offset, long? length); + IResponse InvokePOST(UrlBuilder url, HttpContent content, IBindingSession session); + IResponse InvokePUT(UrlBuilder url, IDictionary<string, string> headers, HttpContent content, IBindingSession session); + IResponse InvokeDelete(UrlBuilder url, IBindingSession session); + } + + public interface IResponse + { + int StatusCode { get; } + string Message { get; } + Stream Stream { get; } + string ErrorContent { get; } + string ContentType { get; } + string Charset { get; } + long? ContentLength { get; } + string Filename { get; } + } +} Added: chemistry/portcmis/PortCMIS/binding/HttpPortable.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/HttpPortable.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/HttpPortable.cs (added) +++ chemistry/portcmis/PortCMIS/binding/HttpPortable.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,311 @@ +/* +* 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.Client; +using PortCMIS.Exceptions; +using PortCMIS.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; + +namespace PortCMIS.Binding.Http +{ + public class DefaultHttpInvoker : IHttpInvoker + { + private const string InvokerHttpClient = "org.apache.chemistry.portcmis.invoker.httpclient"; + private object invokerLock = new object(); + + public IResponse InvokeGET(UrlBuilder url, IBindingSession session) + { + return Invoke(url, HttpMethod.Get, null, session, null, null, null); + } + + public IResponse InvokeGET(UrlBuilder url, IBindingSession session, long? offset, long? length) + { + return Invoke(url, HttpMethod.Get, null, session, offset, length, null); + } + + public IResponse InvokePOST(UrlBuilder url, HttpContent content, IBindingSession session) + { + return Invoke(url, HttpMethod.Post, content, session, null, null, null); + } + + public IResponse InvokePUT(UrlBuilder url, IDictionary<string, string> headers, HttpContent content, IBindingSession session) + { + return Invoke(url, HttpMethod.Put, content, session, null, null, headers); + } + + public IResponse InvokeDelete(UrlBuilder url, IBindingSession session) + { + return Invoke(url, HttpMethod.Delete, null, session, null, null, null); + } + + private IResponse Invoke(UrlBuilder url, HttpMethod method, HttpContent content, IBindingSession session, + long? offset, long? length, IDictionary<string, string> headers) + { + if (Logger.IsDebugEnabled) + { + Logger.Debug("HTTP: " + method.ToString() + " " + url.ToString()); + } + + IPortableAuthenticationProvider authProvider = session.GetAuthenticationProvider() as IPortableAuthenticationProvider; + + HttpClient httpClient = session.GetValue(InvokerHttpClient) as HttpClient; + + if (httpClient == null) + { + lock (invokerLock) + { + httpClient = session.GetValue(InvokerHttpClient) as HttpClient; + if (httpClient == null) + { + + HttpClientHandler httpClientHandler = new HttpClientHandler(); + + // redirects + if (httpClientHandler.SupportsRedirectConfiguration) + { + httpClientHandler.AllowAutoRedirect = false; + } + + // compression + if (httpClientHandler.SupportsAutomaticDecompression) + { + string compressionFlag = session.GetValue(SessionParameter.Compression) as string; + if (compressionFlag != null && compressionFlag.ToLowerInvariant().Equals("true")) + { + httpClientHandler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; + } + } + + // authentictaion + httpClientHandler.PreAuthenticate = true; + httpClientHandler.UseDefaultCredentials = false; + + // authentication provider + if (authProvider != null) + { + authProvider.PrepareHttpClientHandler(httpClientHandler); + } + + // create HttpClient + httpClient = new HttpClient(httpClientHandler, true); + + // timeouts + int connectTimeout = session.GetValue(SessionParameter.ConnectTimeout, -2); + if (connectTimeout >= -1) + { + httpClient.Timeout = TimeSpan.FromMilliseconds(connectTimeout); + } + + session.PutValue(InvokerHttpClient, httpClient); + } + } + } + + HttpRequestMessage request = new HttpRequestMessage(method, url.ToString()); + + // set additional headers + request.Headers.UserAgent.Add(new ProductInfoHeaderValue("ApacheChemistryPortCMIS", "0.1")); + if (headers != null) + { + foreach (KeyValuePair<string, string> header in headers) + { + request.Headers.Add(header.Key, header.Value); + } + } + + // range + if (offset != null && length != null) + { + long longOffset = offset.Value < 0 ? 0 : offset.Value; + if (length.Value > 0) + { + request.Headers.Range = new RangeHeaderValue(longOffset, longOffset + length.Value - 1); + } + else + { + request.Headers.Range = new RangeHeaderValue(longOffset, null); + } + } + else if (offset != null && offset.Value > 0) + { + request.Headers.Range = new RangeHeaderValue(offset, null); + } + + // content + if (content != null) + { + request.Headers.TransferEncodingChunked = true; + request.Content = content; + } + + // authentication provider + if (authProvider != null) + { + authProvider.PrepareHttpRequestMessage(request); + } + + Response response; + try + { + Task<HttpResponseMessage> task = Send(httpClient, request); + if (task.IsFaulted) + { + throw task.Exception; + } + else + { + HttpResponseMessage httpResponseMessage = task.Result; + + if (authProvider != null) + { + authProvider.HandleResponse(httpResponseMessage); + } + response = new Response(httpResponseMessage); + } + } + catch (Exception e) + { + throw new CmisConnectionException("Cannot access " + url + ": " + e.Message, e); + } + + + return response; + } + + private async Task<HttpResponseMessage> Send(HttpClient httpClient, HttpRequestMessage request) + { + return await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); + } + } + + class Response : IResponse + { + private HttpResponseMessage response; + + public int StatusCode { get; private set; } + public string Message { get; private set; } + public Stream Stream { get; private set; } + public string ErrorContent { get; private set; } + public string ContentType { get; private set; } + public string Charset { get; private set; } + public long? ContentLength { get; private set; } + public string Filename { get; private set; } + + public Response(HttpResponseMessage httpResponse) + { + this.response = httpResponse; + StatusCode = (int)httpResponse.StatusCode; + Message = httpResponse.ReasonPhrase; + + bool isBase64 = false; + + if (httpResponse.Content != null) + { + if (httpResponse.Content.Headers.ContentType != null) + { + ContentType = httpResponse.Content.Headers.ContentType.MediaType; + Charset = httpResponse.Content.Headers.ContentType.CharSet; + } + ContentLength = httpResponse.Content.Headers.ContentLength; + + if (httpResponse.Content.Headers.ContentDisposition != null) + { + Filename = httpResponse.Content.Headers.ContentDisposition.FileName; + } + + if (httpResponse.Content.Headers.Contains("Content-Transfer-Encoding")) + { + IEnumerable<String> contentTransferEncoding = httpResponse.Content.Headers.GetValues("Content-Transfer-Encoding"); + isBase64 = contentTransferEncoding.Contains("base64", StringComparer.OrdinalIgnoreCase); + } + } + + if (httpResponse.StatusCode == HttpStatusCode.OK || + httpResponse.StatusCode == HttpStatusCode.Created || + httpResponse.StatusCode == HttpStatusCode.NonAuthoritativeInformation || + httpResponse.StatusCode == HttpStatusCode.PartialContent) + { + Stream = GetContentStream().Result; + + if (isBase64) + { + // TODO: this is only required for the AtomPub binding of SharePoint 2010 + // Stream = new CryptoStream(Stream, new FromBase64Transform(), CryptoStreamMode.Read); + } + } + else + { + if (httpResponse.StatusCode != HttpStatusCode.NoContent) + { + if (ContentType != null && + (ContentType.ToLowerInvariant().StartsWith("text/") || + ContentType.ToLowerInvariant().EndsWith("+xml") || + ContentType.ToLowerInvariant().StartsWith("application/xml") || + ContentType.ToLowerInvariant().StartsWith("application/json"))) + { + ErrorContent = GetContentString().Result; + } + } + + try + { + response.Dispose(); + response = null; + } + catch (Exception) { } + } + } + + public void CloseStream() + { + if (Stream != null) + { + Stream.Dispose(); + Stream = null; + } + + if (response != null) + { + try + { + response.Dispose(); + response = null; + } + catch (Exception) { } + } + } + + async private Task<Stream> GetContentStream() + { + return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + } + + async private Task<String> GetContentString() + { + return await response.Content.ReadAsStringAsync().ConfigureAwait(false); + } + } +} Added: chemistry/portcmis/PortCMIS/binding/IOUtils.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/IOUtils.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/IOUtils.cs (added) +++ chemistry/portcmis/PortCMIS/binding/IOUtils.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,81 @@ +/* +* 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 System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PortCMIS.binding +{ + class IOUtils + { + public static void ConsumeAndClose(TextReader reader) + { + if (reader == null) + { + return; + } + + try + { + char[] buffer = new char[64 * 1024]; + while (reader.Read(buffer, 0, buffer.Length) > 0) + { + // just consume + } + } + catch (IOException) + { + // ignore + } + finally + { + reader.Dispose(); + } + } + + public static void ConsumeAndClose(Stream stream) + { + if (stream == null) + { + return; + } + + try + { + byte[] buffer = new byte[64 * 1024]; + while (stream.Read(buffer, 0, buffer.Length) > 0) + { + // just consume + } + } + catch (IOException) + { + // ignore + } + finally + { + stream.Dispose(); + } + } + } +} Added: chemistry/portcmis/PortCMIS/binding/Services.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/Services.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/Services.cs (added) +++ chemistry/portcmis/PortCMIS/binding/Services.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,197 @@ +/* +* 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.Data; +using PortCMIS.Data.Extensions; +using PortCMIS.Enums; +using System.Collections.Generic; +using System.Numerics; + +namespace PortCMIS.Binding.Services +{ + public interface IRepositoryService + { + IList<IRepositoryInfo> GetRepositoryInfos(IExtensionsData extension); + + IRepositoryInfo GetRepositoryInfo(string repositoryId, IExtensionsData extension); + + ITypeDefinitionList GetTypeChildren(string repositoryId, string typeId, bool? includePropertyDefinitions, + BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension); + + IList<ITypeDefinitionContainer> GetTypeDescendants(string repositoryId, string typeId, BigInteger? depth, + bool? includePropertyDefinitions, IExtensionsData extension); + + ITypeDefinition GetTypeDefinition(string repositoryId, string typeId, IExtensionsData extension); + + ITypeDefinition CreateType(string repositoryId, ITypeDefinition type, IExtensionsData extension); + + ITypeDefinition UpdateType(string repositoryId, ITypeDefinition type, IExtensionsData extension); + + void DeleteType(string repositoryId, string typeId, IExtensionsData extension); + } + + public interface INavigationService + { + IObjectInFolderList GetChildren(string repositoryId, string folderId, string filter, string orderBy, + bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter, + bool? includePathSegment, BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension); + + IList<IObjectInFolderContainer> GetDescendants(string repositoryId, string folderId, BigInteger? depth, string filter, + bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter, + bool? includePathSegment, IExtensionsData extension); + + IList<IObjectInFolderContainer> GetFolderTree(string repositoryId, string folderId, BigInteger? depth, string filter, + bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter, + bool? includePathSegment, IExtensionsData extension); + + 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); + + IObjectList GetCheckedOutDocs(string repositoryId, string folderId, string filter, string orderBy, + bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter, + BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension); + } + + public interface IObjectService + { + string CreateDocument(string repositoryId, IProperties properties, string folderId, IContentStream contentStream, + VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension); + + string CreateDocumentFromSource(string repositoryId, string sourceId, IProperties properties, string folderId, + VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension); + + string CreateFolder(string repositoryId, IProperties properties, string folderId, IList<string> policies, + IAcl addAces, IAcl removeAces, IExtensionsData extension); + + string CreateRelationship(string repositoryId, IProperties properties, IList<string> policies, IAcl addAces, + IAcl removeAces, IExtensionsData extension); + + string CreatePolicy(string repositoryId, IProperties properties, string folderId, IList<string> policies, + IAcl addAces, IAcl removeAces, IExtensionsData extension); + + string CreateItem(string repositoryId, IProperties properties, string folderId, IList<string> policies, + IAcl addAces, IAcl removeAces, IExtensionsData extension); + + IAllowableActions GetAllowableActions(string repositoryId, string objectId, IExtensionsData extension); + + IProperties GetProperties(string repositoryId, string objectId, string filter, IExtensionsData extension); + + IList<IRenditionData> GetRenditions(string repositoryId, string objectId, string renditionFilter, + BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension); + + IObjectData GetObject(string repositoryId, string objectId, string filter, bool? includeAllowableActions, + IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds, + bool? includeAcl, IExtensionsData extension); + + IObjectData GetObjectByPath(string repositoryId, string path, string filter, bool? includeAllowableActions, + IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds, bool? includeAcl, + IExtensionsData extension); + + IContentStream GetContentStream(string repositoryId, string objectId, string streamId, BigInteger? offset, BigInteger? length, + IExtensionsData extension); + + void UpdateProperties(string repositoryId, ref string objectId, ref string changeToken, IProperties properties, + IExtensionsData extension); + + IList<IBulkUpdateObjectIdAndChangeToken> BulkUpdateProperties(string repositoryId, + IList<IBulkUpdateObjectIdAndChangeToken> objectIdAndChangeToken, IProperties properties, + IList<string> addSecondaryTypeIds, IList<string> removeSecondaryTypeIds, IExtensionsData extension); + + void MoveObject(string repositoryId, ref string objectId, string targetFolderId, string sourceFolderId, + IExtensionsData extension); + + void DeleteObject(string repositoryId, string objectId, bool? allVersions, IExtensionsData extension); + + IFailedToDeleteData DeleteTree(string repositoryId, string folderId, bool? allVersions, UnfileObject? unfileObjects, + bool? continueOnFailure, ExtensionsData extension); + + void SetContentStream(string repositoryId, ref string objectId, bool? overwriteFlag, ref string changeToken, + IContentStream contentStream, IExtensionsData extension); + + void DeleteContentStream(string repositoryId, ref string objectId, ref string changeToken, IExtensionsData extension); + + void AppendContentStream(string repositoryId, ref string objectId, bool? isLastChunk, ref string changeToken, + IContentStream contentStream, IExtensionsData extension); + } + + public interface IVersioningService + { + void CheckOut(string repositoryId, ref string objectId, IExtensionsData extension, out bool? contentCopied); + + void CancelCheckOut(string repositoryId, string objectId, IExtensionsData extension); + + void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties, + IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces, + IExtensionsData extension); + + IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major, + string filter, bool? includeAllowableActions, IncludeRelationships? includeRelationships, + string renditionFilter, bool? includePolicyIds, bool? includeAcl, IExtensionsData extension); + + IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major, + string filter, IExtensionsData extension); + + IList<IObjectData> GetAllVersions(string repositoryId, string objectId, string versionSeriesId, string filter, + bool? includeAllowableActions, IExtensionsData extension); + } + + public interface IRelationshipService + { + IObjectList GetObjectRelationships(string repositoryId, string objectId, bool? includeSubRelationshipTypes, + RelationshipDirection? relationshipDirection, string typeId, string filter, bool? includeAllowableActions, + BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension); + } + + public interface IDiscoveryService + { + IObjectList Query(string repositoryId, string statement, bool? searchAllVersions, + bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter, + BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension); + + IObjectList GetContentChanges(string repositoryId, ref string changeLogToken, bool? includeProperties, + string filter, bool? includePolicyIds, bool? includeAcl, BigInteger? maxItems, IExtensionsData extension); + } + + public interface IMultiFilingService + { + void AddObjectToFolder(string repositoryId, string objectId, string folderId, bool? allVersions, IExtensionsData extension); + + void RemoveObjectFromFolder(string repositoryId, string objectId, string folderId, IExtensionsData extension); + } + + public interface IAclService + { + IAcl GetAcl(string repositoryId, string objectId, bool? onlyBasicPermissions, IExtensionsData extension); + + IAcl ApplyAcl(string repositoryId, string objectId, IAcl addAces, IAcl removeAces, AclPropagation? aclPropagation, + IExtensionsData extension); + } + + public interface IPolicyService + { + void ApplyPolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension); + + void RemovePolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension); + + IList<IObjectData> GetAppliedPolicies(string repositoryId, string objectId, string filter, IExtensionsData extension); + } +} Added: chemistry/portcmis/PortCMIS/binding/Url.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/Url.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/Url.cs (added) +++ chemistry/portcmis/PortCMIS/binding/Url.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,211 @@ +/* +* 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.Enums; +using System; +using System.Globalization; +using System.Numerics; +using System.Text; + +namespace PortCMIS.Binding +{ + public class UrlBuilder + { + private UriBuilder uri; + + public Uri Url + { + get { return uri.Uri; } + } + + public UrlBuilder(string url) + { + if (url == null) + { + throw new ArgumentNullException("url"); + } + + uri = new UriBuilder(url); + } + + public UrlBuilder AddParameter(string name, object value) + { + if (name == null || value == null) + { + return this; + } + + string valueStr = Uri.EscapeDataString(UrlBuilder.NormalizeParameter(value)); + + if (uri.Query != null && uri.Query.Length > 1) + { + uri.Query = uri.Query.Substring(1) + "&" + name + "=" + valueStr; + } + else + { + uri.Query = name + "=" + valueStr; + } + + return this; + } + + public UrlBuilder AddPath(string path) + { + return AddPathPart(path, false); + } + + protected UrlBuilder AddPathPart(string part, bool quoteSlash) + { + if (String.IsNullOrEmpty(part)) + { + return this; + } + if (uri.Path.Length == 0 || uri.Path[uri.Path.Length - 1] != '/') + { + uri.Path += "/"; + } + if (part[0] == '/') + { + part = part.Substring(1); + } + uri.Path += QuoteURIPathComponent(part, quoteSlash); + + return this; + } + + + private static readonly char[] RFC7232Reserved = ";?:@&=+$,[]".ToCharArray(); + + public string QuoteURIPathComponent(string s, bool quoteSlash) + { + if (String.IsNullOrEmpty(s)) + { + return s; + } + + StringBuilder result = new StringBuilder(s); + + foreach (char c in RFC7232Reserved) + { + result.Replace(c.ToString(), "%" + Convert.ToByte(c).ToString("X")); + } + + if (quoteSlash) + { + result.Replace("/", "%2F"); + } + + return result.ToString(); + } + + public static string NormalizeParameter(object value) + { + if (value == null) + { + return null; + } + else if (value is Enum) + { + return ((Enum)value).GetCmisValue(); + } + else if (value is bool) + { + return (bool)value ? "true" : "false"; + } + else if (value is BigInteger) + { + return ((BigInteger)value).ToString("#", CultureInfo.InvariantCulture); + } + + return value.ToString(); + } + + public override string ToString() + { + return Url.ToString(); + } + } + + internal class MimeHelper + { + public const string ContentDisposition = "Content-Disposition"; + public const string DispositionAttachment = "attachment"; + public const string DispositionFilename = "filename"; + + private const string MIMESpecials = "()<>@,;:\\\"/[]?=" + "\t "; + private const string RFC2231Specials = "*'%" + MIMESpecials; + private static char[] HexDigits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + public static string EncodeContentDisposition(string disposition, string filename) + { + if (disposition == null) + { + disposition = DispositionAttachment; + } + return disposition + EncodeRFC2231(DispositionFilename, filename); + } + + protected static string EncodeRFC2231(string key, string value) + { + StringBuilder buf = new StringBuilder(); + bool encoded = EncodeRFC2231value(value, buf); + if (encoded) + { + return "; " + key + "*=" + buf.ToString(); + } + else + { + return "; " + key + "=" + value; + } + } + + protected static bool EncodeRFC2231value(string value, StringBuilder buf) + { + buf.Append("UTF-8"); + buf.Append("''"); // no language + byte[] bytes; + try + { + bytes = UTF8Encoding.UTF8.GetBytes(value); + } + catch (Exception) + { + return true; + } + + bool encoded = false; + for (int i = 0; i < bytes.Length; i++) + { + int ch = bytes[i] & 0xff; + if (ch <= 32 || ch >= 127 || RFC2231Specials.IndexOf((char)ch) != -1) + { + buf.Append('%'); + buf.Append(HexDigits[ch >> 4]); + buf.Append(HexDigits[ch & 0xf]); + encoded = true; + } + else + { + buf.Append((char)ch); + } + } + return encoded; + } + } +} Added: chemistry/portcmis/PortCMIS/binding/atompub/XmlConstants.cs URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/atompub/XmlConstants.cs?rev=1691890&view=auto ============================================================================== --- chemistry/portcmis/PortCMIS/binding/atompub/XmlConstants.cs (added) +++ chemistry/portcmis/PortCMIS/binding/atompub/XmlConstants.cs Mon Jul 20 08:48:57 2015 @@ -0,0 +1,259 @@ +/* +* 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 System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PortCMIS.Binding.AtomPub +{ + class XmlConstants + { + // namespaces + public const string NAMESPACE_CMIS = "http://docs.oasis-open.org/ns/cmis/core/200908/"; + public const string NAMESPACE_ATOM = "http://www.w3.org/2005/Atom"; + public const string NAMESPACE_APP = "http://www.w3.org/2007/app"; + public const string NAMESPACE_RESTATOM = "http://docs.oasis-open.org/ns/cmis/restatom/200908/"; + public const string NAMESPACE_XSI = "http://www.w3.org/2001/XMLSchema-instance"; + public const string NAMESPACE_APACHE_CHEMISTRY = "http://chemistry.apache.org/"; + + // prefixes + public const string PREFIX_XSI = "xsi"; + public const string PREFIX_ATOM = "atom"; + public const string PREFIX_APP = "app"; + public const string PREFIX_CMIS = "cmis"; + public const string PREFIX_RESTATOM = "cmisra"; + public const string PREFIX_APACHE_CHEMISTY = "chemistry"; + + // tags + public const string TAG_REPOSITORY_INFO = "repositoryInfo"; + + public const string TAG_REPINFO_ID = "repositoryId"; + public const string TAG_REPINFO_NAME = "repositoryName"; + public const string TAG_REPINFO_DESCRIPTION = "repositoryDescription"; + public const string TAG_REPINFO_VENDOR = "vendorName"; + public const string TAG_REPINFO_PRODUCT = "productName"; + public const string TAG_REPINFO_PRODUCT_VERSION = "productVersion"; + public const string TAG_REPINFO_ROOT_FOLDER_ID = "rootFolderId"; + public const string TAG_REPINFO_CAPABILITIES = "capabilities"; + public const string TAG_REPINFO_ACL_CAPABILITIES = "aclCapability"; + public const string TAG_REPINFO_CHANGE_LOG_TOKEN = "latestChangeLogToken"; + public const string TAG_REPINFO_CMIS_VERSION_SUPPORTED = "cmisVersionSupported"; + public const string TAG_REPINFO_THIN_CLIENT_URI = "thinClientURI"; + public const string TAG_REPINFO_CHANGES_INCOMPLETE = "changesIncomplete"; + public const string TAG_REPINFO_CHANGES_ON_TYPE = "changesOnType"; + public const string TAG_REPINFO_PRINCIPAL_ID_ANONYMOUS = "principalAnonymous"; + public const string TAG_REPINFO_PRINCIPAL_ID_ANYONE = "principalAnyone"; + public const string TAG_REPINFO_EXTENDED_FEATURES = "extendedFeatures"; + + public const string TAG_CAP_CONTENT_STREAM_UPDATABILITY = "capabilityContentStreamUpdatability"; + public const string TAG_CAP_CHANGES = "capabilityChanges"; + public const string TAG_CAP_RENDITIONS = "capabilityRenditions"; + public const string TAG_CAP_GET_DESCENDANTS = "capabilityGetDescendants"; + public const string TAG_CAP_GET_FOLDER_TREE = "capabilityGetFolderTree"; + public const string TAG_CAP_MULTIFILING = "capabilityMultifiling"; + public const string TAG_CAP_UNFILING = "capabilityUnfiling"; + public const string TAG_CAP_VERSION_SPECIFIC_FILING = "capabilityVersionSpecificFiling"; + public const string TAG_CAP_PWC_SEARCHABLE = "capabilityPWCSearchable"; + public const string TAG_CAP_PWC_UPDATABLE = "capabilityPWCUpdatable"; + public const string TAG_CAP_ALL_VERSIONS_SEARCHABLE = "capabilityAllVersionsSearchable"; + public const string TAG_CAP_ORDER_BY = "capabilityOrderBy"; + public const string TAG_CAP_QUERY = "capabilityQuery"; + public const string TAG_CAP_JOIN = "capabilityJoin"; + public const string TAG_CAP_ACL = "capabilityACL"; + public const string TAG_CAP_CREATABLE_PROPERTY_TYPES = "capabilityCreatablePropertyTypes"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES = "capabilityNewTypeSettableAttributes"; + + public const string TAG_CAP_CREATABLE_PROPERTY_TYPES_CANCREATE = "canCreate"; + + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_ID = "id"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_LOCALNAME = "localName"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_LOCALNAMESPACE = "localNamespace"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_DISPLAYNAME = "displayName"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_QUERYNAME = "queryName"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_DESCRIPTION = "description"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CREATEABLE = "creatable"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_FILEABLE = "fileable"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_QUERYABLE = "queryable"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_FULLTEXTINDEXED = "fulltextIndexed"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_INCLUDEDINSUPERTYTPEQUERY = "includedInSupertypeQuery"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CONTROLABLEPOLICY = "controllablePolicy"; + public const string TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CONTROLABLEACL = "controllableACL"; + + public const string TAG_ACLCAP_SUPPORTED_PERMISSIONS = "supportedPermissions"; + public const string TAG_ACLCAP_ACL_PROPAGATION = "propagation"; + public const string TAG_ACLCAP_PERMISSIONS = "permissions"; + public const string TAG_ACLCAP_PERMISSION_MAPPING = "mapping"; + + public const string TAG_ACLCAP_PERMISSION_PERMISSION = "permission"; + public const string TAG_ACLCAP_PERMISSION_DESCRIPTION = "description"; + + public const string TAG_ACLCAP_MAPPING_KEY = "key"; + public const string TAG_ACLCAP_MAPPING_PERMISSION = "permission"; + + public const string TAG_FEATURE_ID = "id"; + public const string TAG_FEATURE_URL = "url"; + public const string TAG_FEATURE_COMMON_NAME = "commonName"; + public const string TAG_FEATURE_VERSION_LABEL = "versionLabel"; + public const string TAG_FEATURE_DESCRIPTION = "description"; + public const string TAG_FEATURE_DATA = "featureData"; + + public const string TAG_FEATURE_DATA_KEY = "key"; + public const string TAG_FEATURE_DATA_VALUE = "value"; + + public const string TAG_OBJECT = "object"; + + public const string TAG_OBJECT_PROPERTIES = "properties"; + public const string TAG_OBJECT_ALLOWABLE_ACTIONS = "allowableActions"; + public const string TAG_OBJECT_RELATIONSHIP = "relationship"; + public const string TAG_OBJECT_CHANGE_EVENT_INFO = "changeEventInfo"; + public const string TAG_OBJECT_ACL = "acl"; + public const string TAG_OBJECT_EXACT_ACL = "exactACL"; + public const string TAG_OBJECT_POLICY_IDS = "policyIds"; + public const string TAG_OBJECT_RENDITION = "rendition"; + + public const string TAG_PROP_BOOLEAN = "propertyBoolean"; + public const string TAG_PROP_ID = "propertyId"; + public const string TAG_PROP_INTEGER = "propertyInteger"; + public const string TAG_PROP_DATETIME = "propertyDateTime"; + public const string TAG_PROP_DECIMAL = "propertyDecimal"; + public const string TAG_PROP_HTML = "propertyHtml"; + public const string TAG_PROP_STRING = "propertyString"; + public const string TAG_PROP_URI = "propertyUri"; + + public const string TAG_CHANGE_EVENT_TYPE = "changeType"; + public const string TAG_CHANGE_EVENT_TIME = "changeTime"; + + public const string TAG_ACL_PERMISSISONS = "permission"; + public const string TAG_ACL_IS_EXACT = "permission"; + public const string TAG_ACE_PRINCIPAL = "principal"; + public const string TAG_ACE_PRINCIPAL_ID = "principalId"; + public const string TAG_ACE_PERMISSIONS = "permission"; + public const string TAG_ACE_IS_DIRECT = "direct"; + + public const string TAG_POLICY_ID = "id"; + + public const string TAG_RENDITION_STREAM_ID = "streamId"; + public const string TAG_RENDITION_MIMETYPE = "mimetype"; + public const string TAG_RENDITION_LENGTH = "length"; + public const string TAG_RENDITION_KIND = "kind"; + public const string TAG_RENDITION_TITLE = "title"; + public const string TAG_RENDITION_HEIGHT = "height"; + public const string TAG_RENDITION_WIDTH = "width"; + public const string TAG_RENDITION_DOCUMENT_ID = "renditionDocumentId"; + + public const string ATTR_PROPERTY_ID = "propertyDefinitionId"; + public const string ATTR_PROPERTY_LOCALNAME = "localName"; + public const string ATTR_PROPERTY_DISPLAYNAME = "displayName"; + public const string ATTR_PROPERTY_QUERYNAME = "queryName"; + public const string TAG_PROPERTY_VALUE = "value"; + + public const string TAG_TYPE = "type"; + + public const string ATTR_DOCUMENT_TYPE = "cmisTypeDocumentDefinitionType"; + public const string ATTR_FOLDER_TYPE = "cmisTypeFolderDefinitionType"; + public const string ATTR_RELATIONSHIP_TYPE = "cmisTypeRelationshipDefinitionType"; + public const string ATTR_POLICY_TYPE = "cmisTypePolicyDefinitionType"; + public const string ATTR_ITEM_TYPE = "cmisTypeItemDefinitionType"; + public const string ATTR_SECONDARY_TYPE = "cmisTypeSecondaryDefinitionType"; + + public const string TAG_TYPE_ID = "id"; + public const string TAG_TYPE_LOCALNAME = "localName"; + public const string TAG_TYPE_LOCALNAMESPACE = "localNamespace"; + public const string TAG_TYPE_DISPLAYNAME = "displayName"; + public const string TAG_TYPE_QUERYNAME = "queryName"; + public const string TAG_TYPE_DESCRIPTION = "description"; + public const string TAG_TYPE_BASE_ID = "baseId"; + public const string TAG_TYPE_PARENT_ID = "parentId"; + public const string TAG_TYPE_CREATABLE = "creatable"; + public const string TAG_TYPE_FILEABLE = "fileable"; + public const string TAG_TYPE_QUERYABLE = "queryable"; + public const string TAG_TYPE_FULLTEXT_INDEXED = "fulltextIndexed"; + public const string TAG_TYPE_INCLUDE_IN_SUPERTYPE_QUERY = "includedInSupertypeQuery"; + public const string TAG_TYPE_CONTROLABLE_POLICY = "controllablePolicy"; + public const string TAG_TYPE_CONTROLABLE_ACL = "controllableACL"; + public const string TAG_TYPE_TYPE_MUTABILITY = "typeMutability"; + public const string TAG_TYPE_VERSIONABLE = "versionable"; // document + public const string TAG_TYPE_CONTENTSTREAM_ALLOWED = "contentStreamAllowed"; // document + public const string TAG_TYPE_ALLOWED_SOURCE_TYPES = "allowedSourceTypes"; // relationship + public const string TAG_TYPE_ALLOWED_TARGET_TYPES = "allowedTargetTypes"; // relationship + + public const string TAG_TYPE_PROP_DEF_BOOLEAN = "propertyBooleanDefinition"; + public const string TAG_TYPE_PROP_DEF_DATETIME = "propertyDateTimeDefinition"; + public const string TAG_TYPE_PROP_DEF_DECIMAL = "propertyDecimalDefinition"; + public const string TAG_TYPE_PROP_DEF_ID = "propertyIdDefinition"; + public const string TAG_TYPE_PROP_DEF_INTEGER = "propertyIntegerDefinition"; + public const string TAG_TYPE_PROP_DEF_HTML = "propertyHtmlDefinition"; + public const string TAG_TYPE_PROP_DEF_STRING = "propertyStringDefinition"; + public const string TAG_TYPE_PROP_DEF_URI = "propertyUriDefinition"; + + public const string TAG_PROPERTY_TYPE_ID = "id"; + public const string TAG_PROPERTY_TYPE_LOCALNAME = "localName"; + public const string TAG_PROPERTY_TYPE_LOCALNAMESPACE = "localNamespace"; + public const string TAG_PROPERTY_TYPE_DISPLAYNAME = "displayName"; + public const string TAG_PROPERTY_TYPE_QUERYNAME = "queryName"; + public const string TAG_PROPERTY_TYPE_DESCRIPTION = "description"; + public const string TAG_PROPERTY_TYPE_PROPERTY_TYPE = "propertyType"; + public const string TAG_PROPERTY_TYPE_CARDINALITY = "cardinality"; + public const string TAG_PROPERTY_TYPE_UPDATABILITY = "updatability"; + public const string TAG_PROPERTY_TYPE_INHERITED = "inherited"; + public const string TAG_PROPERTY_TYPE_REQUIRED = "required"; + public const string TAG_PROPERTY_TYPE_QUERYABLE = "queryable"; + public const string TAG_PROPERTY_TYPE_ORDERABLE = "orderable"; + public const string TAG_PROPERTY_TYPE_OPENCHOICE = "openChoice"; + + public const string TAG_PROPERTY_TYPE_DEAULT_VALUE = "defaultValue"; + + public const string TAG_PROPERTY_TYPE_MAX_LENGTH = "maxLength"; + public const string TAG_PROPERTY_TYPE_MIN_VALUE = "minValue"; + public const string TAG_PROPERTY_TYPE_MAX_VALUE = "maxValue"; + public const string TAG_PROPERTY_TYPE_PRECISION = "precision"; + public const string TAG_PROPERTY_TYPE_RESOLUTION = "resolution"; + + public const string TAG_PROPERTY_TYPE_CHOICE = "choice"; + public const string ATTR_PROPERTY_TYPE_CHOICE_DISPLAYNAME = "displayName"; + public const string TAG_PROPERTY_TYPE_CHOICE_VALUE = "value"; + public const string TAG_PROPERTY_TYPE_CHOICE_CHOICE = "choice"; + + public const string TAG_TYPE_TYPE_MUTABILITY_CREATE = "create"; + public const string TAG_TYPE_TYPE_MUTABILITY_UPDATE = "update"; + public const string TAG_TYPE_TYPE_MUTABILITY_DELETE = "delete"; + + public const string TAG_QUERY = "query"; + public const string TAG_QUERY_STATEMENT = "statement"; + public const string TAG_QUERY_SEARCHALLVERSIONS = "searchAllVersions"; + public const string TAG_QUERY_INCLUDEALLOWABLEACTIONS = "includeAllowableActions"; + public const string TAG_QUERY_INCLUDERELATIONSHIPS = "includeRelationships"; + public const string TAG_QUERY_RENDITIONFILTER = "renditionFilter"; + public const string TAG_QUERY_MAXITEMS = "maxItems"; + public const string TAG_QUERY_SKIPCOUNT = "skipCount"; + + public const string TAG_BULK_UPDATE = "bulkUpdate"; + public const string TAG_BULK_UPDATE_ID_AND_TOKEN = "objectIdAndChangeToken"; + public const string TAG_BULK_UPDATE_PROPERTIES = "properties"; + public const string TAG_BULK_UPDATE_ADD_SECONDARY_TYPES = "addSecondaryTypeIds"; + public const string TAG_BULK_UPDATE_REMOVE_SECONDARY_TYPES = "removeSecondaryTypeIds"; + + public const string TAG_IDANDTOKEN_ID = "id"; + public const string TAG_IDANDTOKEN_NEWID = "newId"; + public const string TAG_IDANDTOKEN_CHANGETOKEN = "changeToken"; + } +}
