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%
+