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 [14/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/PortCMISWin/binding/WindowsHttp.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMISWin/binding/WindowsHttp.cs?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/PortCMISWin/binding/WindowsHttp.cs (added)
+++ chemistry/portcmis/PortCMISWin/binding/WindowsHttp.cs Mon Jul 20 08:48:57 2015
@@ -0,0 +1,391 @@
+/*
+* 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.Runtime.InteropServices.WindowsRuntime;
+using System.Threading;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.Storage.Streams;
+using Windows.Web.Http;
+using Windows.Web.Http.Filters;
+using Windows.Web.Http.Headers;
+
+
+namespace PortCMIS.Binding.Http
+{
+    public class WindowsHttpInvoker : 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, System.Net.Http.HttpContent content, IBindingSession session)
+        {
+            return Invoke(url, HttpMethod.Post, content, session, null, null, null);
+        }
+
+        public IResponse InvokePUT(UrlBuilder url, IDictionary<string, string> headers, System.Net.Http.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, System.Net.Http.HttpContent content, IBindingSession session,
+                long? offset, long? length, IDictionary<string, string> headers)
+        {
+            if (Logger.IsDebugEnabled)
+            {
+                Logger.Debug("HTTP: " + method.ToString() + " " + url.ToString());
+            }
+
+            IWindowsAuthenticationProvider authProvider = session.GetAuthenticationProvider() as IWindowsAuthenticationProvider;
+
+            HttpClient httpClient = session.GetValue(InvokerHttpClient) as HttpClient;
+
+            if (httpClient == null)
+            {
+                lock (invokerLock)
+                {
+                    httpClient = session.GetValue(InvokerHttpClient) as HttpClient;
+                    if (httpClient == null)
+                    {
+                        HttpBaseProtocolFilter httpClientFilter = new HttpBaseProtocolFilter();
+
+                        // redirects
+                        httpClientFilter.AllowAutoRedirect = false;
+
+                        // compression
+                        string compressionFlag = session.GetValue(SessionParameter.Compression) as string;
+                        if (compressionFlag != null && compressionFlag.ToLowerInvariant().Equals("true"))
+                        {
+                            httpClientFilter.AutomaticDecompression = true;
+                        }
+
+                        // authentictaion
+                        httpClientFilter.AllowUI = false;
+
+                        // authentication provider
+                        if (authProvider != null)
+                        {
+                            authProvider.PrepareHttpClientFilter(httpClientFilter);
+                        }
+
+                        // create HttpClient
+                        httpClient = new HttpClient(httpClientFilter);
+
+                        session.PutValue(InvokerHttpClient, httpClient);
+                    }
+                }
+            }
+
+            HttpRequestMessage request = new HttpRequestMessage(method, new Uri(url.ToString()));
+
+            // set additional headers
+            request.Headers.UserAgent.Add(new HttpProductInfoHeaderValue("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.Add(new KeyValuePair<string, string>("Range", "bytes=" + longOffset + "-" + (longOffset + length.Value - 1)));
+                }
+                else
+                {
+                    request.Headers.Add(new KeyValuePair<string, string>("Range", "bytes=" + longOffset + "-"));
+                }
+            }
+            else if (offset != null && offset.Value > 0)
+            {
+                request.Headers.Add(new KeyValuePair<string, string>("Range", "bytes=" + offset.Value + "-"));
+            }
+
+            // content
+            if (content != null)
+            {
+                request.Content = new ConvertedHttpContent(content);
+
+                if (request.Content.Headers.ContentLength == null)
+                {
+                    request.Headers.TransferEncoding.TryParseAdd("chunked");
+                }
+            }
+
+            // authentication provider
+            if (authProvider != null)
+            {
+                authProvider.PrepareHttpRequestMessage(request);
+            }
+
+            // timeouts
+            int timeout = session.GetValue(SessionParameter.ConnectTimeout, -2);
+
+            WindowsResponse response;
+            try
+            {
+                Task<HttpResponseMessage> task = Send(httpClient, request, timeout);
+                if (task.IsFaulted)
+                {
+                    throw task.Exception;
+                }
+                else
+                {
+                    HttpResponseMessage httpResponseMessage = task.Result;
+
+                    if (authProvider != null)
+                    {
+                        authProvider.HandleResponse(httpResponseMessage);
+                    }
+                    response = new WindowsResponse(httpResponseMessage);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new CmisConnectionException("Cannot access " + url + ": " + e.Message, e);
+            }
+
+            return response;
+        }
+
+        private async Task<HttpResponseMessage> Send(HttpClient httpClient, HttpRequestMessage request, int timeout)
+        {
+            if (timeout > 0)
+            {
+                CancellationTokenSource cts = new CancellationTokenSource();
+                cts.CancelAfter(TimeSpan.FromMilliseconds(timeout));
+                return await httpClient.SendRequestAsync(request, HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token).ConfigureAwait(false);
+            }
+            else
+            {
+                return await httpClient.SendRequestAsync(request, HttpCompletionOption.ResponseHeadersRead).AsTask().ConfigureAwait(false);
+            }
+        }
+    }
+
+    class ConvertedHttpContent : IHttpContent
+    {
+        private System.Net.Http.HttpContent content;
+
+        public ConvertedHttpContent(System.Net.Http.HttpContent httpContent)
+        {
+            content = httpContent;
+            Headers = new HttpContentHeaderCollection();
+
+            foreach (KeyValuePair<string, IEnumerable<string>> header in httpContent.Headers)
+            {
+                Headers.Add(header.Key, header.Value.First());
+            }
+        }
+
+        public HttpContentHeaderCollection Headers { get; set; }
+
+        public IAsyncOperationWithProgress<ulong, ulong> BufferAllAsync()
+        {
+            return AsyncInfo.Run<ulong, ulong>(async (token, progress) =>
+            {
+                await content.LoadIntoBufferAsync();
+                return 0;
+            });
+        }
+
+        public IAsyncOperationWithProgress<IBuffer, ulong> ReadAsBufferAsync()
+        {
+            return AsyncInfo.Run<IBuffer, ulong>(async (token, progress) =>
+            {
+                return (await content.ReadAsByteArrayAsync()).AsBuffer();
+            });
+        }
+
+        public IAsyncOperationWithProgress<IInputStream, ulong> ReadAsInputStreamAsync()
+        {
+            return AsyncInfo.Run<IInputStream, ulong>(async (token, progress) =>
+            {
+                return (await content.ReadAsStreamAsync()).AsInputStream();
+            });
+        }
+
+        public IAsyncOperationWithProgress<string, ulong> ReadAsStringAsync()
+        {
+            return AsyncInfo.Run<string, ulong>((token, progress) =>
+            {
+                return content.ReadAsStringAsync();
+            });
+        }
+
+        public bool TryComputeLength(out ulong length)
+        {
+            length = 0;
+            return false;
+        }
+
+        public IAsyncOperationWithProgress<ulong, ulong> WriteToStreamAsync(IOutputStream outputStream)
+        {
+            return AsyncInfo.Run<ulong, ulong>(async (token, progress) =>
+            {
+                Stream stream = outputStream.AsStreamForWrite();
+                await content.CopyToAsync(stream);
+                stream.Flush();
+
+                return 0;
+            });
+        }
+
+        public void Dispose()
+        {
+        }
+    }
+
+
+    class WindowsResponse : 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 WindowsResponse(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 = (long?)httpResponse.Content.Headers.ContentLength;
+
+                if (httpResponse.Content.Headers.ContentDisposition != null)
+                {
+                    Filename = httpResponse.Content.Headers.ContentDisposition.FileName;
+                }
+
+                string contentTransferEncoding;
+                if (httpResponse.Content.Headers.TryGetValue("Content-Transfer-Encoding", out contentTransferEncoding))
+                {
+                    isBase64 = contentTransferEncoding == "base64";
+                }
+            }
+
+            if (httpResponse.StatusCode == HttpStatusCode.Ok ||
+                httpResponse.StatusCode == HttpStatusCode.Created ||
+                httpResponse.StatusCode == HttpStatusCode.NonAuthoritativeInformation ||
+                httpResponse.StatusCode == HttpStatusCode.PartialContent)
+            {
+                Stream = GetContentStream().Result.AsStreamForRead();
+
+                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<IInputStream> GetContentStream()
+        {
+            return await response.Content.ReadAsInputStreamAsync().AsTask().ConfigureAwait(false);
+        }
+
+        async private Task<String> GetContentString()
+        {
+            return await response.Content.ReadAsStringAsync().AsTask().ConfigureAwait(false);
+        }
+    }
+}

Added: chemistry/portcmis/PortCMISWin/build.bat
URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMISWin/build.bat?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/PortCMISWin/build.bat (added)
+++ chemistry/portcmis/PortCMISWin/build.bat Mon Jul 20 08:48:57 2015
@@ -0,0 +1,34 @@
+@echo off
+
+rem
+rem Licensed to the Apache Software Foundation (ASF) under one
+rem or more contributor license agreements. See the NOTICE file
+rem distributed with this work for additional information
+rem regarding copyright ownership. The ASF licenses this file
+rem to you under the Apache License, Version 2.0 (the
+rem "License"); you may not use this file except in compliance
+rem with the License. You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing,
+rem software distributed under the License is distributed on an
+rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem KIND, either express or implied. See the License for the
+rem specific language governing permissions and limitations
+rem under the License.
+
+echo Removing old DLLs
+rmdir /Q /S bin
+rmdir /Q /S obj
+
+echo Building Debug DLL...
+msbuild PortCMISWin.csproj /ToolsVersion:4.0 /p:Configuration=Debug
+
+echo Building Release DLL...
+msbuild PortCMISWin.csproj /ToolsVersion:4.0 /p:Configuration=Release
+
+nuget pack
+
+rem echo Building documentation...
+rem msbuild PortCMISWin.shfbproj /ToolsVersion:4.0 /p:Configuration=Release
\ No newline at end of file

Added: chemistry/portcmis/PortCMISWin/client/ClientImpl.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMISWin/client/ClientImpl.cs?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/PortCMISWin/client/ClientImpl.cs (added)
+++ chemistry/portcmis/PortCMISWin/client/ClientImpl.cs Mon Jul 20 08:48:57 2015
@@ -0,0 +1,89 @@
+/*
+* 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 System.Collections.Generic;
+
+namespace PortCMIS.Client.Impl
+{
+    /// <summary>
+    /// Session factory implementation for Store Apps.
+    /// </summary>
+    public class WindowsSessionFactory : ISessionFactory
+    {
+        protected SessionFactory DefaultSessionFactory { get; private set; }
+
+        private WindowsSessionFactory()
+        {
+            DefaultSessionFactory = SessionFactory.NewInstance();
+        }
+
+        public static WindowsSessionFactory NewInstance()
+        {
+            return new WindowsSessionFactory();
+        }
+
+        public ISession CreateSession(IDictionary<string, string> parameters)
+        {
+            return DefaultSessionFactory.CreateSession(AddWindowClasses(parameters));
+        }
+
+        public ISession CreateSession(IDictionary<string, string> parameters, IObjectFactory objectFactory, IAuthenticationProvider authenticationProvider, ICache cache)
+        {
+            return DefaultSessionFactory.CreateSession(AddWindowClasses(parameters), objectFactory, authenticationProvider, cache);
+        }
+
+        public IList<IRepository> GetRepositories(IDictionary<string, string> parameters)
+        {
+            return DefaultSessionFactory.GetRepositories(AddWindowClasses(parameters));
+        }
+
+        public IList<IRepository> GetRepositories(IDictionary<string, string> parameters, IObjectFactory objectFactory, IAuthenticationProvider authenticationProvider, ICache cache)
+        {
+            return DefaultSessionFactory.GetRepositories(AddWindowClasses(parameters), objectFactory, authenticationProvider, cache);
+        }
+
+        protected IDictionary<string, string> AddWindowClasses(IDictionary<string, string> parameters)
+        {
+            if (parameters == null)
+            {
+                return parameters;
+            }
+
+            if (parameters.ContainsKey(SessionParameter.HttpInvokerClass) && parameters.ContainsKey(SessionParameter.AuthenticationProviderClass))
+            {
+                return parameters;
+            }
+
+            IDictionary<string, string> newParameters = new Dictionary<string, string>(parameters);
+
+            if (!newParameters.ContainsKey(SessionParameter.HttpInvokerClass))
+            {
+                newParameters.Add(SessionParameter.HttpInvokerClass, typeof(PortCMIS.Binding.Http.WindowsHttpInvoker).AssemblyQualifiedName);
+            }
+
+            if (!newParameters.ContainsKey(SessionParameter.AuthenticationProviderClass))
+            {
+                newParameters.Add(SessionParameter.AuthenticationProviderClass, typeof(PortCMIS.Binding.StandardWindowsAuthenticationProvider).AssemblyQualifiedName);
+            }
+
+            return newParameters;
+        }
+    }
+}

Added: chemistry/portcmis/README
URL: http://svn.apache.org/viewvc/chemistry/portcmis/README?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/README (added)
+++ chemistry/portcmis/README Mon Jul 20 08:48:57 2015
@@ -0,0 +1,29 @@
+Apache Chemistry PortCMIS 0.1
+=============================
+
+Apache Chemistry PortCMIS is a Content Management Interoperability Services (CMIS)
+client library for the .NET framework 4.5 or higher.
+
+See http://chemistry.apache.org/dotnet/portcmis.html for more information.
+
+This release is a bug fix release.
+If you find a problem, please let us know: https://issues.apache.org/jira/browse/CMIS
+
+
+Change log 
+----------
+
+PortCMIS 0.1:
+
+Initial relase
+
+  
+Strong-Name signing
+-------------------
+
+The DLL included in this release is signed with a public/private key pair that is also 
+included in this package. This allows you to deploy it to the global assembly cache (GAC) 
+and to make changes to the PortCMIS source code without recompiling your application.
+However, since the private key is publicly available, this strong name cannot be trusted.
+If a trust relationship between your application and the PortCMIS DLL is important to you, 
+you have to rebuild the DLL from the source code and sign it yourself.

Added: chemistry/portcmis/release.bat
URL: http://svn.apache.org/viewvc/chemistry/portcmis/release.bat?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/release.bat (added)
+++ chemistry/portcmis/release.bat Mon Jul 20 08:48:57 2015
@@ -0,0 +1,93 @@
+@echo off
+
+rem
+rem    Licensed to the Apache Software Foundation (ASF) under one
+rem    or more contributor license agreements.  See the NOTICE file
+rem    distributed with this work for additional information
+rem    regarding copyright ownership.  The ASF licenses this file
+rem    to you under the Apache License, Version 2.0 (the
+rem    "License"); you may not use this file except in compliance
+rem    with the License.  You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem    Unless required by applicable law or agreed to in writing,
+rem    software distributed under the License is distributed on an
+rem    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem    KIND, either express or implied.  See the License for the
+rem    specific language governing permissions and limitations
+rem    under the License.
+rem
+
+rem This batch file creates a release.
+rem It requires Cygwin.
+
+set PORTCMISVERSION=0.1
+set PORTCMISZIPSRC=chemistry-portcmis-%PORTCMISVERSION%-src.zip
+set PORTCMISZIPBIN=chemistry-portcmis-%PORTCMISVERSION%-bin.zip
+set PORTCMISRC=RC1
+
+set CYGWIN=ntea
+
+echo Building...
+cd PortCMIS
+call build.bat
+cd ..
+
+echo Creating release directories...
+rmdir /S /Q release-src
+mkdir release-src
+rmdir /S /Q release-bin
+mkdir release-bin
+
+echo Copying readme, etc...
+copy LICENSE release-src
+copy LICENSE release-bin
+copy NOTICE release-src
+copy NOTICE release-bin
+copy DEPENDENCIES release-src
+copy DEPENDENCIES release-bin
+copy README release-src
+copy README release-bin
+
+echo Copying binaries ...
+copy PortCMIS\bin\Release\PortCMIS.dll release-bin
+copy PortCMIS\doc\PortCMIS.chm release-bin
+chmod -R a+rwx release-bin
+
+echo Copying source...
+mkdir release-src\src
+xcopy PortCMIS release-src\src /E
+rmdir /S /Q release-src\src\bin
+rmdir /S /Q release-src\src\obj
+rmdir /S /Q release-src\src\doc
+chmod -R a+rwx release-src
+
+echo Creating release file...
+rmdir /S /Q artifacts
+mkdir artifacts
+
+cd release-src
+zip -r  ../artifacts/%PORTCMISZIPSRC% *
+cd ..
+
+cd release-bin
+zip -r  ../artifacts/%PORTCMISZIPBIN% *
+cd ..
+
+echo Signing release file...
+cd artifacts
+
+gpg --armor --output %PORTCMISZIPSRC%.asc --detach-sig %PORTCMISZIPSRC%
+gpg --print-md MD5 %PORTCMISZIPSRC% > %PORTCMISZIPSRC%.md5
+gpg --print-md SHA512 %PORTCMISZIPSRC% > %PORTCMISZIPSRC%.sha
+
+gpg --armor --output %PORTCMISZIPBIN%.asc --detach-sig %PORTCMISZIPBIN%
+gpg --print-md MD5 %PORTCMISZIPBIN% > %PORTCMISZIPBIN%.md5
+gpg --print-md SHA512 %PORTCMISZIPBIN% > %PORTCMISZIPBIN%.sha
+
+cd ..
+
+echo Creating RC tag
+rem svn copy https://svn.apache.org/repos/asf/chemistry/portcmis/trunk https://svn.apache.org/repos/asf/chemistry/portcmis/tags/chemistry-portcmis-%PORTCMISVERSION%-%PORTCMISRC%
+