Removed Spring.Http project (moved to GitHub project spring-net-rest) (SPRNET-1345)

This commit is contained in:
bbaia
2011-02-04 19:10:36 +00:00
parent ab3f4dedea
commit 5532f67a9d
161 changed files with 0 additions and 38784 deletions

View File

@@ -1,5 +0,0 @@
using System;
using System.Reflection;
[assembly: AssemblyTitle("Spring.Http")]
[assembly: AssemblyDescription("Interfaces and classes that provide REST client API in Spring.NET")]

View File

@@ -1,221 +0,0 @@
#if SILVERLIGHT
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
namespace Spring.Collections.Specialized
{
/// <summary>
/// Represents a collection of associated string keys and multiple string values.
/// </summary>
/// <remarks>
/// Silverlight's implementation, based on a dictionary, of the .NET Framework NameValueCollection class.
/// </remarks>
/// <author>Bruno Baia</author>
public class NameValueCollection : IEnumerable<string>
{
private Dictionary<string, List<string>> innerCollection;
/// <summary>
/// Creates a new instance of the <see cref="NameValueCollection"/> class.
/// </summary>
public NameValueCollection()
{
innerCollection = new Dictionary<string, List<string>>();
}
/// <summary>
/// Creates a new instance of the <see cref="NameValueCollection"/> class
/// with the specified initial capacity.
/// </summary>
public NameValueCollection(int capacity)
{
innerCollection = new Dictionary<string, List<string>>(capacity);
}
/// <summary>
/// Creates a new instance of the <see cref="NameValueCollection"/> class
/// with the specified comparer.
/// </summary>
public NameValueCollection(IEqualityComparer<string> comparer)
{
innerCollection = new Dictionary<string, List<string>>(comparer);
}
/// <summary>
/// Creates a new instance of the <see cref="NameValueCollection"/> class
/// with the specified initial capacity and comparer.
/// </summary>
public NameValueCollection(int capacity, IEqualityComparer<string> comparer)
{
innerCollection = new Dictionary<string, List<string>>(capacity, comparer);
}
/// <summary>
/// Adds the given single value to the current list of values for the given key.
/// </summary>
/// <param name="name">The key to use.</param>
/// <param name="value">The value to add.</param>
public virtual void Add(string name, string value)
{
List<string> list;
if (!this.innerCollection.TryGetValue(name, out list))
{
list = new List<string>();
}
list.Add(value);
this.innerCollection[name] = list;
}
/// <summary>
/// Returns values for the given key as a comma-delimited string.
/// </summary>
/// <param name="name">The key that contains the values to get.</param>
/// <returns>A comma-delimited string, if found; otherwise <see langword="null"/>.</returns>
public virtual string Get(string name)
{
string str = null;
List<string> list;
if (this.innerCollection.TryGetValue(name, out list))
{
for (int i = 0; i < list.Count; i++)
{
if (i == 0)
{
str = list[i];
}
else
{
str = str + list[i];
}
if (i != (list.Count - 1))
{
str = str + ",";
}
}
}
return str;
}
/// <summary>
/// Returns values for the given key as a string array.
/// </summary>
/// <param name="name">The key that contains the values to get.</param>
/// <returns>A string array, if found; otherwise, <see langword="null"/>.</returns>
public virtual string[] GetValues(string name)
{
List<string> list;
if (this.innerCollection.TryGetValue(name, out list))
{
return list.ToArray();
}
return null;
}
/// <summary>
/// Sets the given single value under the given key.
/// </summary>
/// <param name="name">The key to use.</param>
/// <param name="value">The value to set.</param>
public virtual void Set(string name, string value)
{
List<string> list = new List<string>();
list.Add(value);
this.innerCollection[name] = list;
}
/// <summary>
/// Removes the given key from the collection.
/// </summary>
/// <param name="name">The key to remove.</param>
/// <returns>
/// <see langword="true"/> if the key have been found and removed from the collection;
/// otherwise, <see langword="false"/>.
/// </returns>
public virtual bool Remove(string name)
{
return this.innerCollection.Remove(name);
}
/// <summary>
/// Gets all the keys in the collection.
/// </summary>
public virtual string[] AllKeys
{
get
{
int count = this.innerCollection.Count;
string[] array = new string[count];
this.innerCollection.Keys.CopyTo(array, 0);
return array;
}
}
/// <summary>
/// Gets the number of keys contained in the collection.
/// </summary>
public virtual int Count
{
get
{
return this.innerCollection.Count;
}
}
/// <summary>
/// Gets values as a comma-delimited string or sets a single value for the given key.
/// </summary>
/// <param name="name">The key to use.</param>
/// <returns>A comma-delimited string, if found; otherwise <see langword="null"/>.</returns>
public virtual string this[string name]
{
get
{
return this.Get(name);
}
set
{
this.Set(name, value);
}
}
#region IEnumerable<string> Membres
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
return this.innerCollection.Keys.GetEnumerator();
}
#endregion
#region IEnumerable Membres
IEnumerator IEnumerable.GetEnumerator()
{
return this.innerCollection.Keys.GetEnumerator();
}
#endregion
}
}
#endif

View File

@@ -1,66 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.ComponentModel;
namespace Spring.Http.Client
{
// TODO: Rename this to HttpRequestCompletedEventArgs or something ?
/// <summary>
/// Provides data when an asynchronous HTTP request execution completes.
/// </summary>
/// <see cref="IClientHttpRequest"/>
public class ExecuteCompletedEventArgs : AsyncCompletedEventArgs
{
private IClientHttpResponse response;
/// <summary>
/// Gets the <see cref="IClientHttpResponse">response</see> result of the execution.
/// </summary>
/// <exception cref="System.InvalidOperationException">If the execution was canceled.</exception>
/// <exception cref="System.Reflection.TargetInvocationException">If the execution failed.</exception>
public IClientHttpResponse Response
{
get
{
// Raise an exception if the operation failed or was canceled.
base.RaiseExceptionIfNecessary();
// If the operation was successful, return the value.
return response;
}
}
/// <summary>
/// Creates a new instance of <see cref="ExecuteCompletedEventArgs"/>.
/// </summary>
/// <param name="response">The response of the execution.</param>
/// <param name="exception">Any error that occurred during the asynchronous execution.</param>
/// <param name="cancelled">A value indicating whether the asynchronous execution was canceled.</param>
/// <param name="userState">The optional user-supplied state object.</param>
public ExecuteCompletedEventArgs(IClientHttpResponse response, Exception exception, bool cancelled, object userState)
: base(exception, cancelled, userState)
{
this.response = response;
}
}
}

View File

@@ -1,79 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
namespace Spring.Http.Client
{
/// <summary>
/// Represents a client-side HTTP request.
/// </summary>
/// <remarks>
/// <para>
/// Created via an implementation of the <see cref="IClientHttpRequestFactory"/>.
/// </para>
/// <para>
/// A client HTTP request can be executed,
/// getting an <see cref="IClientHttpResponse"/> which can be read from.
/// </para>
/// </remarks>
/// <seealso cref="IClientHttpRequestFactory"/>
/// <seealso cref="IClientHttpResponse"/>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IClientHttpRequest : IHttpOutputMessage
{
/// <summary>
/// Gets the HTTP method of the request.
/// </summary>
HttpMethod Method { get; }
/// <summary>
/// Gets the URI of the request.
/// </summary>
Uri Uri { get; }
#if !SILVERLIGHT
/// <summary>
/// Execute this request, resulting in a <see cref="IClientHttpResponse" /> that can be read.
/// </summary>
/// <returns>The response result of the execution</returns>
IClientHttpResponse Execute();
#endif
/// <summary>
/// Execute this request asynchronously.
/// </summary>
/// <param name="state">
/// An optional user-defined object that is passed to the method invoked
/// when the asynchronous operation completes.
/// </param>
/// <param name="executeCompleted">
/// The <see cref="Action{ExecuteCompletedEventArgs}"/> to perform when the asynchronous execution completes.
/// </param>
void ExecuteAsync(object state, Action<ExecuteCompletedEventArgs> executeCompleted);
/// <summary>
/// Cancels a pending asynchronous operation.
/// </summary>
void CancelAsync();
}
}

View File

@@ -1,42 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
namespace Spring.Http.Client
{
/// <summary>
/// Factory for <see cref="IClientHttpRequest"/> objects.
/// Requests are created by the <see cref="M:CreateRequest"/> method.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IClientHttpRequestFactory
{
/// <summary>
/// Create a new <see cref="IClientHttpRequest"/> for the specified URI and HTTP method.
/// </summary>
/// <param name="uri">The URI to create a request for.</param>
/// <param name="method">The HTTP method to execute.</param>
/// <returns>The created request</returns>
IClientHttpRequest CreateRequest(Uri uri, HttpMethod method);
}
}

View File

@@ -1,59 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
namespace Spring.Http.Client
{
/// <summary>
/// Represents a client-side HTTP response.
/// </summary>
/// <remarks>
/// <para>
/// Obtained via an 'execution' of the <see cref="IClientHttpRequest"/>.
/// </para>
/// <para>
/// A client HTTP response must be <see cref="M:Close">closed</see>,
/// typically in a <code>finally</code> or via an <code>using</code> block.
/// </para>
/// </remarks>
/// <seealso cref="IClientHttpRequest"/>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IClientHttpResponse : IHttpInputMessage, IDisposable
{
/// <summary>
/// Gets the HTTP status code of the response.
/// </summary>
HttpStatusCode StatusCode { get; }
/// <summary>
/// Gets the HTTP status description of the response.
/// </summary>
string StatusDescription { get; }
/// <summary>
/// Closes this response, freeing any resources created.
/// </summary>
void Close();
}
}

View File

@@ -1,491 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Threading;
using System.ComponentModel;
using System.Globalization;
using Spring.Util;
namespace Spring.Http.Client
{
/// <summary>
/// <see cref="IClientHttpRequest"/> implementation that uses
/// .NET <see cref="HttpWebRequest"/>'s class to execute requests.
/// </summary>
/// <seealso cref="WebClientHttpRequestFactory"/>
/// <author>Bruno Baia</author>
public class WebClientHttpRequest : IClientHttpRequest
{
private HttpHeaders headers;
private Action<Stream> body;
private HttpWebRequest httpWebRequest;
private bool isExecuted;
private bool isCancelled;
/// <summary>
/// Gets the <see cref="HttpWebRequest"/> instance used by the request.
/// </summary>
public HttpWebRequest HttpWebRequest
{
get { return this.httpWebRequest; }
}
/// <summary>
/// Creates a new instance of <see cref="WebClientHttpRequest"/>
/// with the given <see cref="HttpWebRequest"/> instance.
/// </summary>
/// <param name="request">The <see cref="HttpWebRequest"/> instance to use.</param>
public WebClientHttpRequest(HttpWebRequest request)
{
AssertUtils.ArgumentNotNull(request, "HttpWebRequest");
this.httpWebRequest = request;
this.headers = new HttpHeaders();
}
#region IClientHttpRequest Members
/// <summary>
/// Gets the HTTP method of the request.
/// </summary>
public HttpMethod Method
{
get
{
return (HttpMethod)Enum.Parse(typeof(HttpMethod), this.httpWebRequest.Method, true);
}
}
/// <summary>
/// Gets the URI of the request.
/// </summary>
public Uri Uri
{
get
{
return this.httpWebRequest.RequestUri;
}
}
/// <summary>
/// Gets the message headers.
/// </summary>
public HttpHeaders Headers
{
get { return headers; }
}
/// <summary>
/// Sets the delegate that writes the body message as a stream.
/// </summary>
public Action<Stream> Body
{
set { this.body = value; }
}
#if !SILVERLIGHT
/// <summary>
/// Execute this request, resulting in a <see cref="IClientHttpResponse" /> that can be read.
/// </summary>
/// <returns>The response result of the execution</returns>
/// <see cref="InvalidOperationException">If the request is already executed or is currently executing.</see>
public IClientHttpResponse Execute()
{
this.EnsureNotExecuted();
try
{
// Prepare
this.PrepareForExecution();
// Write
if (this.body != null)
{
using (Stream stream = this.httpWebRequest.GetRequestStream())
{
this.body(stream);
}
}
// Read
HttpWebResponse httpWebResponse = this.httpWebRequest.GetResponse() as HttpWebResponse;
if (this.httpWebRequest.HaveResponse && httpWebResponse != null)
{
return this.CreateClientHttpResponse(httpWebResponse);
}
}
catch (WebException ex)
{
// This exception can be raised with some status code
// Try to retrieve the response from the error
HttpWebResponse httpWebResponse = ex.Response as HttpWebResponse;
if (httpWebResponse != null)
{
return this.CreateClientHttpResponse(httpWebResponse);
}
throw;
}
finally
{
this.isExecuted = true;
}
return null;
}
#endif
/// <summary>
/// Execute this request asynchronously.
/// </summary>
/// <param name="state">
/// An optional user-defined object that is passed to the method invoked
/// when the asynchronous operation completes.
/// </param>
/// <param name="executeCompleted">
/// The <see cref="Action{ExecuteCompletedEventArgs}"/> to perform when the asynchronous execution completes.
/// </param>
/// <see cref="InvalidOperationException">If the request is already executed or is currently executing.</see>
public void ExecuteAsync(object state, Action<ExecuteCompletedEventArgs> executeCompleted)
{
this.EnsureNotExecuted();
AsyncOperation asyncOperation = AsyncOperationManager.CreateOperation(state);
ExecuteState executeState = new ExecuteState(executeCompleted, asyncOperation);
try
{
// Prepare
this.PrepareForExecution();
// Post request
if (this.body != null)
{
this.httpWebRequest.BeginGetRequestStream(new AsyncCallback(ExecuteRequestCallback), executeState);
}
else
{
// Get request
this.HttpWebRequest.BeginGetResponse(new AsyncCallback(ExecuteResponseCallback), executeState);
}
}
catch (Exception ex)
{
if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException)
{
throw;
}
ExecuteAsyncCallback(executeState, null, ex);
}
finally
{
this.isExecuted = true;
}
}
/// <summary>
/// Cancels a pending asynchronous operation.
/// </summary>
public void CancelAsync()
{
this.isCancelled = true;
try
{
if (this.httpWebRequest != null)
{
this.httpWebRequest.Abort();
}
}
catch (Exception exception)
{
if (((exception is OutOfMemoryException) || (exception is StackOverflowException)) || (exception is ThreadAbortException))
{
throw;
}
}
}
#endregion
#region Async methods/classes
private void ExecuteRequestCallback(IAsyncResult result)
{
ExecuteState state = (ExecuteState)result.AsyncState;
try
{
// Write
using (Stream stream = this.httpWebRequest.EndGetRequestStream(result))
{
this.body(stream);
}
// Read
this.httpWebRequest.BeginGetResponse(new AsyncCallback(ExecuteResponseCallback), state);
}
catch (Exception ex)
{
if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException)
{
throw;
}
ExecuteAsyncCallback(state, null, ex);
}
}
private void ExecuteResponseCallback(IAsyncResult result)
{
ExecuteState state = (ExecuteState)result.AsyncState;
IClientHttpResponse response = null;
Exception exception = null;
try
{
HttpWebResponse httpWebResponse = this.httpWebRequest.EndGetResponse(result) as HttpWebResponse;
if (this.httpWebRequest.HaveResponse == true && httpWebResponse != null)
{
response = this.CreateClientHttpResponse(httpWebResponse);
}
}
catch (Exception ex)
{
if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException)
{
throw;
}
exception = ex;
// This exception can be raised with some status code
// Try to retrieve the response from the error
if (ex is WebException)
{
HttpWebResponse httpWebResponse = ((WebException)ex).Response as HttpWebResponse;
if (httpWebResponse != null)
{
exception = null;
response = this.CreateClientHttpResponse(httpWebResponse);
}
}
}
ExecuteAsyncCallback(state, response, exception);
}
// This is the method that the underlying, free-threaded asynchronous behavior will invoke.
// This will happen on an arbitrary thread.
private void ExecuteAsyncCallback(ExecuteState state, IClientHttpResponse response, Exception exception)
{
// Package the results of the operation
ExecuteCompletedEventArgs eventArgs = new ExecuteCompletedEventArgs(response, exception, this.isCancelled, state.AsyncOperation.UserSuppliedState);
ExecuteCallbackArgs<ExecuteCompletedEventArgs> callbackArgs = new ExecuteCallbackArgs<ExecuteCompletedEventArgs>(eventArgs, state.ExecuteCompleted);
SendOrPostCallback callback = new SendOrPostCallback(ExecuteResponseReceived);
// End the task. The asyncOp object is responsible for marshaling the call.
state.AsyncOperation.PostOperationCompleted(callback, callbackArgs);
}
private static void ExecuteResponseReceived(object arg)
{
ExecuteCallbackArgs<ExecuteCompletedEventArgs> callbackArgs = (ExecuteCallbackArgs<ExecuteCompletedEventArgs>)arg;
if (callbackArgs.Callback != null)
{
callbackArgs.Callback(callbackArgs.EventArgs);
}
}
private class ExecuteCallbackArgs<T> where T : class
{
public T EventArgs;
public Action<T> Callback;
public ExecuteCallbackArgs(T eventArgs,
Action<T> callback)
{
this.EventArgs = eventArgs;
this.Callback = callback;
}
}
private class ExecuteState
{
public Action<ExecuteCompletedEventArgs> ExecuteCompleted;
public AsyncOperation AsyncOperation;
public ExecuteState(
Action<ExecuteCompletedEventArgs> executeCompleted,
AsyncOperation asyncOperation)
{
this.ExecuteCompleted = executeCompleted;
this.AsyncOperation = asyncOperation;
}
}
#endregion
/// <summary>
/// Ensures that the request can be executed.
/// </summary>
/// <see cref="InvalidOperationException">If the request is already executed or is currently executing.</see>
protected void EnsureNotExecuted()
{
if (this.isExecuted)
{
throw new InvalidOperationException("Client HTTP request already executed or is currently executing.");
}
}
/// <summary>
/// Creates and returns an <see cref="IClientHttpResponse"/> implementation associated
/// with the request.
/// </summary>
/// <param name="response">The <see cref="HttpWebResponse"/> instance to use.</param>
/// <returns>
/// An <see cref="IClientHttpResponse"/> implementation associated with the request.
/// </returns>
protected virtual IClientHttpResponse CreateClientHttpResponse(HttpWebResponse response)
{
return new WebClientHttpResponse(response);
}
/// <summary>
/// Prepare the request for execution.
/// </summary>
/// <remarks>
/// Default implementation copies headers to the .NET request. Can be overridden in subclasses.
/// </remarks>
protected virtual void PrepareForExecution()
{
// Copy headers
foreach (string header in this.headers)
{
// Special headers
switch (header.ToUpper(CultureInfo.InvariantCulture))
{
case "ACCEPT":
{
this.httpWebRequest.Accept = this.headers[header];
break;
}
#if !SILVERLIGHT_3 && !WINDOWS_PHONE
case "CONTENT-LENGTH":
{
this.httpWebRequest.ContentLength = this.headers.ContentLength;
break;
}
#endif
case "CONTENT-TYPE":
{
this.httpWebRequest.ContentType = this.headers[header];
break;
}
#if NET_4_0
case "DATE" :
{
DateTime? date = this.headers.Date;
if (date.HasValue)
{
this.httpWebRequest.Date = date.Value;
}
else
{
this.httpWebRequest.Date = DateTime.MinValue;
}
break;
}
case "HOST" :
{
this.httpWebRequest.Host = this.headers[header];
break;
}
#endif
#if !SILVERLIGHT
case "CONNECTION":
{
string headerValue = this.headers[header];
if (headerValue.Equals("Keep-Alive", StringComparison.OrdinalIgnoreCase))
{
this.httpWebRequest.KeepAlive = true;
}
else if (!headerValue.Equals("Close", StringComparison.OrdinalIgnoreCase))
{
this.httpWebRequest.Connection = headerValue;
}
break;
}
case "EXPECT":
{
this.httpWebRequest.Expect = this.headers[header];
break;
}
case "IF-MODIFIED-SINCE":
{
DateTime? date = this.headers.IfModifiedSince;
if (date.HasValue)
{
this.httpWebRequest.IfModifiedSince = date.Value;
}
else
{
this.httpWebRequest.IfModifiedSince = DateTime.MinValue;
}
break;
}
//case "RANGE":
// {
// break;
// }
case "REFERER":
{
this.httpWebRequest.Referer = this.headers[header];
break;
}
case "TRANSFER-ENCODING":
{
this.httpWebRequest.SendChunked = true;
string headerValue = this.headers[header];
if (!headerValue.Equals("Chunked", StringComparison.OrdinalIgnoreCase))
{
this.httpWebRequest.TransferEncoding = headerValue;
}
break;
}
#endif
#if !SILVERLIGHT_3
case "USER-AGENT":
{
this.httpWebRequest.UserAgent = this.headers[header];
break;
}
#endif
default:
{
// Other headers
this.httpWebRequest.Headers[header] = this.headers[header];
break;
}
}
}
}
}
}

View File

@@ -1,228 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace Spring.Http.Client
{
/// <summary>
/// <see cref="IClientHttpRequestFactory"/> implementation that uses
/// .NET <see cref="HttpWebRequest"/>'s class to create requests.
/// </summary>
/// <see cref="WebClientHttpRequest"/>
/// <author>Bruno Baia</author>
public class WebClientHttpRequestFactory : IClientHttpRequestFactory
{
/// <summary>
/// The .NET <see cref="HttpWebRequest"/> used by this factory
/// or <see langword="null"/> if not created.
/// </summary>
private HttpWebRequest httpWebRequest;
#region Properties
#if !SILVERLIGHT_3
private bool? _useDefaultCredentials;
/// <summary>
/// Gets or sets a boolean value that controls whether default credentials are sent with this request.
/// </summary>
public bool? UseDefaultCredentials
{
get { return this._useDefaultCredentials; }
set { this._useDefaultCredentials = value; }
}
#endif
private ICredentials _credentials;
/// <summary>
/// Gets or sets authentication information for the request.
/// </summary>
public ICredentials Credentials
{
get { return this._credentials; }
set { this._credentials = value; }
}
#if !SILVERLIGHT
private X509CertificateCollection _clientCertificates;
/// <summary>
/// Gets or sets the collection of security certificates that are associated with this request.
/// </summary>
public X509CertificateCollection ClientCertificates
{
get
{
if (this._clientCertificates == null)
{
this._clientCertificates = new X509CertificateCollection();
}
return this._clientCertificates;
}
}
private IWebProxy _proxy;
/// <summary>
/// Gets or sets proxy information for the request.
/// </summary>
/// <remarks>
/// The default value is set by calling the <see cref="P:System.Net.GlobalProxySelection.Select"/> property.
/// </remarks>
public IWebProxy Proxy
{
get { return this._proxy; }
set { this._proxy = value; }
}
private int? _timeout;
/// <summary>
/// Gets or sets the time-out value in milliseconds for synchrone request only.
/// </summary>
/// <remarks>
/// The default is 100,000 milliseconds (100 seconds).
/// </remarks>
public int? Timeout
{
get { return this._timeout; }
set { this._timeout = value; }
}
#endif
#if SILVERLIGHT && !WINDOWS_PHONE
private WebRequestCreatorType _webRequestCreator;
/// <summary>
/// Gets or sets a value that indicates how HTTP requests and responses will be handled.
/// </summary>
/// <remarks>
/// By default, this factory will use the default Silverlight behavior for HTTP methods GET and POST,
/// and force the client HTTP stack for other HTTP methods.
/// </remarks>
public WebRequestCreatorType WebRequestCreator
{
get { return this._webRequestCreator; }
set { this._webRequestCreator = value; }
}
#endif
#endregion
#if SILVERLIGHT && !WINDOWS_PHONE
/// <summary>
/// Creates a new instance of <see cref="WebClientHttpRequestFactory"/>.
/// </summary>
public WebClientHttpRequestFactory()
{
this._webRequestCreator = WebRequestCreatorType.Unknown;
}
#endif
#region IClientHttpRequestFactory Membres
/// <summary>
/// Create a new <see cref="IClientHttpRequest"/> for the specified URI and HTTP method.
/// </summary>
/// <param name="uri">The URI to create a request for.</param>
/// <param name="method">The HTTP method to execute.</param>
/// <returns>The created request</returns>
public virtual IClientHttpRequest CreateRequest(Uri uri, HttpMethod method)
{
#if SILVERLIGHT && !WINDOWS_PHONE
switch (this._webRequestCreator)
{
case WebRequestCreatorType.ClientHttp:
this.httpWebRequest = (HttpWebRequest)System.Net.Browser.WebRequestCreator.ClientHttp.Create(uri);
break;
case WebRequestCreatorType.BrowserHttp:
this.httpWebRequest = (HttpWebRequest)System.Net.Browser.WebRequestCreator.BrowserHttp.Create(uri);
break;
case WebRequestCreatorType.Unknown:
if (method == HttpMethod.GET || method == HttpMethod.POST)
{
this.httpWebRequest = WebRequest.Create(uri) as HttpWebRequest;
}
else
{
// Force Client HTTP stack
this.httpWebRequest = (HttpWebRequest)System.Net.Browser.WebRequestCreator.ClientHttp.Create(uri);
}
break;
}
#else
this.httpWebRequest = WebRequest.Create(uri) as HttpWebRequest;
#endif
this.httpWebRequest.Method = method.ToString();
#if !SILVERLIGHT_3
if (this._useDefaultCredentials.HasValue)
{
this.httpWebRequest.UseDefaultCredentials = this._useDefaultCredentials.Value;
}
#endif
if (this._credentials != null)
{
this.httpWebRequest.Credentials = this._credentials;
}
#if !SILVERLIGHT
if (this._clientCertificates != null)
{
foreach (X509Certificate2 certificate in this._clientCertificates)
{
this.httpWebRequest.ClientCertificates.Add(certificate);
}
}
if (this._proxy != null)
{
this.httpWebRequest.Proxy = this._proxy;
}
if (this._timeout != null)
{
this.httpWebRequest.Timeout = this._timeout.Value;
}
#endif
return new WebClientHttpRequest(this.httpWebRequest);
}
#endregion
}
#if SILVERLIGHT && !WINDOWS_PHONE
/// <summary>
/// Defines identifiers for supported Silverlight HTTP handling stacks.
/// </summary>
public enum WebRequestCreatorType
{
/// <summary>
/// Specifies an unknown HTTP handling stack.
/// </summary>
Unknown,
/// <summary>
/// Specifies browser HTTP handling stack.
/// </summary>
BrowserHttp,
/// <summary>
/// Specifies client HTTP handling stack.
/// </summary>
ClientHttp
}
#endif
}

View File

@@ -1,163 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
using Spring.Util;
namespace Spring.Http.Client
{
/// <summary>
/// <see cref="IClientHttpResponse"/> implementation that uses
/// .NET <see cref="HttpWebResponse"/>'s class to read responses.
/// </summary>
/// <author>Bruno Baia</author>
public class WebClientHttpResponse : IClientHttpResponse
{
private HttpHeaders headers;
private HttpWebResponse httpWebResponse;
/// <summary>
/// Gets the <see cref="HttpWebResponse"/> instance used by the response.
/// </summary>
public HttpWebResponse HttpWebResponse
{
get { return this.httpWebResponse; }
}
/// <summary>
/// Creates a new instance of <see cref="WebClientHttpResponse"/>
/// with the given <see cref="HttpWebResponse"/> instance.
/// </summary>
/// <param name="response">The <see cref="HttpWebResponse"/> instance to use.</param>
public WebClientHttpResponse(HttpWebResponse response)
{
AssertUtils.ArgumentNotNull(response, "HttpWebResponse");
this.httpWebResponse = response;
this.headers = new HttpHeaders();
this.Initialize();
}
#region IClientHttpResponse Membres
/// <summary>
/// Gets the message headers.
/// </summary>
public HttpHeaders Headers
{
get { return this.headers; }
}
/// <summary>
/// Gets the body of the message as a stream.
/// </summary>
public Stream Body
{
get
{
return this.httpWebResponse.GetResponseStream();
}
}
/// <summary>
/// Gets the HTTP status code of the response.
/// </summary>
public HttpStatusCode StatusCode
{
get
{
return this.httpWebResponse.StatusCode;
}
}
/// <summary>
/// Gets the HTTP status description of the response.
/// </summary>
public string StatusDescription
{
get
{
return this.httpWebResponse.StatusDescription;
}
}
/// <summary>
/// Closes this response, freeing any resources created.
/// </summary>
public void Close()
{
this.httpWebResponse.Close();
}
void IDisposable.Dispose()
{
((IDisposable)this.httpWebResponse).Dispose();
}
#endregion
/// <summary>
/// Initialize the response.
/// </summary>
/// <remarks>
/// Default implementation copies headers from the .NET response. Can be overridden in subclasses.
/// </remarks>
protected virtual void Initialize()
{
#if NET_2_0 || WINDOWS_PHONE
foreach (string header in this.httpWebResponse.Headers)
{
this.headers[header] = this.httpWebResponse.Headers[header];
}
#endif
#if SILVERLIGHT_3
try
{
foreach (string header in this.httpWebResponse.Headers)
{
this.headers[header] = this.httpWebResponse.Headers[header];
}
}
catch(NotImplementedException)
{
this.headers.ContentLength = this.httpWebResponse.ContentLength;
this.headers["Content-Type"] = this.httpWebResponse.ContentType;
}
#elif SILVERLIGHT
if (this.httpWebResponse.SupportsHeaders)
{
foreach (string header in this.httpWebResponse.Headers)
{
this.headers[header] = this.httpWebResponse.Headers[header];
}
}
else
{
this.headers.ContentLength = this.httpWebResponse.ContentLength;
this.headers["Content-Type"] = this.httpWebResponse.ContentType;
}
#endif
}
}
}

View File

@@ -1,260 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Collections.Generic;
namespace Spring.Http.Converters
{
/// <summary>
/// Base class for most <see cref="IHttpMessageConverter"/> implementations.
/// </summary>
/// <remarks>
/// This base class adds support for setting supported <see cref="MediaType"/>s, through the
/// <see cref="P:SupportedMediaTypes"/> property.
/// It also adds support for 'Content-Type' when writing to the HTTP message.
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Juergen Hoeller</author>
/// <author>Bruno Baia (.NET)</author>
public abstract class AbstractHttpMessageConverter : IHttpMessageConverter
{
#region Logging
#if !SILVERLIGHT
private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(AbstractHttpMessageConverter));
#endif
#endregion
private IList<MediaType> _supportedMediaTypes = new List<MediaType>();
#region Constructor(s)
/// <summary>
/// Creates a new instance of the <see cref="AbstractHttpMessageConverter"/>
/// with no supported media types.
/// </summary>
protected AbstractHttpMessageConverter()
{
}
/// <summary>
/// Creates a new instance of the <see cref="AbstractHttpMessageConverter"/>
/// with multiple supported media type.
/// </summary>
/// <param name="supportedMediaTypes">The supported media types.</param>
protected AbstractHttpMessageConverter(params MediaType[] supportedMediaTypes)
{
this._supportedMediaTypes = new List<MediaType>(supportedMediaTypes);
}
#endregion
#region IHttpMessageConverter Membres
/// <summary>
/// Indicates whether the given class can be read by this converter.
/// </summary>
/// <remarks>
/// This implementation checks if the given class is <see cref="M:Supports(Type)">supported</see>,
/// and if the <see cref="P:SupportedMediaTypes">supported media types</see> <see cref="M:MediaType.Includes(MediaType)">include</see>
/// the given media type.
/// </remarks>
/// <param name="type">The class to test for readability</param>
/// <param name="mediaType">
/// The media type to read, can be null if not specified. Typically the value of a 'Content-Type' header.
/// </param>
/// <returns><see langword="true"/> if readable; otherwise <see langword="false"/></returns>
public bool CanRead(Type type, MediaType mediaType)
{
return Supports(type) && CanRead(mediaType);
}
/// <summary>
/// Indicates whether the given class can be written by this converter.
/// </summary>
/// <remarks>
/// This implementation checks if the given class is <see cref="M:Supports(Type)">supported</see>,
/// and if the <see cref="P:SupportedMediaTypes">supported media types</see> <see cref="M:MediaType.Includes(MediaType)">include</see>
/// the given media type.
/// </remarks>
/// <param name="type">The class to test for writability</param>
/// <param name="mediaType">
/// The media type to write, can be null if not specified. Typically the value of an 'Accept' header.
/// </param>
/// <returns><see langword="true"/> if writable; otherwise <see langword="false"/></returns>
public bool CanWrite(Type type, MediaType mediaType)
{
return Supports(type) && CanWrite(mediaType);
}
/// <summary>
/// Gets or sets the list of <see cref="MediaType"/> objects supported by this converter.
/// </summary>
public IList<MediaType> SupportedMediaTypes
{
get { return _supportedMediaTypes; }
set { _supportedMediaTypes = value; }
}
/// <summary>
/// Read an object of the given type form the given HTTP message, and returns it.
/// </summary>
/// <remarks>
/// This implementation simple delegates to <see cre="ReadInternal"/> method.
/// Future implementations might add some default behavior, however.
/// </remarks>
/// <typeparam name="T">
/// The type of object to return. This type must have previously been passed to the
/// <see cref="M:CanRead"/> method of this interface, which must have returned <see langword="true"/>.
/// </typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
public T Read<T>(IHttpInputMessage message) where T : class
{
return ReadInternal<T>(message);
}
/// <summary>
/// Write an given object to the given HTTP message.
/// </summary>
/// <remarks>
/// This implementation delegates to <see cref="M:GetDefaultContentType"/> method if a content
/// type was not provided, and calls <see cref="M:WriteInternal"/>.
/// </remarks>
/// <param name="content">
/// The object to write to the HTTP message. The type of this object must have previously been
/// passed to the <see cref="M:CanWrite"/> method of this interface, which must have returned <see langword="true"/>.
/// </param>
/// <param name="contentType">
/// The content type to use when writing. May be null to indicate that the default content type of the converter must be used.
/// If not null, this media type must have previously been passed to the <see cref="M:CanWrite"/> method of this interface,
/// which must have returned <see langword="true"/>.
/// </param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
public void Write(object content, MediaType contentType, IHttpOutputMessage message)
{
HttpHeaders headers = message.Headers;
if (headers.ContentType == null)
{
if (contentType == null || contentType.IsWildcardType || contentType.IsWildcardSubtype)
{
contentType = GetDefaultContentType(content.GetType());
}
if (contentType != null)
{
headers.ContentType = contentType;
}
}
WriteInternal(content, message);
}
#endregion
/// <summary>
/// Returns true if any of the <see cref="P:SupportedMediaTypes">supported media types</see> include the given media type.
/// </summary>
/// <param name="mediaType">
/// The media type to read, can be null if not specified. Typically the value of a 'Content-Type' header.
/// </param>
/// <returns>
/// <see langword="true"/> if the supported media types include the media type, or if the media type is null.
/// </returns>
protected bool CanRead(MediaType mediaType)
{
if (mediaType == null)
{
return true;
}
foreach(MediaType supportedMediaType in this._supportedMediaTypes)
{
if (supportedMediaType.Includes(mediaType))
{
return true;
}
}
return false;
}
/// <summary>
/// Returns true if the given media type includes any of the <see cref="P:SupportedMediaTypes">supported media types</see>.
/// </summary>
/// <param name="mediaType">
/// The media type to write, can be {@code null} if not specified. Typically the value of an 'Accept' header.
/// </param>
/// <returns>
/// <see langword="true"/> if the supported media types are compatible with the media type, or if the media type is null.
/// </returns>
protected bool CanWrite(MediaType mediaType)
{
if (mediaType == null || mediaType.Equals(MediaType.ALL))
{
return true;
}
foreach(MediaType supportedMediaType in this._supportedMediaTypes)
{
if (supportedMediaType.IsCompatibleWith(mediaType))
{
return true;
}
}
return false;
}
/// <summary>
/// Returns the default content type for the given type.
/// Called when <see cref="M:Write"/> is invoked without a specified content type parameter.
/// </summary>
/// <remarks>
/// By default, this returns the first element of the <see cref="P:SupportedMediaTypes"/> property, if any.
/// </remarks>
/// <param name="type">The type to return the content type for.</param>
/// <returns>The <see cref="MediaType">content type</see>, or null if not known.</returns>
protected virtual MediaType GetDefaultContentType(Type type)
{
return (this._supportedMediaTypes.Count > 0 ? this._supportedMediaTypes[0] : null);
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected abstract bool Supports(Type type);
/// <summary>
/// Abstract template method that reads the actualy object. Invoked from <see cref="M:Read"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
protected abstract T ReadInternal<T>(IHttpInputMessage message) where T : class;
/// <summary>
/// Abstract template method that writes the actual body. Invoked from <see cref="M:Write"/>.
/// </summary>
/// <param name="content">The object to write to the HTTP message.</param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
protected abstract void WriteInternal(object content, IHttpOutputMessage message);
}
}

View File

@@ -1,97 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
namespace Spring.Http.Converters
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write byte arrays.
/// </summary>
/// <remarks>
/// By default, this converter supports all media types '*/*', and writes with a 'Content-Type'
/// of 'application/octet-stream'.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class ByteArrayHttpMessageConverter : AbstractHttpMessageConverter
{
/// <summary>
/// Creates a new instance of the <see cref="ByteArrayHttpMessageConverter"/>
/// with 'application/octet-stream', and '*/*' media types.
/// </summary>
public ByteArrayHttpMessageConverter() :
base(new MediaType("application", "octet-stream"), MediaType.ALL)
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return type.Equals(typeof(byte[]));
}
/// <summary>
/// Abstract template method that reads the actualy object. Invoked from <see cref="M:Read"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
protected override T ReadInternal<T>(IHttpInputMessage message)
{
// Read from the message stream
using (BinaryReader reader = new BinaryReader(message.Body))
{
return reader.ReadBytes((int)message.Headers.ContentLength) as T;
}
}
/// <summary>
/// Abstract template method that writes the actual body. Invoked from <see cref="M:Write"/>.
/// </summary>
/// <param name="content">The object to write to the HTTP message.</param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
protected override void WriteInternal(object content, IHttpOutputMessage message)
{
// Create a byte array of the data we want to send
byte[] byteData = content as byte[];
//#if !SILVERLIGHT
// // Set the content length in the message headers
// message.Headers.ContentLength = byteData.Length;
//#endif
// Write to the message stream
message.Body = delegate(Stream stream)
{
stream.Write(byteData, 0, byteData.Length);
};
}
}
}

View File

@@ -1,97 +0,0 @@
#if NET_3_5 && !SILVERLIGHT
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Xml;
using System.ServiceModel.Syndication;
using Spring.Http.Converters.Xml;
namespace Spring.Http.Converters.Feed
{
/// <summary>
/// Base class for Atom and RSS Feed message converters
/// using the <see cref="System.ServiceModel.Syndication.SyndicationFeed"/> class.
/// </summary>
/// <author>Bruno Baia</author>
public abstract class AbstractFeedHttpMessageConverter : AbstractXmlHttpMessageConverter
{
/// <summary>
/// Creates a new instance of the <see cref="AbstractXmlHttpMessageConverter"/>
/// with multiple supported media type.
/// </summary>
/// <param name="supportedMediaTypes">The supported media types.</param>
protected AbstractFeedHttpMessageConverter(params MediaType[] supportedMediaTypes) :
base(supportedMediaTypes)
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return type.Equals(typeof(SyndicationFeed)) || type.Equals(typeof(SyndicationItem));
}
/// <summary>
/// Abstract template method that reads the actualy object using a <see cref="XmlReader"/>. Invoked from <see cref="M:ReadInternal"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="xmlReader">The XmlReader to use.</param>
/// <returns>The converted object.</returns>
protected override T ReadXml<T>(XmlReader xmlReader)
{
if (typeof(SyndicationFeed).Equals(typeof(T)))
{
return SyndicationFeed.Load(xmlReader) as T;
}
if (typeof(SyndicationItem).Equals(typeof(T)))
{
return SyndicationItem.Load(xmlReader) as T;
}
return null;
}
/// <summary>
/// Returns the <see cref="XmlReaderSettings">XmlReader settings</see>
/// used by this converter to read from the HTTP message.
/// </summary>
/// <returns>The XmlReader settings.</returns>
protected override XmlReaderSettings GetXmlReaderSettings()
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.CloseInput = true;
settings.IgnoreProcessingInstructions = true;
#if NET_4_0 || SILVERLIGHT
settings.DtdProcessing = DtdProcessing.Ignore;
#else
settings.ProhibitDtd = false;
#endif
settings.XmlResolver = null;
return settings;
}
}
}
#endif

View File

@@ -1,68 +0,0 @@
#if NET_3_5 && !SILVERLIGHT
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
using System.Xml;
using System.ServiceModel.Syndication;
namespace Spring.Http.Converters.Feed
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write Atom feeds
/// using the <see cref="System.ServiceModel.Syndication.SyndicationFeed"/> class.
/// </summary>
/// <remarks>
/// By default, this converter reads and writes the media type 'application/atom+xml' media type.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Bruno Baia</author>
public class Atom10FeedHttpMessageConverter : AbstractFeedHttpMessageConverter
{
/// <summary>
/// Creates a new instance of the <see cref="Atom10FeedHttpMessageConverter"/>
/// with 'application/atom+xml', 'application/xml' and 'text/xml' media types.
/// </summary>
public Atom10FeedHttpMessageConverter() :
base(new MediaType("application", "atom+xml"), new MediaType("application", "xml"), new MediaType("text", "xml"))
{
}
/// <summary>
/// Abstract template method that writes the actual body using a <see cref="XmlWriter"/>. Invoked from <see cref="M:WriteInternal"/>.
/// </summary>
/// <param name="xmlWriter">The XmlWriter to use.</param>
/// <param name="content">The object to write to the HTTP message.</param>
protected override void WriteXml(XmlWriter xmlWriter, object content)
{
if (content is SyndicationFeed)
{
SyndicationFeed atomFeed = content as SyndicationFeed;
atomFeed.SaveAsAtom10(xmlWriter);
}
else if (content is SyndicationItem)
{
SyndicationItem atomItem = content as SyndicationItem;
atomItem.SaveAsAtom10(xmlWriter);
}
}
}
}
#endif

View File

@@ -1,68 +0,0 @@
#if NET_3_5 && !SILVERLIGHT
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
using System.Xml;
using System.ServiceModel.Syndication;
namespace Spring.Http.Converters.Feed
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write RSS feeds
/// using the <see cref="System.ServiceModel.Syndication.SyndicationFeed"/> class.
/// </summary>
/// <remarks>
/// By default, this converter reads and writes the media type 'application/rss+xml' media type.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Bruno Baia</author>
public class Rss20FeedHttpMessageConverter : AbstractFeedHttpMessageConverter
{
/// <summary>
/// Creates a new instance of the <see cref="Rss20FeedHttpMessageConverter"/>
/// with 'application/rss+xml', 'application/xml' and 'text/xml' media types.
/// </summary>
public Rss20FeedHttpMessageConverter() :
base(new MediaType("application", "rss+xml"), new MediaType("application", "xml"), new MediaType("text", "xml"))
{
}
/// <summary>
/// Abstract template method that writes the actual body using a <see cref="XmlWriter"/>. Invoked from <see cref="M:WriteInternal"/>.
/// </summary>
/// <param name="xmlWriter">The XmlWriter to use.</param>
/// <param name="content">The object to write to the HTTP message.</param>
protected override void WriteXml(XmlWriter xmlWriter, object content)
{
if (content is SyndicationFeed)
{
SyndicationFeed rssFeed = content as SyndicationFeed;
rssFeed.SaveAsRss20(xmlWriter);
}
else if (content is SyndicationItem)
{
SyndicationItem rssItem = content as SyndicationItem;
rssItem.SaveAsRss20(xmlWriter);
}
}
}
}
#endif

View File

@@ -1,195 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Collections.Generic;
using Spring.Util;
namespace Spring.Http.Converters
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can write files.
/// </summary>
/// <remarks>
/// A mapping between file extension and mime types is used to determine the Content-Type of written files.
/// If no Content-Type is available, 'application/octet-stream' is used.
/// </remarks>
/// <author>Bruno Baia</author>
public class FileInfoHttpMessageConverter : IHttpMessageConverter
{
// Pre-defined mapping between file extension and mime types
private static IDictionary<string, string> defaultMimeMapping;
private IList<MediaType> _supportedMediaTypes;
private IDictionary<string, string> _mimeMapping;
/// <summary>
/// Gets or sets the mapping between file extension and mime types.
/// </summary>
public IDictionary<string, string> MimeMapping
{
get
{
if (this._mimeMapping == null)
{
this._mimeMapping = new Dictionary<string, string>(defaultMimeMapping);
}
return _mimeMapping;
}
set { _mimeMapping = value; }
}
static FileInfoHttpMessageConverter()
{
defaultMimeMapping = new Dictionary<string, string>(9, StringComparer.OrdinalIgnoreCase);
defaultMimeMapping.Add(".bmp", "image/bmp");
defaultMimeMapping.Add(".gif", "image/gif");
defaultMimeMapping.Add(".jpg", "image/jpeg");
defaultMimeMapping.Add(".jpeg", "image/jpeg");
defaultMimeMapping.Add(".pdf", "application/pdf");
defaultMimeMapping.Add(".png", "image/png");
defaultMimeMapping.Add(".tif", "image/tiff");
defaultMimeMapping.Add(".txt", "text/plain");
defaultMimeMapping.Add(".zip", "application/x-zip-compressed");
}
/// <summary>
/// Creates a new instance of the <see cref="FileInfoHttpMessageConverter"/>
/// with 'application/octet-stream', and '*/*' media types.
/// </summary>
public FileInfoHttpMessageConverter()
{
this._supportedMediaTypes = new List<MediaType>();
this._supportedMediaTypes.Add(MediaType.APPLICATION_OCTET_STREAM);
this._supportedMediaTypes.Add(MediaType.ALL);
}
#region IHttpMessageConverter Membres
/// <summary>
/// Indicates whether the given class can be read by this converter.
/// </summary>
/// <param name="type">The class to test for readability</param>
/// <param name="mediaType">
/// The media type to read, can be null if not specified. Typically the value of a 'Content-Type' header.
/// </param>
/// <returns><see langword="true"/> if readable; otherwise <see langword="false"/></returns>
public bool CanRead(Type type, MediaType mediaType)
{
return false;
}
/// <summary>
/// Indicates whether the given class can be written by this converter.
/// </summary>
/// <param name="type">The class to test for writability</param>
/// <param name="mediaType">
/// The media type to write, can be null if not specified. Typically the value of an 'Accept' header.
/// </param>
/// <returns><see langword="true"/> if writable; otherwise <see langword="false"/></returns>
public bool CanWrite(Type type, MediaType mediaType)
{
return type.Equals(typeof(FileInfo));
}
/// <summary>
/// Gets the list of <see cref="MediaType"/> objects supported by this converter.
/// </summary>
public IList<MediaType> SupportedMediaTypes
{
get { return this._supportedMediaTypes; }
}
/// <summary>
/// Read an object of the given type form the given HTTP message, and returns it.
/// </summary>
/// <typeparam name="T">
/// The type of object to return. This type must have previously been passed to the
/// <see cref="M:CanRead"/> method of this interface, which must have returned <see langword="true"/>.
/// </typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
public T Read<T>(IHttpInputMessage message) where T : class
{
throw new NotSupportedException();
}
/// <summary>
/// Write an given object to the given HTTP message.
/// </summary>
/// <param name="content">
/// The object to write to the HTTP message. The type of this object must have previously been
/// passed to the <see cref="M:CanWrite"/> method of this interface, which must have returned <see langword="true"/>.
/// </param>
/// <param name="contentType">
/// The content type to use when writing. May be null to indicate that the default content type of the converter must be used.
/// If not null, this media type must have previously been passed to the <see cref="M:CanWrite"/> method of this interface,
/// which must have returned <see langword="true"/>.
/// </param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
public void Write(object content, MediaType contentType, IHttpOutputMessage message)
{
// Get the content type
HttpHeaders headers = message.Headers;
if (headers.ContentType == null)
{
if (contentType == null || contentType.IsWildcardType || contentType.IsWildcardSubtype)
{
contentType = GetContentType(content as FileInfo);
}
if (contentType != null)
{
headers.ContentType = contentType;
}
}
// Write to the message stream
message.Body = delegate(Stream stream)
{
using (FileStream fs = ((FileInfo)content).OpenRead())
{
IoUtils.CopyStream(fs, stream);
}
};
}
#endregion
private MediaType GetContentType(FileInfo file)
{
IDictionary<string, string> mimeMapping =
(this._mimeMapping == null) ? defaultMimeMapping : this._mimeMapping;
string mimeType;
if (mimeMapping.TryGetValue(file.Extension, out mimeType))
{
return MediaType.Parse(mimeType);
}
else
{
return MediaType.APPLICATION_OCTET_STREAM;
}
}
}
}

View File

@@ -1,519 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;
#if SILVERLIGHT
using Spring.Collections.Specialized;
#else
using System.Collections.Specialized;
#endif
using Spring.Util;
namespace Spring.Http.Converters
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can handle form data,
/// including multipart form data (i.e. file uploads).
/// </summary>
/// <remarks>
/// <para>
/// This converter supports the 'application/x-www-form-urlencoded' and 'multipart/form-data' media
/// types, and read the 'application/x-www-form-urlencoded' media type (but not 'multipart/form-data').
/// </para>
/// <para>
/// In other words, this converter can read and write 'normal' HTML forms (as <see cref="NameValueCollection"/>),
/// and it can write multipart form (as <see cref="IDictionary{String,Object}"/>).
/// When writing multipart, this converter uses other <see cref="IHttpMessageConverter"/> to write the respective MIME parts.
/// By default, basic converters are registered (supporting <see cref="String"/> and <see cref="FileInfo"/>, for instance);
/// these can be overridden by setting <see cref="P:PartConverters"/> property.
/// </para>
/// <para>
/// For example, the following snippet shows how to submit an HTML form:
/// <code>
/// RestTemplate template = new RestTemplate(); // FormHttpMessageConverter is configured by default
/// NameValueCollection form = new NameValueCollection();
/// form.Add("field 1", "value 1");
/// form.Add("field 2", "value 2");
/// form.Add("field 2", "value 3");
/// template.PostForLocation("http://example.com/myForm", form);
/// </code>
/// </para>
/// <para>
/// The following snippet shows how to do a file upload:
/// <code>
/// RestTemplate template = new RestTemplate();
/// IDictionary&lt;string, object> parts = new Dictionary&lt;string, object>();
/// parts.Add("field 1", "value 1");
/// parts.Add("file", new FileInfo(@"C:\myFile.jpg"));
/// template.PostForLocation("http://example.com/myFileUpload", parts);
/// </code>
/// </para>
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class FormHttpMessageConverter : IHttpMessageConverter
{
private static char[] BOUNDARY_CHARS =
new char[]{'-', '_', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A',
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z'};
private Random random;
private Encoding _charset;
private IList<MediaType> _supportedMediaTypes;
private IList<IHttpMessageConverter> _partConverters;
/// <summary>
/// Gets or sets the message body converters to use.
/// These converters are used to convert objects to MIME parts.
/// </summary>
public IList<IHttpMessageConverter> PartConverters
{
get { return _partConverters; }
set { _partConverters = value; }
}
/// <summary>
/// Gets or sets the encoding used for writing form data.
/// </summary>
public Encoding Charset
{
get { return this._charset; }
set { _charset = value; }
}
/// <summary>
/// Creates a new instance of the <see cref="FormHttpMessageConverter"/>.
/// </summary>
public FormHttpMessageConverter()
{
this.random = new Random();
#if SILVERLIGHT
this._charset = new UTF8Encoding(false); // Remove byte Order Mask (BOM)
#else
this._charset = Encoding.GetEncoding("ISO-8859-1");
#endif
this._supportedMediaTypes = new List<MediaType>(2);
this._supportedMediaTypes.Add(MediaType.APPLICATION_FORM_URLENCODED);
this._supportedMediaTypes.Add(MediaType.MULTIPART_FORM_DATA);
this._partConverters = new List<IHttpMessageConverter>(3);
this._partConverters.Add(new ByteArrayHttpMessageConverter());
this._partConverters.Add(new StringHttpMessageConverter());
this._partConverters.Add(new FileInfoHttpMessageConverter());
//this._partConverters.Add(new ResourceHttpMessageConverter());
}
#region IHttpMessageConverter Membres
/// <summary>
/// Indicates whether the given class can be read by this converter.
/// </summary>
/// <param name="type">The class to test for readability</param>
/// <param name="mediaType">
/// The media type to read, can be null if not specified. Typically the value of a 'Content-Type' header.
/// </param>
/// <returns><see langword="true"/> if readable; otherwise <see langword="false"/></returns>
public bool CanRead(Type type, MediaType mediaType)
{
if (!typeof(NameValueCollection).IsAssignableFrom(type))
{
return false;
}
if (mediaType != null)
{
return MediaType.APPLICATION_FORM_URLENCODED.Includes(mediaType);
}
return true;
}
/// <summary>
/// Indicates whether the given class can be written by this converter.
/// </summary>
/// <param name="type">The class to test for writability</param>
/// <param name="mediaType">
/// The media type to write, can be null if not specified. Typically the value of an 'Accept' header.
/// </param>
/// <returns><see langword="true"/> if writable; otherwise <see langword="false"/></returns>
public bool CanWrite(Type type, MediaType mediaType)
{
if (!typeof(NameValueCollection).IsAssignableFrom(type) &&
!typeof(IDictionary<string, object>).IsAssignableFrom(type))
{
return false;
}
if (mediaType != null)
{
return MediaType.APPLICATION_FORM_URLENCODED.IsCompatibleWith(mediaType) ||
MediaType.MULTIPART_FORM_DATA.IsCompatibleWith(mediaType);
}
return true;
}
/// <summary>
/// Gets the list of <see cref="MediaType"/> objects supported by this converter.
/// </summary>
public IList<MediaType> SupportedMediaTypes
{
get { return _supportedMediaTypes; }
}
/// <summary>
/// Read an object of the given type form the given HTTP message, and returns it.
/// </summary>
/// <typeparam name="T">
/// The type of object to return. This type must have previously been passed to the
/// <see cref="M:CanRead"/> method of this interface, which must have returned <see langword="true"/>.
/// </typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
public T Read<T>(IHttpInputMessage message) where T : class
{
// Get the message encoding
Encoding encoding;
MediaType mediaType = message.Headers.ContentType;
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = this._charset;
}
else
{
encoding = Encoding.GetEncoding(mediaType.CharSet);
}
// Read from the message stream
string body;
using (StreamReader reader = new StreamReader(message.Body, encoding))
{
body = reader.ReadToEnd();
}
string[] pairs = body.Split('&');
NameValueCollection result = new NameValueCollection(pairs.Length);
foreach (string pair in pairs)
{
int idx = pair.IndexOf('=');
if (idx == -1)
{
result.Add(UrlDecode(pair, this._charset), null);
}
else
{
string name = UrlDecode(pair.Substring(0, idx), this._charset);
string value = UrlDecode(pair.Substring(idx + 1), this._charset);
result.Add(name, value);
}
}
return result as T;
}
/// <summary>
/// Write an given object to the given HTTP message.
/// </summary>
/// <param name="content">
/// The object to write to the HTTP message. The type of this object must have previously been
/// passed to the <see cref="M:CanWrite"/> method of this interface, which must have returned <see langword="true"/>.
/// </param>
/// <param name="contentType">
/// The content type to use when writing. May be null to indicate that the default content type of the converter must be used.
/// If not null, this media type must have previously been passed to the <see cref="M:CanWrite"/> method of this interface,
/// which must have returned <see langword="true"/>.
/// </param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
public void Write(object content, MediaType contentType, IHttpOutputMessage message)
{
if (content is NameValueCollection)
{
this.WriteForm((NameValueCollection) content, message);
}
else if (content is IDictionary<string, object>)
{
this.WriteMultipart((IDictionary<string, object>) content, message);
}
}
#endregion
#region Write Form
private void WriteForm(NameValueCollection form, IHttpOutputMessage message)
{
message.Headers.ContentType = MediaType.APPLICATION_FORM_URLENCODED;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < form.AllKeys.Length; i++)
{
string name = form.AllKeys[i];
string[] values = form.GetValues(name);
if (values == null)
{
builder.Append(UrlEncode(name, this._charset));
}
else
{
for (int j = 0; j < values.Length; j++)
{
string value = values[j];
builder.Append(UrlEncode(name, this._charset));
builder.Append('=');
builder.Append(UrlEncode(value, this._charset));
if (j != (values.Length - 1))
{
builder.Append('&');
}
}
}
if (i != (form.AllKeys.Length - 1))
{
builder.Append('&');
}
}
// Create a byte array of the data we want to send
byte[] byteData = this._charset.GetBytes(builder.ToString());
//#if !SILVERLIGHT
// // Set the content length in the message headers
// message.Headers.ContentLength = byteData.Length;
//#endif
// Write to the message stream
message.Body = delegate(Stream stream)
{
stream.Write(byteData, 0, byteData.Length);
};
}
private static string UrlDecode(string url, Encoding charset)
{
#if WINDOWS_PHONE
return System.Net.HttpUtility.UrlDecode(url);
#elif SILVERLIGHT
return System.Windows.Browser.HttpUtility.UrlDecode(url);
#else
return System.Web.HttpUtility.UrlDecode(url, charset);
#endif
}
private static string UrlEncode(string url, Encoding charset)
{
#if WINDOWS_PHONE
return System.Net.HttpUtility.UrlEncode(url);
#elif SILVERLIGHT
return System.Windows.Browser.HttpUtility.UrlEncode(url);
#else
return System.Web.HttpUtility.UrlEncode(url, charset);
#endif
}
#endregion
#region Write Multipart
private void WriteMultipart(IDictionary<string, object> parts, IHttpOutputMessage message)
{
string boundary = this.GenerateMultipartBoundary();
IDictionary<string, string> parameters = new Dictionary<string, string>(1);
parameters.Add("boundary", boundary);
MediaType contentType = new MediaType(MediaType.MULTIPART_FORM_DATA, parameters);
message.Headers.ContentType = contentType;
message.Body = delegate(Stream stream)
{
using (StreamWriter streamWriter = new StreamWriter(stream))
{
streamWriter.NewLine = "\r\n";
this.WriteParts(boundary, parts, streamWriter);
this.WriteEnd(boundary, streamWriter);
}
};
}
/// <summary>
/// Generates a multipart boundary.
/// </summary>
/// <remarks>
/// Default implementation returns a random boundary. Can be overridden in subclasses.
/// </remarks>
/// <returns>A multipart boundary</returns>
protected virtual string GenerateMultipartBoundary()
{
char[] boundary = new char[random.Next(11) + 30];
for (int i = 0; i < boundary.Length; i++)
{
boundary[i] = BOUNDARY_CHARS[random.Next(BOUNDARY_CHARS.Length)];
}
return new String(boundary);
}
/// <summary>
/// Return the filename of the given multipart part
/// to be used for the 'Content-Disposition' header.
/// </summary>
/// <remarks>
/// Default implementation returns <see cref="P:FileInfo.FullName"/> if the part is a <see cref="FileInfo"/>,
/// and <see langword="null"/> in other cases. Can be overridden in subclasses.
/// </remarks>
/// <param name="part">The part to determine the file name for</param>
/// <returns>The filename, or <see langword="null"/> if not known</returns>
protected virtual string GetMultipartFilename(object part)
{
if (part is FileInfo)
{
return ((FileInfo)part).FullName;
}
return null;
}
private void WriteParts(string boundary, IDictionary<string, object> parts, StreamWriter streamWriter)
{
foreach(KeyValuePair<string, object> entry in parts)
{
this.WriteBoundary(boundary, streamWriter);
HttpEntity entity = this.GetEntity(entry.Value);
this.WritePart(entry.Key, entity, streamWriter);
streamWriter.WriteLine();
}
}
private void WriteBoundary(string boundary, StreamWriter streamWriter)
{
streamWriter.Write("--");
streamWriter.Write(boundary);
streamWriter.WriteLine();
}
private void WritePart(String name, HttpEntity partEntity, StreamWriter streamWriter)
{
object partBody = partEntity.Body;
Type partType = partBody.GetType();
HttpHeaders partHeaders = partEntity.Headers;
MediaType partContentType = partHeaders.ContentType;
foreach (IHttpMessageConverter messageConverter in this._partConverters)
{
if (messageConverter.CanWrite(partType, partContentType))
{
IHttpOutputMessage multipartMessage = new MultipartHttpOutputMessage(streamWriter);
multipartMessage.Headers["Content-Disposition"] = this.GetContentDispositionFormData(name, this.GetMultipartFilename(partBody));
foreach (string header in partHeaders)
{
multipartMessage.Headers[header] = partHeaders[header];
}
messageConverter.Write(partBody, partContentType, multipartMessage);
return;
}
}
throw new HttpMessageNotWritableException(String.Format(
"Could not write request: no suitable HttpMessageConverter found for part type [{0}]", partType));
}
private void WriteEnd(string boundary, StreamWriter streamWriter)
{
streamWriter.Write("--");
streamWriter.Write(boundary);
streamWriter.Write("--");
streamWriter.WriteLine();
}
private HttpEntity GetEntity(object part)
{
if (part is HttpEntity)
{
return (HttpEntity)part;
}
return new HttpEntity(part);
}
/// <summary>
/// Return the value of the 'Content-Disposition' header for 'form-data'.
/// </summary>
/// <param name="name">The field name</param>
/// <param name="filename">The filename, may be <see langwrod="null"/></param>
/// <returns>The value of the 'Content-Disposition' header</returns>
private string GetContentDispositionFormData(string name, string filename)
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("form-data; name=\"{0}\"", name);
if (filename != null)
{
builder.AppendFormat("; filename=\"{0}\"", filename);
}
return builder.ToString();
}
/// <summary>
/// Implementation of <see cref="IHttpOutputMessage"/> used for writing multipart data.
/// </summary>
private sealed class MultipartHttpOutputMessage : IHttpOutputMessage
{
private HttpHeaders headers;
private StreamWriter bodyWriter;
public MultipartHttpOutputMessage(StreamWriter bodyWriter)
{
this.headers = new HttpHeaders();
this.bodyWriter = bodyWriter;
}
#region IHttpMessage Membres
public HttpHeaders Headers
{
get { return this.headers; }
}
public Action<Stream> Body
{
get { throw new InvalidOperationException(); }
set { this.WritePartBody(value); }
}
#endregion
private void WritePartBody(Action<Stream> body)
{
foreach (string header in this.headers)
{
bodyWriter.Write(header);
bodyWriter.Write(": ");
bodyWriter.Write(this.headers[header]);
bodyWriter.WriteLine();
}
bodyWriter.WriteLine();
bodyWriter.Flush();
Stream stream = bodyWriter.BaseStream;
stream.Flush();
body(stream);
stream.Flush();
}
}
#endregion
}
}

View File

@@ -1,86 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Runtime.Serialization;
namespace Spring.Http.Converters
{
/// <summary>
/// Exception thrown by <see cref="IHttpMessageConverter"/> implementations when the conversion fails.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
#if !SILVERLIGHT
[Serializable]
#endif
public class HttpMessageConversionException : Exception
{
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageConversionException"/> class.
/// </summary>
public HttpMessageConversionException()
{
}
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageConversionException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
public HttpMessageConversionException(string message)
: base(message)
{
}
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageConversionException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
/// <param name="rootCause">
/// The root exception that is being wrapped.
/// </param>
public HttpMessageConversionException(string message, Exception rootCause)
: base(message, rootCause)
{
}
#if !SILVERLIGHT
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageConversionException"/> class.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/>
/// that contains contextual information about the source or destination.
/// </param>
protected HttpMessageConversionException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
}
}

View File

@@ -1,87 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Runtime.Serialization;
namespace Spring.Http.Converters
{
/// <summary>
/// Exception thrown by <see cref="IHttpMessageConverter"/> implementations
/// when reading from HTTP message fails.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
#if !SILVERLIGHT
[Serializable]
#endif
public class HttpMessageNotReadableException : HttpMessageConversionException
{
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotReadableException"/> class.
/// </summary>
public HttpMessageNotReadableException()
{
}
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotReadableException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
public HttpMessageNotReadableException(string message)
: base(message)
{
}
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotReadableException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
/// <param name="rootCause">
/// The root exception that is being wrapped.
/// </param>
public HttpMessageNotReadableException(string message, Exception rootCause)
: base(message, rootCause)
{
}
#if !SILVERLIGHT
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotReadableException"/> class.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/>
/// that contains contextual information about the source or destination.
/// </param>
protected HttpMessageNotReadableException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
}
}

View File

@@ -1,87 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Runtime.Serialization;
namespace Spring.Http.Converters
{
/// <summary>
/// Exception thrown by <see cref="IHttpMessageConverter"/> implementations
/// when writing to HTTP message fails.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
#if !SILVERLIGHT
[Serializable]
#endif
public class HttpMessageNotWritableException : HttpMessageConversionException
{
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotWritableException"/> class.
/// </summary>
public HttpMessageNotWritableException()
{
}
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotWritableException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
public HttpMessageNotWritableException(string message)
: base(message)
{
}
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotWritableException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
/// <param name="rootCause">
/// The root exception that is being wrapped.
/// </param>
public HttpMessageNotWritableException(string message, Exception rootCause)
: base(message, rootCause)
{
}
#if !SILVERLIGHT
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageNotWritableException"/> class.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/>
/// that contains contextual information about the source or destination.
/// </param>
protected HttpMessageNotWritableException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
}
}

View File

@@ -1,89 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Collections.Generic;
using System.IO;
namespace Spring.Http.Converters
{
/// <summary>
/// Strategy interface that specifies a converter that can convert from and to HTTP messages.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Juergen Hoeller</author>
/// <author>Bruno Baia (.NET)</author>
public interface IHttpMessageConverter
{
/// <summary>
/// Indicates whether the given class can be read by this converter.
/// </summary>
/// <param name="type">The class to test for readability</param>
/// <param name="mediaType">
/// The media type to read, can be null if not specified. Typically the value of a 'Content-Type' header.
/// </param>
/// <returns><see langword="true"/> if readable; otherwise <see langword="false"/></returns>
bool CanRead(Type type, MediaType mediaType);
/// <summary>
/// Indicates whether the given class can be written by this converter.
/// </summary>
/// <param name="type">The class to test for writability</param>
/// <param name="mediaType">
/// The media type to write, can be null if not specified. Typically the value of an 'Accept' header.
/// </param>
/// <returns><see langword="true"/> if writable; otherwise <see langword="false"/></returns>
bool CanWrite(Type type, MediaType mediaType);
/// <summary>
/// Gets the list of <see cref="MediaType"/> objects supported by this converter.
/// </summary>
IList<MediaType> SupportedMediaTypes { get; }
/// <summary>
/// Read an object of the given type form the given HTTP message, and returns it.
/// </summary>
/// <typeparam name="T">
/// The type of object to return. This type must have previously been passed to the
/// <see cref="M:CanRead"/> method of this interface, which must have returned <see langword="true"/>.
/// </typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
T Read<T>(IHttpInputMessage message) where T : class;
/// <summary>
/// Write an given object to the given HTTP message.
/// </summary>
/// <param name="content">
/// The object to write to the HTTP message. The type of this object must have previously been
/// passed to the <see cref="M:CanWrite"/> method of this interface, which must have returned <see langword="true"/>.
/// </param>
/// <param name="contentType">
/// The content type to use when writing. May be null to indicate that the default content type of the converter must be used.
/// If not null, this media type must have previously been passed to the <see cref="M:CanWrite"/> method of this interface,
/// which must have returned <see langword="true"/>.
/// </param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
void Write(object content, MediaType contentType, IHttpOutputMessage message);
}
}

View File

@@ -1,153 +0,0 @@
#if NET_3_5 || WINDOWS_PHONE
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;
using Spring.Util;
namespace Spring.Http.Converters.Json
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write JSON.
/// </summary>
/// <remarks>
/// By default, this converter supports 'application/json' media type.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Bruno Baia</author>
public class JsonHttpMessageConverter : AbstractHttpMessageConverter
{
/// <summary>
/// Default encoding for JSON.
/// </summary>
public static readonly Encoding DEFAULT_CHARSET = new UTF8Encoding(false); // Remove byte Order Mask (BOM)
private IEnumerable<Type> _knownTypes;
/// <summary>
/// Gets or sets types that may be present in the object graph.
/// </summary>
public IEnumerable<Type> KnownTypes
{
get { return _knownTypes; }
set { _knownTypes = value; }
}
/// <summary>
/// Creates a new instance of the <see cref="JsonHttpMessageConverter"/>
/// with the media type 'application/json'.
/// </summary>
public JsonHttpMessageConverter() :
base(new MediaType("application", "json"))
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return true;
}
/// <summary>
/// Abstract template method that reads the actualy object. Invoked from <see cref="M:Read"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
protected override T ReadInternal<T>(IHttpInputMessage message)
{
DataContractJsonSerializer serializer = this.GetSerializer(typeof(T));
return (T)serializer.ReadObject(message.Body) as T;
}
/// <summary>
/// Abstract template method that writes the actual body. Invoked from <see cref="M:Write"/>.
/// </summary>
/// <param name="content">The object to write to the HTTP message.</param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
protected override void WriteInternal(object content, IHttpOutputMessage message)
{
#if SILVERLIGHT
// Write to the message stream
message.Body = delegate(Stream stream)
{
DataContractJsonSerializer serializer = this.GetSerializer(content.GetType());
serializer.WriteObject(stream, content);
};
#else
// Get the message encoding
Encoding encoding;
MediaType mediaType = message.Headers.ContentType;
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = DEFAULT_CHARSET;
}
else
{
encoding = Encoding.GetEncoding(mediaType.CharSet);
}
DataContractJsonSerializer serializer = this.GetSerializer(content.GetType());
// Write to the message stream
message.Body = delegate(Stream stream)
{
// Using JsonReaderWriterFactory directly to set encoding
using (XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, encoding, false))
{
serializer.WriteObject(jsonWriter, content);
}
};
#endif
}
/// <summary>
/// Creates an instance of <see cref="DataContractJsonSerializer"/> to
/// serialize or deserialize an object of the specified type.
/// </summary>
/// <param name="type">The type of instances to serialize or deserialize.</param>
/// <returns>The serializer to use.</returns>
protected virtual DataContractJsonSerializer GetSerializer(Type type)
{
if (this._knownTypes == null)
{
return new DataContractJsonSerializer(type);
}
else
{
return new DataContractJsonSerializer(type, this._knownTypes);
}
}
}
}
#endif

View File

@@ -1,137 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Text;
using Spring.Util;
namespace Spring.Http.Converters
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write strings.
/// </summary>
/// <remarks>
/// By default, this converter supports all media types '*/*', and writes with a 'Content-Type'
/// of 'text/plain'.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class StringHttpMessageConverter : AbstractHttpMessageConverter
{
/// <summary>
/// Default encoding for strings.
/// </summary>
#if SILVERLIGHT
public static readonly Encoding DEFAULT_CHARSET = new UTF8Encoding(false); // Remove byte Order Mask (BOM)
#else
public static readonly Encoding DEFAULT_CHARSET = Encoding.GetEncoding("ISO-8859-1");
#endif
/// <summary>
/// Creates a new instance of the <see cref="ByteArrayHttpMessageConverter"/>
/// with 'text/plain; charset=ISO-8859-1', and '*/*' media types.
/// </summary>
public StringHttpMessageConverter() :
#if SILVERLIGHT
base(new MediaType("text", "plain", "UTF-8"), MediaType.ALL)
#else
base(new MediaType("text", "plain", "ISO-8859-1"), MediaType.ALL)
#endif
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return type.Equals(typeof(string));
}
/// <summary>
/// Abstract template method that reads the actualy object. Invoked from <see cref="M:Read"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
protected override T ReadInternal<T>(IHttpInputMessage message)
{
// Get the message encoding
Encoding encoding;
MediaType mediaType = message.Headers.ContentType;
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = DEFAULT_CHARSET;
}
else
{
encoding = Encoding.GetEncoding(mediaType.CharSet);
}
// Read from the message stream
using (StreamReader reader = new StreamReader(message.Body, encoding))
{
return reader.ReadToEnd() as T;
}
}
/// <summary>
/// Abstract template method that writes the actual body. Invoked from <see cref="M:Write"/>.
/// </summary>
/// <param name="content">The object to write to the HTTP message.</param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
protected override void WriteInternal(object content, IHttpOutputMessage message)
{
// Get the message encoding
Encoding encoding;
MediaType mediaType = message.Headers.ContentType;
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = DEFAULT_CHARSET;
}
else
{
encoding = Encoding.GetEncoding(mediaType.CharSet);
}
// Create a byte array of the data we want to send
byte[] byteData = encoding.GetBytes(content as string);
//#if !SILVERLIGHT
// // Set the content length in the message headers
// message.Headers.ContentLength = byteData.Length;
//#endif
// Write to the message stream
message.Body = delegate(Stream stream)
{
stream.Write(byteData, 0, byteData.Length);
};
}
}
}

View File

@@ -1,160 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.IO;
using System.Xml;
using System.Net;
using System.Text;
using Spring.Util;
namespace Spring.Http.Converters.Xml
{
/// <summary>
/// Base class for <see cref="IHttpMessageConverter"/> that convert from/to XML.
/// </summary>
/// <remarks>
/// By default, subclasses of this converter support 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Bruno Baia</author>
public abstract class AbstractXmlHttpMessageConverter : AbstractHttpMessageConverter
{
/// <summary>
/// Default encoding for XML.
/// </summary>
public static readonly Encoding DEFAULT_CHARSET = new UTF8Encoding(false); // Remove byte Order Mask (BOM)
/// <summary>
/// Creates a new instance of the <see cref="AbstractHttpMessageConverter"/>
/// with multiple supported media type.
/// </summary>
/// <param name="supportedMediaTypes">The supported media types.</param>
protected AbstractXmlHttpMessageConverter(params MediaType[] supportedMediaTypes) :
base(supportedMediaTypes)
{
}
/// <summary>
/// Creates a new instance of the <see cref="AbstractHttpMessageConverter"/> that sets
/// the <see cref="P:SupportedMediaTypes"/> to 'text/xml' and 'application/xml', and 'application/*-xml'.
/// </summary>
protected AbstractXmlHttpMessageConverter() :
base(new MediaType("application", "xml"), new MediaType("text", "xml"), new MediaType("application", "*+xml"))
{
}
/// <summary>
/// Abstract template method that reads the actualy object. Invoked from <see cref="M:Read"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="message">The HTTP message to read from.</param>
/// <returns>The converted object.</returns>
/// <exception cref="HttpMessageNotReadableException">In case of conversion errors</exception>
protected override T ReadInternal<T>(IHttpInputMessage message)
{
XmlReaderSettings settings = this.GetXmlReaderSettings();
// Read from the message stream
using (XmlReader xmlReader = XmlReader.Create(message.Body, settings))
{
return ReadXml<T>(xmlReader);
}
}
/// <summary>
/// Abstract template method that writes the actual body. Invoked from <see cref="M:Write"/>.
/// </summary>
/// <param name="content">The object to write to the HTTP message.</param>
/// <param name="message">The HTTP message to write to.</param>
/// <exception cref="HttpMessageNotWritableException">In case of conversion errors</exception>
protected override void WriteInternal(object content, IHttpOutputMessage message)
{
// Get the message encoding
Encoding encoding;
MediaType mediaType = message.Headers.ContentType;
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = DEFAULT_CHARSET;
}
else
{
encoding = Encoding.GetEncoding(mediaType.CharSet);
}
XmlWriterSettings settings = this.GetXmlWriterSettings();
settings.Encoding = encoding;
// Write to the message stream
message.Body = delegate(Stream stream)
{
using (XmlWriter xmlWriter = XmlWriter.Create(stream, settings))
{
WriteXml(xmlWriter, content);
}
};
}
/// <summary>
/// Abstract template method that reads the actualy object using a <see cref="XmlReader"/>. Invoked from <see cref="M:ReadInternal"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="xmlReader">The XmlReader to use.</param>
/// <returns>The converted object.</returns>
protected abstract T ReadXml<T>(XmlReader xmlReader) where T : class;
/// <summary>
/// Abstract template method that writes the actual body using a <see cref="XmlWriter"/>. Invoked from <see cref="M:WriteInternal"/>.
/// </summary>
/// <param name="xmlWriter">The XmlWriter to use.</param>
/// <param name="content">The object to write to the HTTP message.</param>
protected abstract void WriteXml(XmlWriter xmlWriter, object content);
/// <summary>
/// Returns the <see cref="XmlReaderSettings">XmlReader settings</see>
/// used by this converter to read from the HTTP message.
/// </summary>
/// <returns>The XmlReader settings.</returns>
protected virtual XmlReaderSettings GetXmlReaderSettings()
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.CloseInput = true;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreWhitespace = true;
return settings;
}
/// <summary>
/// Returns the <see cref="XmlWriterSettings">XmlWriter settings</see>
/// used by this converter to write to the HTTP message.
/// </summary>
/// <returns>The XmlWriter settings.</returns>
protected virtual XmlWriterSettings GetXmlWriterSettings()
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.CloseOutput = false;
settings.NewLineHandling = NewLineHandling.Entitize;
settings.OmitXmlDeclaration = true;
settings.CheckCharacters = false;
return settings;
}
}
}

View File

@@ -1,122 +0,0 @@
#if NET_3_0 || SILVERLIGHT
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Xml;
using System.Runtime.Serialization;
using System.Collections.Generic;
namespace Spring.Http.Converters.Xml
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write XML
/// using <see cref="DataContractSerializer"/>.
/// </summary>
/// <remarks>
/// <para>
/// By default, this converter supports 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </para>
/// <para>
/// This converter can read classes annotated with <see cref="DataContractAttribute"/> and <see cref="CollectionDataContractAttribute"/>, and write classes
/// annotated with with {@link XmlRootElement}, or subclasses thereof.
/// </para>
/// </remarks>
/// <author>Bruno Baia</author>
public class DataContractHttpMessageConverter : AbstractXmlHttpMessageConverter
{
private IEnumerable<Type> _knownTypes;
/// <summary>
/// Gets or sets types that may be present in the object graph.
/// </summary>
public IEnumerable<Type> KnownTypes
{
get { return _knownTypes; }
set { _knownTypes = value; }
}
/// <summary>
/// Creates a new instance of the <see cref="DataContractHttpMessageConverter"/>
/// with 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// </summary>
public DataContractHttpMessageConverter() :
base()
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return (
Attribute.GetCustomAttributes(type, typeof(DataContractAttribute), true).Length > 0 ||
Attribute.GetCustomAttributes(type, typeof(CollectionDataContractAttribute), true).Length > 0
);
}
/// <summary>
/// Abstract template method that reads the actualy object using a <see cref="XmlReader"/>. Invoked from <see cref="M:ReadInternal"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="xmlReader">The XmlReader to use.</param>
/// <returns>The converted object.</returns>
protected override T ReadXml<T>(XmlReader xmlReader)
{
DataContractSerializer serializer = this.GetSerializer(typeof(T));
return serializer.ReadObject(xmlReader) as T;
}
/// <summary>
/// Abstract template method that writes the actual body using a <see cref="XmlWriter"/>. Invoked from <see cref="M:WriteInternal"/>.
/// </summary>
/// <param name="xmlWriter">The XmlWriter to use.</param>
/// <param name="content">The object to write to the HTTP message.</param>
protected override void WriteXml(XmlWriter xmlWriter, object content)
{
DataContractSerializer serializer = this.GetSerializer(content.GetType());
serializer.WriteObject(xmlWriter, content);
}
/// <summary>
/// Creates an instance of <see cref="DataContractSerializer"/> to
/// serialize or deserialize an object of the specified type.
/// </summary>
/// <param name="type">The type of instances to serialize or deserialize.</param>
/// <returns>The serializer to use.</returns>
protected virtual DataContractSerializer GetSerializer(Type type)
{
if (this._knownTypes == null)
{
return new DataContractSerializer(type);
}
else
{
return new DataContractSerializer(type, this._knownTypes);
}
}
}
}
#endif

View File

@@ -1,82 +0,0 @@
#if NET_3_5 || WINDOWS_PHONE
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Xml;
using System.Xml.Linq;
namespace Spring.Http.Converters.Xml
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write XML
/// from a <see cref="XElement"/> (Linq to XML).
/// </summary>
/// <remarks>
/// By default, this converter supports 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Bruno Baia</author>
public class XElementHttpMessageConverter : AbstractXmlHttpMessageConverter
{
/// <summary>
/// Creates a new instance of the <see cref="XElementHttpMessageConverter"/>
/// with 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// </summary>
public XElementHttpMessageConverter() :
base()
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return type.Equals(typeof(XElement));
}
/// <summary>
/// Abstract template method that reads the actualy object using a <see cref="XmlReader"/>. Invoked from <see cref="M:ReadInternal"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="xmlReader">The XmlReader to use.</param>
/// <returns>The converted object.</returns>
protected override T ReadXml<T>(XmlReader xmlReader)
{
return XElement.Load(xmlReader) as T;
}
/// <summary>
/// Abstract template method that writes the actual body using a <see cref="XmlWriter"/>. Invoked from <see cref="M:WriteInternal"/>.
/// </summary>
/// <param name="xmlWriter">The XmlWriter to use.</param>
/// <param name="content">The object to write to the HTTP message.</param>
protected override void WriteXml(XmlWriter xmlWriter, object content)
{
XElement xElement = content as XElement;
xElement.WriteTo(xmlWriter);
}
}
}
#endif

View File

@@ -1,83 +0,0 @@
#if !SILVERLIGHT
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Xml;
using System.Net;
namespace Spring.Http.Converters.Xml
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write XML
/// from a <see cref="XmlDocument"/>.
/// </summary>
/// <remarks>
/// By default, this converter supports 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Bruno Baia</author>
public class XmlDocumentHttpMessageConverter : AbstractXmlHttpMessageConverter
{
/// <summary>
/// Creates a new instance of the <see cref="XmlDocumentHttpMessageConverter"/>
/// with 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// </summary>
public XmlDocumentHttpMessageConverter() :
base()
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return type.Equals(typeof(XmlDocument));
}
/// <summary>
/// Abstract template method that reads the actualy object using a <see cref="XmlReader"/>. Invoked from <see cref="M:ReadInternal"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="xmlReader">The XmlReader to use.</param>
/// <returns>The converted object.</returns>
protected override T ReadXml<T>(XmlReader xmlReader)
{
XmlDocument document = new XmlDocument();
document.Load(xmlReader);
return document as T;
}
/// <summary>
/// Abstract template method that writes the actual body using a <see cref="XmlWriter"/>. Invoked from <see cref="M:WriteInternal"/>.
/// </summary>
/// <param name="xmlWriter">The XmlWriter to use.</param>
/// <param name="content">The object to write to the HTTP message.</param>
protected override void WriteXml(XmlWriter xmlWriter, object content)
{
XmlDocument document = content as XmlDocument;
document.WriteTo(xmlWriter);
}
}
}
#endif

View File

@@ -1,115 +0,0 @@
#if !SILVERLIGHT || WINDOWS_PHONE
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Xml;
using System.Xml.Serialization;
namespace Spring.Http.Converters.Xml
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write XML
/// using <see cref="XmlSerializer"/>.
/// </summary>
/// <remarks>
/// By default, this converter supports 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </remarks>
/// <author>Bruno Baia</author>
public class XmlSerializableHttpMessageConverter : AbstractXmlHttpMessageConverter
{
private Type[] _knownTypes;
/// <summary>
/// Gets or sets types that may be present in the object graph.
/// </summary>
public Type[] KnownTypes
{
get { return _knownTypes; }
set { _knownTypes = value; }
}
/// <summary>
/// Creates a new instance of the <see cref="XmlSerializableHttpMessageConverter"/>
/// with 'text/xml', 'application/xml', and 'application/*-xml' media types.
/// </summary>
public XmlSerializableHttpMessageConverter() :
base()
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return true;
//return (
// AttributeUtils.FindAttribute(type, typeof(XmlRootAttribute)) != null ||
// AttributeUtils.FindAttribute(type, typeof(XmlTypeAttribute)) != null);
}
/// <summary>
/// Abstract template method that reads the actualy object using a <see cref="XmlReader"/>. Invoked from <see cref="M:ReadInternal"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="xmlReader">The XmlReader to use.</param>
/// <returns>The converted object.</returns>
protected override T ReadXml<T>(XmlReader xmlReader)
{
XmlSerializer serializer = this.GetSerializer(typeof(T));
return serializer.Deserialize(xmlReader) as T;
}
/// <summary>
/// Abstract template method that writes the actual body using a <see cref="XmlWriter"/>. Invoked from <see cref="M:WriteInternal"/>.
/// </summary>
/// <param name="xmlWriter">The XmlWriter to use.</param>
/// <param name="content">The object to write to the HTTP message.</param>
protected override void WriteXml(XmlWriter xmlWriter, object content)
{
XmlSerializer serializer = this.GetSerializer(content.GetType());
serializer.Serialize(xmlWriter, content);
}
/// <summary>
/// Creates an instance of <see cref="XmlSerializer"/> to
/// serialize or deserialize an object of the specified type.
/// </summary>
/// <param name="type">The type of instances to serialize or deserialize.</param>
/// <returns>The serializer to use.</returns>
protected virtual XmlSerializer GetSerializer(Type type)
{
if (this._knownTypes == null)
{
return new XmlSerializer(type);
}
else
{
return new XmlSerializer(type, this._knownTypes);
}
}
}
}
#endif

View File

@@ -1,68 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
namespace Spring.Http
{
/// <summary>
/// Represents a HTTP entity message, as defined in the HTTP specification.
/// <a href="http://tools.ietf.org/html/rfc2616#section-7">HTTP 1.1, section 7</a>
/// </summary>
/// <author>Bruno Baia</author>
public class HttpEntity : HttpEntity<object>
{
/// <summary>
/// Creates a new, empty instance of <see cref="HttpEntity"/> with no body or headers.
/// </summary>
public HttpEntity()
: base()
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpEntity"/> with the given body.
/// </summary>
/// <param name="body">The entity body.</param>
public HttpEntity(object body) :
base(body)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpEntity"/> with the given headers.
/// </summary>
/// <param name="headers">The entity headers.</param>
public HttpEntity(HttpHeaders headers) :
base(headers)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpEntity"/> with the given body and headers.
/// </summary>
/// <param name="body">The entity body.</param>
/// <param name="headers">The entity headers.</param>
public HttpEntity(object body, HttpHeaders headers) :
base(body, headers)
{
}
}
}

View File

@@ -1,103 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
using Spring.Util;
namespace Spring.Http
{
/// <summary>
/// Represents a HTTP entity message, as defined in the HTTP specification.
/// <a href="http://tools.ietf.org/html/rfc2616#section-7">HTTP 1.1, section 7</a>
/// </summary>
/// <typeparam name="T">The type of the entity body.</typeparam>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class HttpEntity<T> where T : class
{
private HttpHeaders headers;
private T body;
/// <summary>
/// Gets the entity headers.
/// </summary>
public HttpHeaders Headers
{
get { return this.headers; }
}
/// <summary>
/// Gets the entity body. May be null.
/// </summary>
public T Body
{
get { return this.body; }
}
/// <summary>
/// Indicates whether this entity has a body.
/// </summary>
/// <returns></returns>
public bool HasBody
{
get { return (this.body != null); }
}
/// <summary>
/// Creates a new, empty instance of <see cref="HttpEntity{T}"/> with no body or headers.
/// </summary>
public HttpEntity()
: this(null, new HttpHeaders())
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpEntity{T}"/> with the given body.
/// </summary>
/// <param name="body">The entity body.</param>
public HttpEntity(T body)
: this(body, new HttpHeaders())
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpEntity{T}"/> with the given headers.
/// </summary>
/// <param name="headers">The entity headers.</param>
public HttpEntity(HttpHeaders headers)
: this(null, headers)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpEntity{T}"/> with the given body and headers.
/// </summary>
/// <param name="body">The entity body.</param>
/// <param name="headers">The entity headers.</param>
public HttpEntity(T body, HttpHeaders headers)
{
AssertUtils.ArgumentNotNull(headers, "headers");
this.body = body;
this.headers = headers;
}
}
}

View File

@@ -1,503 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Globalization;
using System.Collections.Generic;
using Spring.Util;
#if SILVERLIGHT
using Spring.Collections.Specialized;
#else
using System.Collections.Specialized;
#endif
namespace Spring.Http
{
/// <summary>
/// Represents HTTP request and response headers, mapping string header names to list of string values.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class HttpHeaders : NameValueCollection
{
private const string ACCEPT = "Accept";
private const string ACCEPT_CHARSET = "Accept-Charset";
private const string ALLOW = "Allow";
private const string CACHE_CONTROL = "Cache-Control";
private const string CONTENT_LENGTH = "Content-Length";
private const string CONTENT_TYPE = "Content-Type";
private const string DATE = "Date";
private const string ETAG = "ETag";
private const string EXPIRES = "Expires";
private const string IF_MODIFIED_SINCE = "If-Modified-Since";
private const string IF_NONE_MATCH = "If-None-Match";
private const string LAST_MODIFIED = "Last-Modified";
private const string LOCATION = "Location";
private const string PRAGMA = "Pragma";
private static readonly DateTimeFormatInfo DateTimeFormatInfo = new DateTimeFormatInfo();
#region Constructor(s)
/// <summary>
/// Creates a new, empty instance of the <see cref="HttpHeaders"/> object.
/// </summary>
public HttpHeaders() :
base(8, StringComparer.OrdinalIgnoreCase)
{
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the array of acceptable <see cref="MediaType">media types</see>,
/// as specified by the 'Accept' header.
/// </summary>
/// <remarks>
/// Returns an empty array when the acceptable media types are unspecified.
/// </remarks>
public MediaType[] Accept
{
get
{
string[] values = this.GetMultiValues(ACCEPT);
if (values == null || values.Length == 0)
{
return new MediaType[0];
}
else
{
MediaType[] result = new MediaType[values.Length];
for (int i = 0; i < values.Length; i++)
{
result[i] = MediaType.Parse(values[i]);
}
return result;
}
}
set
{
foreach (MediaType mediaType in value)
{
this.Add(ACCEPT, mediaType.ToString());
}
}
}
//**
// * Set the list of acceptable {@linkplain Charset charsets}, as specified by the {@code Accept-Charset} header.
// * @param acceptableCharsets the acceptable charsets
// */
//public void setAcceptCharset(List<Charset> acceptableCharsets) {
// StringBuilder builder = new StringBuilder();
// for (Iterator<Charset> iterator = acceptableCharsets.iterator(); iterator.hasNext();) {
// Charset charset = iterator.next();
// builder.append(charset.name().toLowerCase(Locale.ENGLISH));
// if (iterator.hasNext()) {
// builder.append(", ");
// }
// }
// set(ACCEPT_CHARSET, builder.toString());
//}
//**
// * Return the list of acceptable {@linkplain Charset charsets}, as specified by the {@code Accept-Charset}
// * header.
// * @return the acceptable charsets
// */
//public List<Charset> getAcceptCharset() {
// List<Charset> result = new ArrayList<Charset>();
// String value = getFirst(ACCEPT_CHARSET);
// if (value != null) {
// String[] tokens = value.split(",\\s*");
// for (String token : tokens) {
// int paramIdx = token.indexOf(';');
// if (paramIdx == -1) {
// result.add(Charset.forName(token));
// }
// else {
// result.add(Charset.forName(token.substring(0, paramIdx)));
// }
// }
// }
// return result;
//}
/// <summary>
/// Gets or sets the array of allowed <see cref="HttpMethod">HTTP methods</see>,
/// as specified by the 'Allow' header.
/// </summary>
/// <remarks>
/// Returns an empty array when the allowed methods are unspecified.
/// </remarks>
public HttpMethod[] Allow
{
get
{
string[] values = this.GetMultiValues(ALLOW);
if (values == null || values.Length == 0)
{
return new HttpMethod[0];
}
else
{
HttpMethod[] result = new HttpMethod[values.Length];
for (int i = 0; i < values.Length; i++)
{
result[i] = (HttpMethod)Enum.Parse(typeof(HttpMethod), values[i], true);
}
return result;
}
}
set
{
foreach (HttpMethod method in value)
{
this.Add(ALLOW, method.ToString());
}
}
}
/// <summary>
/// Gets or sets the value of the 'Cache-Control' header.
/// </summary>
public string CacheControl
{
get
{
return this.Get(CACHE_CONTROL);
}
set
{
this.Set(CACHE_CONTROL, value);
}
}
/// <summary>
/// Gets or sets the length of the body in bytes,
/// as specified by the 'Content-Length' header.
/// </summary>
/// <remarks>
/// Returns -1 when the content-length is unknown.
/// </remarks>
public long ContentLength
{
get
{
string value = this.GetSingleValue(CONTENT_LENGTH);
return (value != null ? long.Parse(value) : -1);
}
set
{
this.Set(CONTENT_LENGTH, value.ToString());
}
}
/// <summary>
/// Gets or sets the <see cref="MediaType">media type</see> of the body,
/// as specified by the 'Content-Type' header.
/// </summary>
/// <remarks>
/// Returns <see langword="null"/> when the content type is unknown.
/// </remarks>
public MediaType ContentType
{
get
{
string value = this.GetSingleValue(CONTENT_TYPE);
return (value != null ? MediaType.Parse(value) : null);
}
set
{
if (value.IsWildcardType)
{
throw new ArgumentException("'Content-Type' header cannot contain wildcard type '*'", "Content-Type");
}
if (value.IsWildcardSubtype)
{
throw new ArgumentException("'Content-Type' header cannot contain wildcard subtype '*'", "Content-Type");
}
this.Set(CONTENT_TYPE, value.ToString());
}
}
//**
// * Returns the date and time at which the message was created, as specified by the {@code Date} header.
// * <p>The date is returned as the number of milliseconds since January 1, 1970 GMT. Returns -1 when the date is unknown.
// * @return the creation date/time
// * @throws IllegalArgumentException if the value can't be converted to a date
// */
//**
// * Sets the date and time at which the message was created, as specified by the {@code Date} header.
// * <p>The date should be specified as the number of milliseconds since January 1, 1970 GMT.
// * @param date the date
// */
/// <summary>
/// Gets or sets the date and time at which the message was created,
/// as specified by the 'Date' header.
/// </summary>
/// <remarks>
/// Returns <see langword="null"/> when the date is unknown.
/// </remarks>
public DateTime? Date
{
get
{
return this.GetSingleDate(DATE);
}
set
{
this.SetDate(DATE, value);
}
}
/// <summary>
/// Gets or sets the entity tag of the body, as specified by the 'ETag' header.
/// </summary>
public string ETag
{
get
{
return this.Unquote(this.Get(ETAG));
}
set
{
this.Set(ETAG, this.Quote(value));
}
}
/// <summary>
/// Gets or sets the date and time at which the message is no longer valid,
/// as specified by the 'Expires' header.
/// </summary>
public string Expires
{
get
{
return this.Get(EXPIRES);
}
set
{
this.Set(EXPIRES, value);
}
}
/// <summary>
/// Gets or sets the date and time as specified by the 'If-Modified-Since' header.
/// </summary>
/// <remarks>
/// Returns <see langword="null"/> when the date is unknown.
/// </remarks>
public DateTime? IfModifiedSince
{
get
{
return this.GetSingleDate(IF_MODIFIED_SINCE);
}
set
{
this.SetDate(IF_MODIFIED_SINCE, value);
}
}
/// <summary>
/// Gets or sets the value of the 'If-None-Match' header.
/// </summary>
public string[] IfNoneMatch
{
get
{
string[] values = this.GetMultiValues(IF_NONE_MATCH);
if (values == null || values.Length == 0)
{
return new string[0];
}
else
{
string[] result = new string[values.Length];
for (int i = 0; i < values.Length; i++)
{
result[i] = Unquote(values[i]);
}
return result;
}
}
set
{
foreach (string str in value)
{
this.Add(IF_NONE_MATCH, this.Quote(str));
}
}
}
/// <summary>
/// Gets or sets the time the resource was last changed,
/// as specified by the 'Last-Modified' header.
/// </summary>
/// <remarks>
/// Returns <see langword="null"/> when the date is unknown.
/// </remarks>
public DateTime? LastModified
{
get
{
return this.GetSingleDate(LAST_MODIFIED);
}
set
{
this.SetDate(LAST_MODIFIED, value);
}
}
/// <summary>
/// Gets or sets the (new) location of a resource,
/// as specified by the 'Location' header.
/// </summary>
public Uri Location
{
get
{
string value = this.GetSingleValue(LOCATION);
return (value != null ? new Uri(value, UriKind.RelativeOrAbsolute) : null);
}
set
{
this.Set(LOCATION, value.ToString());
}
}
/// <summary>
/// Gets or sets the value of the 'Pragma' header.
/// </summary>
public string Pragma
{
get
{
return this.Get(PRAGMA);
}
set
{
this.Set(PRAGMA, value);
}
}
#endregion
#region Private methods
private string Quote(string s)
{
if (s == null)
{
return null;
}
if (!s.StartsWith("\"") && !s.EndsWith("\""))
{
s = "\"" + s + "\"";
}
return s;
}
private string Unquote(string s)
{
if (s == null)
{
return null;
}
if (s.StartsWith("\"") && s.EndsWith("\""))
{
s = s.Substring(1, s.Length - 2);
}
return s;
}
private DateTime? GetSingleDate(string headerName)
{
string headerValue = GetSingleValue(headerName);
if (headerValue != null)
{
return DateTime.Parse(headerValue, DateTimeFormatInfo).ToUniversalTime();
}
else
{
return null;
}
}
private void SetDate(string headerName, DateTime? date)
{
if (date.HasValue)
{
this.Set(headerName, date.Value.ToUniversalTime().ToString("R", DateTimeFormatInfo));
}
else
{
this.Remove(headerName);
}
}
#endregion
/// <summary>
/// Return the header value for the given header name, if any.
/// </summary>
/// <param name="headerName">The header name</param>
/// <returns>The first header value; or <see langword="null"/></returns>
/// <exception cref="NotSupportedException">
/// If multiple values are stored for the given header name.
/// </exception>
public string GetSingleValue(string headerName)
{
string[] headerValues = this.GetValues(headerName);
if (headerValues == null || headerValues.Length == 0)
{
return null;
}
if (headerValues.Length == 1)
{
return headerValues[0];
}
throw new NotSupportedException(String.Format(
"Multiple values not supported for header '{0}'", headerName));
}
/// <summary>
/// Return an array of header values for the given header name, if any.
/// </summary>
/// <param name="headerName">The header name</param>
/// <returns>The array of header values; or <see langword="null"/></returns>
public string[] GetMultiValues(string headerName)
{
string headerValue = this.Get(headerName);
if (headerValue == null)
{
return null;
}
else
{
return headerValue.Split(',');
}
}
}
}

View File

@@ -1,71 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
namespace Spring.Http
{
/// <summary>
/// Enumeration of HTTP request methods as defined in the HTTP specification.
/// <a href="http://tools.ietf.org/html/rfc2616#section-5.1.1">HTTP 1.1, section 6</a>
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public enum HttpMethod
{
/// <summary>
/// The OPTIONS method.
/// </summary>
OPTIONS,
/// <summary>
/// The GET method.
/// </summary>
GET,
/// <summary>
/// The HEAD method.
/// </summary>
HEAD,
/// <summary>
/// The POST method.
/// </summary>
POST,
/// <summary>
/// The PUT method.
/// </summary>
PUT,
/// <summary>
/// The DELETE method.
/// </summary>
DELETE,
/// <summary>
/// The TRACE method.
/// </summary>
TRACE,
/// <summary>
/// The CONNECT method.
/// </summary>
CONNECT
}
}

View File

@@ -1,145 +0,0 @@
#region License
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
namespace Spring.Http
{
/// <summary>
/// Represents a HTTP request message, as defined in the HTTP specification.
/// <a href="http://tools.ietf.org/html/rfc2616#section-5">HTTP 1.1, section 5</a>
/// </summary>
/// <author>Bruno Baia</author>
public class HttpRequestMessage
{
//private string requestUri;
//private string httpVersion;
private HttpMethod method;
private WebHeaderCollection headers;
private object body;
//public string RequestUri
//{
// get { return this.requestUri; }
// set { this.requestUri = value; }
//}
//public string HttpVersion
//{
// get { return httpVersion; }
// set { httpVersion = value; }
//}
/// <summary>
/// Gets the HTTP method.
/// </summary>
public HttpMethod Method
{
get { return this.method; }
set { this.method = value; }
}
/// <summary>
/// Gets the request headers.
/// </summary>
public WebHeaderCollection Headers
{
get { return this.headers; }
}
/// <summary>
/// Gets the response body.
/// </summary>
public object Body
{
get { return this.body; }
}
/// <summary>
/// Creates a new instance of <see cref="HttpRequestMessage"/> with the given Http method.
/// </summary>
/// <param name="method">The HTTP method.</param>
public HttpRequestMessage(HttpMethod method) :
this(null, new WebHeaderCollection(), method)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpRequestMessage"/> with the given headers.
/// </summary>
/// <param name="headers">The request headers.</param>
public HttpRequestMessage(WebHeaderCollection headers) :
this(null, headers, HttpMethod.GET)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpRequestMessage"/> with the given headers and HTTP method.
/// </summary>
/// <param name="headers">The request headers.</param>
/// <param name="method">The HTTP method.</param>
public HttpRequestMessage(WebHeaderCollection headers, HttpMethod method) :
this(null, headers, method)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpRequestMessage"/> with the given body.
/// </summary>
/// <param name="body">The response body.</param>
public HttpRequestMessage(object body) :
this(body, new WebHeaderCollection(), HttpMethod.GET)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpRequestMessage"/> with the given body and HTTP method.
/// </summary>
/// <param name="body">The response body.</param>
/// <param name="method">The HTTP method.</param>
public HttpRequestMessage(object body, HttpMethod method) :
this(body, new WebHeaderCollection(), method)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpRequestMessage"/> with the given body and headers.
/// </summary>
/// <param name="body">The response body.</param>
/// <param name="headers">The response headers.</param>
public HttpRequestMessage(object body, WebHeaderCollection headers) :
this(body, headers, HttpMethod.GET)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpRequestMessage"/> with the given body, headers and HTTP method.
/// </summary>
/// <param name="body">The response body.</param>
/// <param name="headers">The response headers.</param>
/// <param name="method">The HTTP method.</param>
public HttpRequestMessage(object body, WebHeaderCollection headers, HttpMethod method)
{
this.method = method;
this.body = body;
this.headers = headers;
}
}
}

View File

@@ -1,52 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
namespace Spring.Http
{
/// <summary>
/// Represents a HTTP response message with no body.
/// </summary>
/// <author>Bruno Baia</author>
public class HttpResponseMessage : HttpResponseMessage<object>
{
/// <summary>
/// Creates a new instance of <see cref="HttpResponseMessage"/> with the given status code and status description.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpResponseMessage(HttpStatusCode statusCode, string statusDescription) :
base(null, null, statusCode, statusDescription)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpResponseMessage"/> with the given headers, status code and status description.
/// </summary>
/// <param name="headers">The response headers.</param>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpResponseMessage(HttpHeaders headers, HttpStatusCode statusCode, string statusDescription) :
base(null, headers, statusCode, statusDescription)
{
}
}
}

View File

@@ -1,98 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
namespace Spring.Http
{
/// <summary>
/// Represents a HTTP response message, as defined in the HTTP specification.
/// <a href="http://tools.ietf.org/html/rfc2616#section-6">HTTP 1.1, section 6</a>
/// </summary>
/// <typeparam name="T">The type of the response body.</typeparam>
/// <author>Bruno Baia</author>
public class HttpResponseMessage<T> : HttpEntity<T> where T : class
{
private HttpStatusCode statusCode;
private string statusDescription;
/// <summary>
/// Gets the HTTP status code of the response.
/// </summary>
public HttpStatusCode StatusCode
{
get { return statusCode; }
}
/// <summary>
/// Gets the HTTP status description of the response.
/// </summary>
public string StatusDescription
{
get { return statusDescription; }
}
/// <summary>
/// Creates a new instance of <see cref="HttpResponseMessage{T}"/> with the given status code and status description.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpResponseMessage(HttpStatusCode statusCode, string statusDescription) :
this(null, null, statusCode, statusDescription)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpResponseMessage{T}"/> with the given body, status code and status description.
/// </summary>
/// <param name="body">The response body.</param>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpResponseMessage(T body, HttpStatusCode statusCode, string statusDescription) :
this(body, null, statusCode, statusDescription)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpResponseMessage{T}"/> with the given headers, status code and status description.
/// </summary>
/// <param name="headers">The response headers.</param>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpResponseMessage(HttpHeaders headers, HttpStatusCode statusCode, string statusDescription) :
this(null, headers, statusCode, statusDescription)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpResponseMessage{T}"/> with the given body, headers, status code and status description.
/// </summary>
/// <param name="body">The response body.</param>
/// <param name="headers">The response headers.</param>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpResponseMessage(T body, HttpHeaders headers, HttpStatusCode statusCode, string statusDescription) :
base(body, headers)
{
this.statusCode = statusCode;
this.statusDescription = statusDescription;
}
}
}

View File

@@ -1,47 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
namespace Spring.Http
{
/// <summary>
/// Represents an HTTP message, consisting of <see cref="P:Headers">headers</see>
/// and a readable <see cref="P:Body">body</see>.
/// </summary>
/// <remarks>
/// Typically implemented by an HTTP request on the server-side, or a response on the client-side.
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IHttpInputMessage
{
/// <summary>
/// Gets the message headers.
/// </summary>
HttpHeaders Headers { get; }
/// <summary>
/// Gets the body of the message as a stream.
/// </summary>
Stream Body { get; }
}
}

View File

@@ -1,47 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
namespace Spring.Http
{
/// <summary>
/// Represents an HTTP message, consisting of <see cref="P:Headers">headers</see>
/// and a writable <see cref="P:Body">body</see>.
/// </summary>
/// <remarks>
/// Typically implemented by an HTTP request on the client-side, or a response on the server-side.
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IHttpOutputMessage
{
/// <summary>
/// Gets the message headers.
/// </summary>
HttpHeaders Headers { get; }
/// <summary>
/// Sets the delegate that writes the body message as a stream.
/// </summary>
Action<Stream> Body { set; }
}
}

View File

@@ -1,818 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Text;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using Spring.Util;
namespace Spring.Http
{
/// <summary>
/// Represents an Internet Media Type, as defined in the HTTP specification.
/// <a href="http://tools.ietf.org/html/rfc2616#section-3.7">HTTP 1.1, section 3.7</a>
/// </summary>
/// <remarks>
/// Consists of a <see cref="P:Type"/> and a <see cref="P:SubType"/>.
/// Also has functionality to parse media types from a string using <see cref="M:ParseMediaType(string)"/>,
/// or multiple comma-separated media types using <see cref="M:ParseMediaTypes(string)"/>.
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Juergen Hoeller</author>
/// <author>Bruno Baia (.NET)</author>
public class MediaType : IComparable<MediaType>
{
/// <summary>
/// Public constant media type that includes all media ranges (i.e. '*/*').
/// </summary>
public static readonly MediaType ALL = new MediaType("*", "*");
/// <summary>
/// Public constant media type for 'application/atom+xml'.
/// </summary>
public static readonly MediaType APPLICATION_ATOM_XML = new MediaType("application", "atom+xml");
/// <summary>
/// Public constant media type for 'application/x-www-form-urlencoded'.
/// </summary>
public static readonly MediaType APPLICATION_FORM_URLENCODED = new MediaType("application", "x-www-form-urlencoded");
/// <summary>
/// Public constant media type for 'application/json'.
/// </summary>
public static readonly MediaType APPLICATION_JSON = new MediaType("application", "json");
/// <summary>
/// Public constant media type for 'application/octet-stream'.
/// </summary>
public static readonly MediaType APPLICATION_OCTET_STREAM = new MediaType("application", "octet-stream");
/// <summary>
/// Public constant media type for 'application/xhtml+xml'.
/// </summary>
public static readonly MediaType APPLICATION_XHTML_XML = new MediaType("application", "xhtml+xml");
/// <summary>
/// Public constant media type for 'image/gif'.
/// </summary>
public static readonly MediaType IMAGE_GIF = new MediaType("image", "gif");
/// <summary>
/// Public constant media type for 'image/jpeg'.
/// </summary>
public static readonly MediaType IMAGE_JPEG = new MediaType("image", "jpeg");
/// <summary>
/// Public constant media type for 'image/png'.
/// </summary>
public static readonly MediaType IMAGE_PNG = new MediaType("image", "png");
/// <summary>
/// Public constant media type for 'image/xml'.
/// </summary>
public static readonly MediaType APPLICATION_XML = new MediaType("application", "xml");
/// <summary>
/// Public constant media type for 'multipart/form-data'.
/// </summary>
public static readonly MediaType MULTIPART_FORM_DATA = new MediaType("multipart", "form-data");
/// <summary>
/// Public constant media type for 'text/html'.
/// </summary>
public static readonly MediaType TEXT_HTML = new MediaType("text", "html");
/// <summary>
/// Public constant media type for 'text/plain'.
/// </summary>
public static readonly MediaType TEXT_PLAIN = new MediaType("text", "plain");
/// <summary>
/// Public constant media type for 'text/xml'.
/// </summary>
public static readonly MediaType TEXT_XML = new MediaType("text", "xml");
private const string WILDCARD_TYPE = "*";
private const string PARAM_QUALITY_FACTOR = "q";
private const string PARAM_CHARSET = "charset";
private string type;
private string subtype;
private IDictionary<string, string> parameters;
/// <summary>
/// Gets the primary type.
/// </summary>
public string Type
{
get { return this.type; }
}
/// <summary>
/// Gets the subtype.
/// </summary>
public string Subtype
{
get { return this.subtype; }
}
/// <summary>
/// Indicate whether the type is the wildcard character '*', or not.
/// </summary>
public bool IsWildcardType
{
get { return WILDCARD_TYPE == type; }
}
/// <summary>
/// Indicate whether the subtype is the wildcard character '*', or not.
/// </summary>
public bool IsWildcardSubtype
{
get { return WILDCARD_TYPE == subtype; }
}
/// <summary>
/// Gets the character set, as indicated by a 'charset' parameter, if any.
/// </summary>
public string CharSet
{
get
{
string charSet = null;
this.parameters.TryGetValue(PARAM_CHARSET, out charSet);
return charSet;
//string charSet = this.parameters[PARAM_CHARSET];
//return (charSet != null ? Charset.forName(charSet) : null);
}
}
/// <summary>
/// Gets the quality value, as indicated by a 'q' parameter, if any.
/// Defaults to '1.0'.
/// </summary>
public double QualityValue
{
get
{
string qualityFactory = null;
return this.parameters.TryGetValue(PARAM_QUALITY_FACTOR, out qualityFactory)
? Double.Parse(qualityFactory, CultureInfo.InvariantCulture)
: 1D;
}
}
/// <summary>
/// Creates a new instance of <see cref="MediaType"/> for the given primary type.
/// The subtype is set to '*', parameters are empty.
/// </summary>
/// <param name="type">The primary type.</param>
public MediaType(string type) :
this(type, WILDCARD_TYPE)
{
}
/// <summary>
/// Creates a new instance of <see cref="MediaType"/> for the given primary type and subtype.
/// The parameters are empty.
/// </summary>
/// <param name="type">The primary type.</param>
/// <param name="subtype">The subtype.</param>
public MediaType(string type, string subtype) :
this(type, subtype, new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase))
{
}
/// <summary>
/// Creates a new instance of <see cref="MediaType"/> for the given primary type, subtype and character set.
/// </summary>
/// <param name="type">The primary type.</param>
/// <param name="subtype">The subtype.</param>
/// <param name="charSet">The character set</param>
public MediaType(string type, string subtype, string charSet) :
this(type, subtype)
{
this.parameters.Add(PARAM_CHARSET, charSet);
}
/// <summary>
/// Creates a new instance of <see cref="MediaType"/> for the given primary type, subtype and quality value.
/// </summary>
/// <param name="type">The primary type.</param>
/// <param name="subtype">The subtype.</param>
/// <param name="qualityValue">The quality value</param>
public MediaType(String type, String subtype, double qualityValue) :
this(type, subtype)
{
this.parameters.Add(PARAM_QUALITY_FACTOR, qualityValue.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// Creates a new instance of <see cref="MediaType"/> by copying the type and subtype of the given MediaType,
/// and allows for different parameter.
/// </summary>
/// <param name="otherMediaType">The other media type.</param>
/// <param name="parameters">The parameters, may be null.</param>
public MediaType(MediaType otherMediaType, IDictionary<string, string> parameters) :
this(otherMediaType.Type, otherMediaType.Subtype, parameters)
{
}
/// <summary>
/// Creates a new instance of <see cref="MediaType"/> for the given primary type, subtype and parameters.
/// </summary>
/// <param name="type">The primary type.</param>
/// <param name="subtype">The subtype.</param>
/// <param name="parameters">The parameters, may be null.</param>
public MediaType(string type, string subtype, IDictionary<string, string> parameters)
{
AssertUtils.ArgumentHasText(type, "'type' must not be empty");
AssertUtils.ArgumentHasText(subtype, "'subtype' must not be empty");
//checkToken(type);
//checkToken(subtype);
this.type = type.ToLower(CultureInfo.InvariantCulture);
this.subtype = subtype.ToLower(CultureInfo.InvariantCulture);
this.parameters = new Dictionary<string, string>(parameters, StringComparer.InvariantCultureIgnoreCase);
//if (parameters.Count > 0)
//{
// NameValueCollection m = new NameValueCollection(parameters.Count, null, new CaseInsensitiveComparer());
// for (Map.Entry<String, String> entry : parameters.entrySet()) {
// String attribute = entry.getKey();
// String value = entry.getValue();
// checkParameters(attribute, value);
// m.put(attribute, unquote(value));
// }
// this.parameters = Collections.unmodifiableMap(m);
//}
//else
//{
// this.parameters = Collections.emptyMap();
//}
}
/// <summary>
/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
/// </summary>
/// <param name="obj">
/// The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.
/// </param>
/// <returns>
/// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
/// </returns>
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (obj is MediaType)
{
MediaType otherMediaType = (MediaType)obj;
if (this.type == otherMediaType.type &&
this.subtype == otherMediaType.subtype)
{
if (otherMediaType.parameters.Count == this.parameters.Count)
{
foreach(string key in this.parameters.Keys)
{
if (!otherMediaType.parameters.ContainsKey(key) ||
!String.Equals(otherMediaType.parameters[key], this.parameters[key]))
{
return false;
}
}
return true;
}
}
}
return false;
}
/// <summary>
/// Serves as a hash function for a particular type.
/// </summary>
/// <remarks>
/// <see cref="M:System.Object.GetHashCode"/> is suitable for use in hashing algorithms and data structures like a hash table.
/// </remarks>
/// <returns>
/// A hash code for the current <see cref="T:System.Object"/>.
/// </returns>
public override int GetHashCode()
{
int result = this.type.GetHashCode();
result = 31 * result + this.subtype.GetHashCode();
result = 31 * result + this.parameters.GetHashCode();
return result;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object."/>
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object."/>.
/// </returns>
public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.Append(this.type);
builder.Append('/');
builder.Append(this.subtype);
foreach(string key in this.parameters.Keys)
{
builder.Append(';');
builder.Append(key);
builder.Append('=');
builder.Append(this.parameters[key]);
}
return builder.ToString();
}
// **
// * Checks the given token string for illegal characters, as defined in RFC 2616, section 2.2.
// * @throws IllegalArgumentException in case of illegal characters
// * @see <a href="http://tools.ietf.org/html/rfc2616#section-2.2">HTTP 1.1, section 2.2</a>
// */
//private void checkToken(String s) {
// for (int i=0; i < s.length(); i++ ) {
// char ch = s.charAt(i);
// if (!TOKEN.get(ch)) {
// throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + s + "\"");
// }
// }
//}
//private void checkParameters(String attribute, String value) {
// Assert.hasLength(attribute, "parameter attribute must not be empty");
// Assert.hasLength(value, "parameter value must not be empty");
// checkToken(attribute);
// if (PARAM_QUALITY_FACTOR.equals(attribute)) {
// value = unquote(value);
// double d = Double.parseDouble(value);
// Assert.isTrue(d >= 0D && d <= 1D,
// "Invalid quality value \"" + value + "\": should be between 0.0 and 1.0");
// }
// else if (PARAM_CHARSET.equals(attribute)) {
// value = unquote(value);
// Charset.forName(value);
// }
// else if (!isQuotedString(value)) {
// checkToken(value);
// }
//}
//private boolean isQuotedString(String s) {
// return s.length() > 1 && s.startsWith("\"") && s.endsWith("\"") ;
//}
//private String unquote(String s) {
// if (s == null) {
// return null;
// }
// return isQuotedString(s) ? s.substring(1, s.length() - 1) : s;
//}
/// <summary>
/// Return a generic parameter value, given a parameter name.
/// </summary>
/// <param name="name">The parameter name.</param>
/// <returns>The parameter value; or null if not present.</returns>
public string GetParameter(string name)
{
return this.parameters[name];
}
/// <summary>
/// Indicate whether this <see cref="T:MediaType"/> includes the given media type.
/// </summary>
/// <remarks>
/// For instance, 'text/*' includes 'text/plain', 'text/html', and
/// 'application/*+xml' includes 'application/soap+xml', etc.
/// This method is non-symmetric.
/// </remarks>
/// <param name="otherMediaType">The reference media type with which to compare.</param>
/// <returns>
/// <see langword="true"/> if this media type includes the given media type; otherwise <see langword="false"/>.
/// </returns>
public bool Includes(MediaType otherMediaType)
{
if (otherMediaType == null)
{
return false;
}
if (this.IsWildcardType)
{
// */* includes anything
return true;
}
else if (this.type == otherMediaType.type)
{
if (this.subtype == otherMediaType.subtype || this.IsWildcardSubtype)
{
return true;
}
// application/*+xml includes application/soap+xml
int thisPlusIdx = this.subtype.IndexOf('+');
int otherPlusIdx = otherMediaType.subtype.IndexOf('+');
if (thisPlusIdx != -1 && otherPlusIdx != -1)
{
string thisSubtypeNoSuffix = this.subtype.Substring(0, thisPlusIdx);
string thisSubtypeSuffix = this.subtype.Substring(thisPlusIdx + 1);
string otherSubtypeSuffix = otherMediaType.subtype.Substring(otherPlusIdx + 1);
if (thisSubtypeSuffix == otherSubtypeSuffix && WILDCARD_TYPE == thisSubtypeNoSuffix)
{
return true;
}
}
}
return false;
}
/// <summary>
/// Indicate whether this <see cref="T:MediaType"/> is compatible with the given media type.
/// </summary>
/// <remarks>
/// For instance, 'text/*' is compatible 'text/plain', 'text/html', and vice versa.
/// In effect, this method is similar to <see cref="M:Includes(MediaType)"/>, except that it's symmetric.
/// </remarks>
/// <param name="otherMediaType">The reference media type with which to compare.</param>
/// <returns>
/// <see langword="true"/> if this media type is compatible with the given media type; otherwise <see langword="false"/>.
/// </returns>
public bool IsCompatibleWith(MediaType otherMediaType)
{
if (otherMediaType == null)
{
return false;
}
if (this.IsWildcardType || otherMediaType.IsWildcardType)
{
return true;
}
else if (this.type == otherMediaType.type)
{
if (this.subtype == otherMediaType.subtype || this.IsWildcardSubtype || otherMediaType.IsWildcardSubtype)
{
return true;
}
// application/*+xml is compatible with application/soap+xml, and vice-versa
int thisPlusIdx = this.subtype.IndexOf('+');
int otherPlusIdx = otherMediaType.subtype.IndexOf('+');
if (thisPlusIdx != -1 && otherPlusIdx != -1)
{
string thisSubtypeNoSuffix = this.subtype.Substring(0, thisPlusIdx);
string otherSubtypeNoSuffix = otherMediaType.subtype.Substring(0, otherPlusIdx);
string thisSubtypeSuffix = this.subtype.Substring(thisPlusIdx + 1);
string otherSubtypeSuffix = otherMediaType.subtype.Substring(otherPlusIdx + 1);
if (thisSubtypeSuffix == otherSubtypeSuffix &&
(WILDCARD_TYPE == thisSubtypeNoSuffix || WILDCARD_TYPE == otherSubtypeNoSuffix))
{
return true;
}
}
}
return false;
}
#region IComparable<MediaType> Membres
/// <summary>
/// Compares this <see cref="MediaType"/> to another alphabetically.
/// </summary>
/// <param name="other">The media type to compare with this object.</param>
/// <returns>
/// A 32-bit signed integer that indicates the relative order of the objects
/// being compared. The return value has the following meanings: Value Meaning
/// Less than zero This object is less than the other parameter. Zero This object
/// is equal to other. Greater than zero This object is greater than other.
/// </returns>
public int CompareTo(MediaType other)
{
int comp = this.type.CompareTo(other.type);
if (comp != 0)
{
return comp;
}
comp = this.subtype.CompareTo(other.subtype);
if (comp != 0)
{
return comp;
}
comp = this.parameters.Count - other.parameters.Count;
if (comp != 0)
{
return comp;
}
foreach(string key in this.parameters.Keys)
{
if (!other.parameters.ContainsKey(key))
{
return -1;
}
comp = String.Compare(this.parameters[key], other.parameters[key]);
if (comp != 0)
{
return comp;
}
}
return 0;
}
#endregion
/// <summary>
/// Parse the given String into a single <see cref="MediaType"/>.
/// </summary>
/// <remarks>
/// This method can be used to parse a 'Content-Type' header.
/// </remarks>
/// <param name="mediaType">The string to parse.</param>
/// <returns>The media type.</returns>
public static MediaType Parse(string mediaType)
{
if (!StringUtils.HasText(mediaType))
{
return null;
}
string[] parts = mediaType.Split(';');
string fullType = parts[0].Trim();
if (fullType == WILDCARD_TYPE)
{
fullType = "*/*";
}
int subIndex = fullType.IndexOf('/');
if (subIndex == -1)
{
throw new ArgumentException(
String.Format("'{0}' does not contain '/'", mediaType),
"mediaType");
}
if (subIndex == fullType.Length - 1)
{
throw new ArgumentException(
String.Format("'{0}' does not contain subtype after '/'", mediaType),
"mediaType");
}
string type = fullType.Substring(0, subIndex);
string subtype = fullType.Substring(subIndex + 1);
IDictionary<string, string> parameters = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
if (parts.Length > 1)
{
for (int i = 1; i < parts.Length; i++)
{
string parameter = parts[i].Trim();
int eqIndex = parameter.IndexOf('=');
if (eqIndex != -1)
{
string attribute = parameter.Substring(0, eqIndex);
string value = parameter.Substring(eqIndex + 1);
parameters.Add(attribute, value);
}
}
}
return new MediaType(type, subtype, parameters);
}
/// <summary>
/// Return a string representation of the given list of <see cref="MediaType"/> objects.
/// </summary>
/// <remarks>
/// This method can be used to for an 'Accept' or 'Content-Type' header.
/// </remarks>
/// <param name="mediaTypes">The list of media types to convert.</param>
/// <returns>The string representation of the given list.</returns>
public static string ToString(IEnumerable<MediaType> mediaTypes)
{
StringBuilder builder = new StringBuilder();
foreach(MediaType mediaType in mediaTypes)
{
if (builder.Length > 0)
{
builder.Append(',');
}
builder.Append(mediaType);
}
return builder.ToString();
}
/// <summary>
/// Sorts the given list of <see cref="MediaType"/> objects by specificity.
/// <a href="http://tools.ietf.org/html/rfc2616#section-14.1">HTTP 1.1, section 14.1</a>
/// </summary>
/// <remarks>
/// <para>
/// Given two media types:
/// <ol>
/// <li>if either media type has a wildcard type, then the media type without the
/// wildcard is ordered before the other.</li>
/// <li>if the two media types have different types, then they are considered equal and
/// remain their current order.</li>
/// <li>if either media type has a wildcard subtype, then the media type without
/// the wildcard is sorted before the other.</li>
/// <li>if the two media types have different subtypes, then they are considered equal
/// and remain their current order.</li>
/// <li>if the two media types have different quality value, then the media type
/// with the highest quality value is ordered before the other.</li>
/// <li>if the two media types have a different amount of parameters, then the
/// media type with the most parameters is ordered before the other.</li>
/// </ol>
/// </para>
/// <para>
/// For example:
/// <blockquote>audio/basic &lt; audio/* &lt; *&#047;*</blockquote>
/// <blockquote>audio/* &lt; audio/*;q=0.7; audio/*;q=0.3</blockquote>
/// <blockquote>audio/basic;level=1 &lt; audio/basic</blockquote>
/// <blockquote>audio/basic == text/html</blockquote>
/// <blockquote>audio/basic == audio/wave</blockquote>
/// </para>
/// </remarks>
/// <param name="mediaTypes">The list of media types to be sorted.</param>
public static void SortBySpecificity(List<MediaType> mediaTypes)
{
AssertUtils.ArgumentNotNull(mediaTypes, "mediaTypes");
if (mediaTypes.Count > 1)
{
mediaTypes.Sort(SPECIFICITY_COMPARER);
}
}
/// <summary>
/// Sorts the given list of <see cref="MediaType"/> objects by quality value.
/// </summary>
/// <remarks>
/// <para>
/// Given two media types:
/// <ol>
/// <li>if the two media types have different quality value, then the media type
/// with the highest quality value is ordered before the other.</li>
/// <li>if either media type has a wildcard type, then the media type without the
/// wildcard is ordered before the other.</li>
/// <li>if the two media types have different types, then they are considered equal and
/// remain their current order.</li>
/// <li>if either media type has a wildcard subtype, then the media type without
/// the wildcard is sorted before the other.</li>
/// <li>if the two media types have different subtypes, then they are considered equal
/// and remain their current order.</li>
/// <li>if the two media types have a different amount of parameters, then the
/// media type with the most parameters is ordered before the other.</li>
/// </ol>
/// </para>
/// </remarks>
/// <param name="mediaTypes">The list of media types to be sorted</param>
public static void SortByQualityValue(List<MediaType> mediaTypes)
{
AssertUtils.ArgumentNotNull(mediaTypes, "mediaTypes");
if (mediaTypes.Count > 1)
{
mediaTypes.Sort(QUALITY_VALUE_COMPARER);
}
}
/// <summary>
/// <see cref="IComparer&lt;MediaType>"/> implementation by specificity value.
/// </summary>
public static IComparer<MediaType> SPECIFICITY_COMPARER = new SpecificityComparer();
/// <summary>
/// <see cref="IComparer&lt;MediaType>"/> implementation by quality value.
/// </summary>
public static IComparer<MediaType> QUALITY_VALUE_COMPARER = new QualityValueComparer();
#region SpecificityComparer
private class SpecificityComparer : IComparer<MediaType>
{
public int Compare(MediaType x, MediaType y)
{
if (x.IsWildcardType && !y.IsWildcardType)
{ // */* < audio/*
return 1;
}
else if (y.IsWildcardType && !x.IsWildcardType)
{ // audio/* > */*
return -1;
}
else if (x.type != y.type)
{ // audio/basic == text/html
return 0;
}
else
{ // mediaType1.type == mediaType2.type
if (x.IsWildcardSubtype && !y.IsWildcardSubtype)
{ // audio/* < audio/basic
return 1;
}
else if (y.IsWildcardSubtype && !x.IsWildcardSubtype)
{ // audio/basic > audio/*
return -1;
}
else if (x.subtype != y.subtype)
{ // audio/basic == audio/wave
return 0;
}
else
{ // mediaType2.subtype == mediaType2.subtype
double quality1 = x.QualityValue;
double quality2 = y.QualityValue;
int qualityComparison = quality2.CompareTo(quality1);
if (qualityComparison != 0)
{
return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3
}
else
{
int paramsSize1 = x.parameters.Count;
int paramsSize2 = y.parameters.Count;
return (paramsSize2 < paramsSize1 ? -1 : (paramsSize2 == paramsSize1 ? 0 : 1)); // audio/basic;level=1 < audio/basic
}
}
}
}
}
#endregion
#region QualityValueComparer
private class QualityValueComparer : IComparer<MediaType>
{
public int Compare(MediaType x, MediaType y)
{
double quality1 = x.QualityValue;
double quality2 = y.QualityValue;
int qualityComparison = quality2.CompareTo(quality1);
if (qualityComparison != 0)
{
return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3
}
else if (x.IsWildcardType && !y.IsWildcardType)
{ // */* < audio/*
return 1;
}
else if (y.IsWildcardType && !x.IsWildcardType)
{ // audio/* > */*
return -1;
}
else if (x.type != y.type)
{ // audio/basic == text/html
return 0;
}
else
{ // mediaType1.type == mediaType2.type
if (x.IsWildcardSubtype && !y.IsWildcardSubtype)
{ // audio/* < audio/basic
return 1;
}
else if (y.IsWildcardSubtype && !x.IsWildcardSubtype)
{ // audio/basic > audio/*
return -1;
}
else if (x.subtype != y.subtype)
{ // audio/basic == audio/wave
return 0;
}
else
{
int paramsSize1 = x.parameters.Count;
int paramsSize2 = y.parameters.Count;
return (paramsSize2 < paramsSize1 ? -1 : (paramsSize2 == paramsSize1 ? 0 : 1)); // audio/basic;level=1 < audio/basic
}
}
}
}
#endregion
}
}

View File

@@ -1,76 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Runtime.Serialization;
namespace Spring.Http.Rest
{
/// <summary>
/// Exception thrown when an HTTP 4xx is received.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
#if !SILVERLIGHT
[Serializable]
#endif
public class HttpClientErrorException : HttpStatusCodeException
{
/// <summary>
/// Creates a new instance of <see cref="HttpClientErrorException"/>
/// based on a <see cref="HttpStatusCode"/>.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
public HttpClientErrorException(HttpStatusCode statusCode)
: base (statusCode)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpClientErrorException"/>
/// based on a <see cref="HttpStatusCode"/> and a status description.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpClientErrorException(HttpStatusCode statusCode, string statusDescription)
: base (statusCode, statusDescription)
{
}
#if !SILVERLIGHT
/// <summary>
/// Creates a new instance of the <see cref="HttpClientErrorException"/> class.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/>
/// that contains contextual information about the source or destination.
/// </param>
protected HttpClientErrorException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
}
}

View File

@@ -1,76 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Runtime.Serialization;
namespace Spring.Http.Rest
{
/// <summary>
/// Exception thrown when an HTTP 5xx is received.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
#if !SILVERLIGHT
[Serializable]
#endif
public class HttpServerErrorException : HttpStatusCodeException
{
/// <summary>
/// Creates a new instance of <see cref="HttpServerErrorException"/>
/// based on a <see cref="HttpStatusCode"/>.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
public HttpServerErrorException(HttpStatusCode statusCode)
: base (statusCode)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpServerErrorException"/>
/// based on a <see cref="HttpStatusCode"/> and a status description.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpServerErrorException(HttpStatusCode statusCode, string statusDescription)
: base (statusCode, statusDescription)
{
}
#if !SILVERLIGHT
/// <summary>
/// Creates a new instance of the <see cref="HttpServerErrorException"/> class.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/>
/// that contains contextual information about the source or destination.
/// </param>
protected HttpServerErrorException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
}
}

View File

@@ -1,129 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace Spring.Http.Rest
{
/// <summary>
/// Base class for exceptions based on a <see cref="HttpStatusCode"/>.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
#if !SILVERLIGHT
[Serializable]
#endif
public class HttpStatusCodeException : RestClientException
{
private HttpStatusCode statusCode;
private string statusDescription;
/// <summary>
/// Gets the HTTP status code.
/// </summary>
public HttpStatusCode StatusCode
{
get { return this.statusCode; }
}
/// <summary>
/// Gets the HTTP status description.
/// </summary>
public string StatusDescription
{
get { return this.statusDescription; }
}
/// <summary>
/// Creates a new instance of <see cref="HttpStatusCodeException"/>
/// based on a <see cref="HttpStatusCode"/>.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
public HttpStatusCodeException(HttpStatusCode statusCode)
: base(String.Format("The server returned '{0}' with the status code {0:d}.", statusCode))
{
this.statusCode = statusCode;
this.statusDescription = statusCode.ToString();
}
/// <summary>
/// Creates a new instance of <see cref="HttpStatusCodeException"/>
/// based on a <see cref="HttpStatusCode"/> and a status description.
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
/// <param name="statusDescription">The HTTP status description.</param>
public HttpStatusCodeException(HttpStatusCode statusCode, string statusDescription)
: base(String.Format("The server returned '{0}' with the status code {1:d} - {1}.", statusDescription, statusCode))
{
this.statusCode = statusCode;
this.statusDescription = statusDescription;
}
#if !SILVERLIGHT
/// <summary>
/// Creates a new instance of the <see cref="RestClientException"/> class.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/>
/// that contains contextual information about the source or destination.
/// </param>
protected HttpStatusCodeException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
if (info != null)
{
this.statusCode = (HttpStatusCode)info.GetInt32("StatusCode");
this.statusDescription = info.GetString("StatusDescription");
}
}
/// <summary>
/// Populates the <see cref="System.Runtime.Serialization.SerializationInfo"/> with
/// information about the exception.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/> that holds
/// the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/> that contains contextual
/// information about the source or destination.
/// </param>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(
SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
if (info != null)
{
info.AddValue("StatusCode", (int)this.statusCode);
info.AddValue("StatusDescription", this.statusDescription);
}
}
#endif
}
}

View File

@@ -1,57 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.IO;
using System.Net;
using Spring.Http.Client;
namespace Spring.Http.Rest
{
/// <summary>
/// Callback interface for code that operates on a <see cref="IClientHttpRequest"/>.
/// Allows to manipulate the request headers, and write to the request body.
/// </summary>
/// <remarks>
/// <para>
/// Callback interface used by <see cref="RestTemplate"/>'s senders methods.
/// Implementations of this interface perform the actual work of writing data
/// to a <see cref="IClientHttpRequest"/>, but don't need to worry about exception
/// handling or closing resources.
/// </para>
/// <para>
/// Used internally by the <see cref="RestTemplate"/>, but also useful for application code.
/// </para>
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IRequestCallback
{
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an <see cref="IClientHttpRequest"/> to write data.
/// </summary>
/// <remarks>
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </remarks>
/// <param name="request">The active HTTP request.</param>
void DoWithRequest(IClientHttpRequest request);
}
}

View File

@@ -1,54 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using Spring.Http.Client;
namespace Spring.Http.Rest
{
/// <summary>
/// Strategy interface used by the <see cref="RestTemplate"/> to determine
/// whether a particular response has an error or not.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IResponseErrorHandler
{
/// <summary>
/// Indicates whether the given response has any errors.
/// </summary>
/// <remarks>
/// Implementations will typically inspect the status code of the response.
/// </remarks>
/// <param name="response">The response to inspect.</param>
/// <returns>
/// <see langword="true"/> if the response has an error; otherwise <see langword="false"/>.
/// </returns>
bool HasError(IClientHttpResponse response);
/// <summary>
/// Handles the error in the given response.
/// This method is only called when <see cref="M:HasError"/> has returned <see langword="true"/>.
/// </summary>
/// <param name="response">The response with the error</param>
void HandleError(IClientHttpResponse response);
}
}

View File

@@ -1,54 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
using Spring.Http.Client;
namespace Spring.Http.Rest
{
/// <summary>
/// Callback interface for code that operates on a <see cref="IClientHttpResponse"/>.
/// Allows to manipulate the response headers, and extract the response body.
/// </summary>
/// <remarks>
/// <para>
/// Generic callback interface used by <see cref="RestTemplate"/>'s retrieval methods.
/// Implementations of this interface perform the actual work of extracting data
/// from a <see cref="IClientHttpResponse"/>, but don't need to worry about exception
/// handling or closing resources.
/// </para>
/// <para>
/// Used internally by the <see cref="RestTemplate"/>, but also useful for application code.
/// </para>
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public interface IResponseExtractor<T> where T : class
{
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an opened <see cref="IClientHttpResponse"/> to extract data.
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </summary>
/// <param name="response">The active HTTP request.</param>
T ExtractData(IClientHttpResponse response);
}
}

View File

@@ -1,676 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Collections.Generic;
namespace Spring.Http.Rest
{
/// <summary>
/// Interface specifying a basic set of RESTful asynchrone operations.
/// </summary>
/// <remarks>
/// Not often used directly, but a useful option to enhance testability,
/// as it can easily be mocked or stubbed.
/// </remarks>
/// <see cref="RestTemplate"/>
/// <author>Bruno Baia (.NET)</author>
/// <author>Arjen Poutsma</author>
/// <author>Juergen Hoeller</author>
public interface IRestAsyncOperations
{
#region GET
/// <summary>
/// Asynchronously retrieve a representation by doing a GET on the specified URL.
/// The response (if any) is converted.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="getCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous GET method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void GetForObjectAsync<T>(string url, Action<MethodCompletedEventArgs<T>> getCompleted, params object[] uriVariables) where T : class;
/// <summary>
/// Asynchronously retrieve a representation by doing a GET on the specified URL.
/// The response (if any) is converted.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="getCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous GET method completes.
/// </param>
void GetForObjectAsync<T>(string url, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<T>> getCompleted) where T : class;
/// <summary>
/// Asynchronously retrieve a representation by doing a GET on the specified URL.
/// The response (if any) is converted.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="getCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous GET method completes.
/// </param>
void GetForObjectAsync<T>(Uri url, Action<MethodCompletedEventArgs<T>> getCompleted) where T : class;
/// <summary>
/// Asynchronously retrieve an entity by doing a GET on the specified URL.
/// The response is converted and stored in an <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="getCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous GET method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void GetForMessageAsync<T>(string url, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> getCompleted, params object[] uriVariables) where T : class;
/// <summary>
/// Asynchronously retrieve an entity by doing a GET on the specified URL.
/// The response is converted and stored in an <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="getCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous GET method completes.
/// </param>
void GetForMessageAsync<T>(string url, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> getCompleted) where T : class;
/// <summary>
/// Asynchronously retrieve an entity by doing a GET on the specified URL.
/// The response is converted and stored in an <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="getCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous GET method completes.
/// </param>
void GetForMessageAsync<T>(Uri url, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> getCompleted) where T : class;
#endregion
#region HEAD
/// <summary>
/// Asynchronously retrieve all headers of the resource specified by the URI template.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="headCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous HEAD method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void HeadForHeadersAsync(string url, Action<MethodCompletedEventArgs<HttpHeaders>> headCompleted, params object[] uriVariables);
/// <summary>
/// Asynchronously retrieve all headers of the resource specified by the URI template.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="headCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous HEAD method completes.
/// </param>
void HeadForHeadersAsync(string url, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<HttpHeaders>> headCompleted);
/// <summary>
/// Asynchronously retrieve all headers of the resource specified by the URI template.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="headCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous HEAD method completes.
/// </param>
void HeadForHeadersAsync(Uri url, Action<MethodCompletedEventArgs<HttpHeaders>> headCompleted);
#endregion
#region POST
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the value of the 'Location' header.
/// This header typically indicates where the new resource is stored.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void PostForLocationAsync(string url, object request, Action<Uri> postCompleted, params object[] uriVariables);
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the value of the 'Location' header.
/// This header typically indicates where the new resource is stored.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForLocationAsync(string url, object request, IDictionary<string, object> uriVariables, Action<Uri> postCompleted);
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the value of the 'Location' header.
/// This header typically indicates where the new resource is stored.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForLocationAsync(Uri url, object request, Action<Uri> postCompleted);
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the representation found in the response.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void PostForObjectAsync<T>(string url, object request, Action<MethodCompletedEventArgs<T>> postCompleted, params object[] uriVariables) where T : class;
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the representation found in the response.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForObjectAsync<T>(string url, object request, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<T>> postCompleted) where T : class;
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the representation found in the response.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForObjectAsync<T>(Uri url, object request, Action<MethodCompletedEventArgs<T>> postCompleted) where T : class;
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void PostForMessageAsync<T>(string url, object request, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> postCompleted, params object[] uriVariables) where T : class;
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForMessageAsync<T>(string url, object request, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> postCompleted) where T : class;
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForMessageAsync<T>(Uri url, object request, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> postCompleted) where T : class;
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void PostForMessageAsync(string url, object request, Action<MethodCompletedEventArgs<HttpResponseMessage>> postCompleted, params object[] uriVariables);
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForMessageAsync(string url, object request, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<HttpResponseMessage>> postCompleted);
/// <summary>
/// Asynchronously create a new resource by POSTing the given object to the URI template,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="postCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous POST method completes.
/// </param>
void PostForMessageAsync(Uri url, object request, Action<MethodCompletedEventArgs<HttpResponseMessage>> postCompleted);
#endregion
#region PUT
/// <summary>
/// Asynchronously create or update a resource by PUTting the given object to the URI.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="putCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous PUT method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void PutAsync(string url, object request, Action<MethodCompletedEventArgs<object>> putCompleted, params object[] uriVariables);
/// <summary>
/// Asynchronously create or update a resource by PUTting the given object to the URI.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="putCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous PUT method completes.
/// </param>
void PutAsync(string url, object request, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<object>> putCompleted);
/// <summary>
/// Asynchronously create or update a resource by PUTting the given object to the URI.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="putCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous PUT method completes.
/// </param>
void PutAsync(Uri url, object request, Action<MethodCompletedEventArgs<object>> putCompleted);
#endregion
#region DELETE
/// <summary>
/// Asynchronously delete the resources at the specified URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="deleteCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous PUT method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void DeleteAsync(string url, Action<MethodCompletedEventArgs<object>> deleteCompleted, params object[] uriVariables);
/// <summary>
/// Asynchronously delete the resources at the specified URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="deleteCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous PUT method completes.
/// </param>
void DeleteAsync(string url, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<object>> deleteCompleted);
/// <summary>
/// Asynchronously delete the resources at the specified URI.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="deleteCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous PUT method completes.
/// </param>
void DeleteAsync(Uri url, Action<MethodCompletedEventArgs<object>> deleteCompleted);
#endregion
#region OPTIONS
/// <summary>
/// Asynchronously return the value of the Allow header for the given URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="optionsCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous OPTIONS method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void OptionsForAllowAsync(string url, Action<IList<HttpMethod>> optionsCompleted, params object[] uriVariables);
/// <summary>
/// Asynchronously return the value of the Allow header for the given URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="optionsCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous OPTIONS method completes.
/// </param>
void OptionsForAllowAsync(string url, IDictionary<string, object> uriVariables, Action<IList<HttpMethod>> optionsCompleted);
/// <summary>
/// Asynchronously return the value of the Allow header for the given URI.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="optionsCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous OPTIONS method completes.
/// </param>
void OptionsForAllowAsync(Uri url, Action<IList<HttpMethod>> optionsCompleted);
#endregion
#region Exchange
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void ExchangeAsync<T>(string url, HttpMethod method, HttpEntity requestEntity, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> methodCompleted, params object[] uriVariables) where T : class;
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
void ExchangeAsync<T>(string url, HttpMethod method, HttpEntity requestEntity, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> methodCompleted) where T : class;
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
void ExchangeAsync<T>(Uri url, HttpMethod method, HttpEntity requestEntity, Action<MethodCompletedEventArgs<HttpResponseMessage<T>>> methodCompleted) where T : class;
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void ExchangeAsync(string url, HttpMethod method, HttpEntity requestEntity, Action<MethodCompletedEventArgs<HttpResponseMessage>> methodCompleted, params object[] uriVariables);
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
void ExchangeAsync(string url, HttpMethod method, HttpEntity requestEntity, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<HttpResponseMessage>> methodCompleted);
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
void ExchangeAsync(Uri url, HttpMethod method, HttpEntity requestEntity, Action<MethodCompletedEventArgs<HttpResponseMessage>> methodCompleted);
#endregion
#region General execution
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, preparing the request with the
/// <see cref="IRequestCallback"/>, and reading the response with an <see cref="IResponseExtractor{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestCallback">Object that prepares the request.</param>
/// <param name="responseExtractor">Object that extracts the return value from the response.</param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void ExecuteAsync<T>(string url, HttpMethod method, IRequestCallback requestCallback, IResponseExtractor<T> responseExtractor, Action<MethodCompletedEventArgs<T>> methodCompleted, params object[] uriVariables) where T : class;
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, preparing the request with the
/// <see cref="IRequestCallback"/>, and reading the response with an <see cref="IResponseExtractor{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestCallback">Object that prepares the request.</param>
/// <param name="responseExtractor">Object that extracts the return value from the response.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
void ExecuteAsync<T>(string url, HttpMethod method, IRequestCallback requestCallback, IResponseExtractor<T> responseExtractor, IDictionary<string, object> uriVariables, Action<MethodCompletedEventArgs<T>> methodCompleted) where T : class;
/// <summary>
/// Asynchronously execute the HTTP method to the given URI template, preparing the request with the
/// <see cref="IRequestCallback"/>, and reading the response with an <see cref="IResponseExtractor{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestCallback">Object that prepares the request.</param>
/// <param name="responseExtractor">Object that extracts the return value from the response.</param>
/// <param name="methodCompleted">
/// The <code>Action&lt;T&gt;</code> to perform when the asynchronous method completes.
/// </param>
void ExecuteAsync<T>(Uri url, HttpMethod method, IRequestCallback requestCallback, IResponseExtractor<T> responseExtractor, Action<MethodCompletedEventArgs<T>> methodCompleted) where T : class;
#endregion
// TODO : void CancelAsync();
}
}

View File

@@ -1,592 +0,0 @@
#if !SILVERLIGHT
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Collections.Generic;
namespace Spring.Http.Rest
{
/// <summary>
/// Interface specifying a basic set of RESTful operations.
/// </summary>
/// <remarks>
/// Not often used directly, but a useful option to enhance testability,
/// as it can easily be mocked or stubbed.
/// </remarks>
/// <see cref="RestTemplate"/>
/// <author>Arjen Poutsma</author>
/// <author>Juergen Hoeller</author>
/// <author>Bruno Baia (.NET)</author>
public interface IRestOperations
{
#region GET
/// <summary>
/// Retrieve a representation by doing a GET on the specified URL.
/// The response (if any) is converted and returned.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The converted object</returns>
T GetForObject<T>(string url, params object[] uriVariables) where T : class;
/// <summary>
/// Retrieve a representation by doing a GET on the specified URL.
/// The response (if any) is converted and returned.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The converted object</returns>
T GetForObject<T>(string url, IDictionary<string, object> uriVariables) where T : class;
/// <summary>
/// Retrieve a representation by doing a GET on the specified URL.
/// The response (if any) is converted and returned.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <returns>The converted object</returns>
T GetForObject<T>(Uri url) where T : class;
/// <summary>
/// Retrieve an entity by doing a GET on the specified URL.
/// The response is converted and stored in an <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> GetForMessage<T>(string url, params object[] uriVariables) where T : class;
/// <summary>
/// Retrieve an entity by doing a GET on the specified URL.
/// The response is converted and stored in an <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> GetForMessage<T>(string url, IDictionary<string, object> uriVariables) where T : class;
/// <summary>
/// Retrieve an entity by doing a GET on the specified URL.
/// The response is converted and stored in an <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> GetForMessage<T>(Uri url) where T : class;
#endregion
#region HEAD
/// <summary>
/// Retrieve all headers of the resource specified by the URI template.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>All HTTP headers of that resource</returns>
HttpHeaders HeadForHeaders(string url, params object[] uriVariables);
/// <summary>
/// Retrieve all headers of the resource specified by the URI template.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>All HTTP headers of that resource</returns>
HttpHeaders HeadForHeaders(string url, IDictionary<string, object> uriVariables);
/// <summary>
/// Retrieve all headers of the resource specified by the URI template.
/// </summary>
/// <param name="url">The URL.</param>
/// <returns>All HTTP headers of that resource</returns>
HttpHeaders HeadForHeaders(Uri url);
#endregion
#region POST
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the value of the 'Location' header.
/// This header typically indicates where the new resource is stored.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The value for the Location header.</returns>
Uri PostForLocation(string url, object request, params object[] uriVariables);
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the value of the 'Location' header.
/// This header typically indicates where the new resource is stored.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The value for the Location header.</returns>
Uri PostForLocation(string url, object request, IDictionary<string, object> uriVariables);
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the value of the 'Location' header.
/// This header typically indicates where the new resource is stored.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <returns>The value for the Location header.</returns>
Uri PostForLocation(Uri url, object request);
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the representation found in the response.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The converted object.</returns>
T PostForObject<T>(string url, object request, params object[] uriVariables) where T : class;
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the representation found in the response.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The converted object.</returns>
T PostForObject<T>(string url, object request, IDictionary<string, object> uriVariables) where T : class;
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the representation found in the response.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <returns>The converted object.</returns>
T PostForObject<T>(Uri url, object request) where T : class;
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> PostForMessage<T>(string url, object request, params object[] uriVariables) where T : class;
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> PostForMessage<T>(string url, object request, IDictionary<string, object> uriVariables) where T : class;
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> PostForMessage<T>(Uri url, object request) where T : class;
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The HTTP response message with no entity.</returns>
HttpResponseMessage PostForMessage(string url, object request, params object[] uriVariables);
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The HTTP response message with no entity.</returns>
HttpResponseMessage PostForMessage(string url, object request, IDictionary<string, object> uriVariables);
/// <summary>
/// Create a new resource by POSTing the given object to the URI template,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <returns>The HTTP response message with no entity.</returns>
HttpResponseMessage PostForMessage(Uri url, object request);
#endregion
#region PUT
/// <summary>
/// Create or update a resource by PUTting the given object to the URI.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given URI variables, if any.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
void Put(string url, object request, params object[] uriVariables);
/// <summary>
/// Create or update a resource by PUTting the given object to the URI.
/// </summary>
/// <remarks>
/// <para>
/// URI Template variables are expanded using the given dictionary.
/// </para>
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
void Put(string url, object request, IDictionary<string, object> uriVariables);
/// <summary>
/// Create or update a resource by PUTting the given object to the URI.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="request">
/// The object to be POSTed, may be a <see cref="HttpEntity"/> in order to add additional HTTP headers.
/// </param>
void Put(Uri url, object request);
#endregion
#region DELETE
/// <summary>
/// Delete the resources at the specified URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The variables to expand the template.</param>
void Delete(string url, params object[] uriVariables);
/// <summary>
/// Delete the resources at the specified URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
void Delete(string url, IDictionary<string, object> uriVariables);
/// <summary>
/// Delete the resources at the specified URI.
/// </summary>
/// <param name="url">The URL.</param>
void Delete(Uri url);
#endregion
#region OPTIONS
/// <summary>
/// Return the value of the Allow header for the given URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The value of the allow header.</returns>
IList<HttpMethod> OptionsForAllow(string url, params object[] uriVariables);
/// <summary>
/// Return the value of the Allow header for the given URI.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The value of the allow header.</returns>
IList<HttpMethod> OptionsForAllow(string url, IDictionary<string, object> uriVariables);
/// <summary>
/// Return the value of the Allow header for the given URI.
/// </summary>
/// <param name="url">The URL.</param>
/// <returns>The value of the allow header.</returns>
IList<HttpMethod> OptionsForAllow(Uri url);
#endregion
#region Exchange
/// <summary>
/// Execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> Exchange<T>(string url, HttpMethod method, HttpEntity requestEntity, params object[] uriVariables) where T : class;
/// <summary>
/// Execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> Exchange<T>(string url, HttpMethod method, HttpEntity requestEntity, IDictionary<string, object> uriVariables) where T : class;
/// <summary>
/// Execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response as <see cref="HttpResponseMessage{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <returns>The HTTP response message.</returns>
HttpResponseMessage<T> Exchange<T>(Uri url, HttpMethod method, HttpEntity requestEntity) where T : class;
/// <summary>
/// Execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>The HTTP response message with no entity.</returns>
HttpResponseMessage Exchange(string url, HttpMethod method, HttpEntity requestEntity, params object[] uriVariables);
/// <summary>
/// Execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>The HTTP response message with no entity.</returns>
HttpResponseMessage Exchange(string url, HttpMethod method, HttpEntity requestEntity, IDictionary<string, object> uriVariables);
/// <summary>
/// Execute the HTTP method to the given URI template, writing the given request message to the request,
/// and returns the response with no entity as <see cref="HttpResponseMessage"/>.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestEntity">
/// The HTTP entity (headers and/or body) to write to the request, may be <see langword="null"/>.
/// </param>
/// <returns>The HTTP response message with no entity.</returns>
HttpResponseMessage Exchange(Uri url, HttpMethod method, HttpEntity requestEntity);
#endregion
#region General execution
/// <summary>
/// Execute the HTTP method to the given URI template, preparing the request with the
/// <see cref="IRequestCallback"/>, and reading the response with an <see cref="IResponseExtractor{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given URI variables, if any.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestCallback">Object that prepares the request.</param>
/// <param name="responseExtractor">Object that extracts the return value from the response.</param>
/// <param name="uriVariables">The variables to expand the template.</param>
/// <returns>An arbitrary object, as returned by the <see cref="IResponseExtractor{T}"/>.</returns>
T Execute<T>(string url, HttpMethod method, IRequestCallback requestCallback, IResponseExtractor<T> responseExtractor, params object[] uriVariables) where T : class;
/// <summary>
/// Execute the HTTP method to the given URI template, preparing the request with the
/// <see cref="IRequestCallback"/>, and reading the response with an <see cref="IResponseExtractor{T}"/>.
/// </summary>
/// <remarks>
/// URI Template variables are expanded using the given dictionary.
/// </remarks>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestCallback">Object that prepares the request.</param>
/// <param name="responseExtractor">Object that extracts the return value from the response.</param>
/// <param name="uriVariables">The dictionary containing variables for the URI template.</param>
/// <returns>An arbitrary object, as returned by the <see cref="IResponseExtractor{T}"/>.</returns>
T Execute<T>(string url, HttpMethod method, IRequestCallback requestCallback, IResponseExtractor<T> responseExtractor, IDictionary<string, object> uriVariables) where T : class;
/// <summary>
/// Execute the HTTP method to the given URI template, preparing the request with the
/// <see cref="IRequestCallback"/>, and reading the response with an <see cref="IResponseExtractor{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <param name="url">The URL.</param>
/// <param name="method">The HTTP method (GET, POST, etc.)</param>
/// <param name="requestCallback">Object that prepares the request.</param>
/// <param name="responseExtractor">Object that extracts the return value from the response.</param>
/// <returns>An arbitrary object, as returned by the <see cref="IResponseExtractor{T}"/>.</returns>
T Execute<T>(Uri url, HttpMethod method, IRequestCallback requestCallback, IResponseExtractor<T> responseExtractor) where T : class;
#endregion
}
}
#endif

View File

@@ -1,68 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.ComponentModel;
namespace Spring.Http.Rest
{
// TODO: Rename this to RestOperationCompletedEventArgs or RestAsyncCompletedEventArgs ?
/// <summary>
/// Provides data when an asynchronous REST operation completes.
/// </summary>
/// <typeparam name="T">The type of the response value.</typeparam>
/// <see cref="IRestAsyncOperations"/>
/// <see cref="RestTemplate"/>
public class MethodCompletedEventArgs<T> : AsyncCompletedEventArgs where T : class
{
private T response;
/// <summary>
/// Gest the response of the REST operation.
/// </summary>
/// <exception cref="System.InvalidOperationException">If the operation was canceled.</exception>
/// <exception cref="System.Reflection.TargetInvocationException">If the operation failed.</exception>
public T Response
{
get
{
// Raise an exception if the operation failed or was canceled.
base.RaiseExceptionIfNecessary();
// If the operation was successful, return the value.
return response;
}
}
/// <summary>
/// Creates a new instance of <see cref="MethodCompletedEventArgs{T}"/>.
/// </summary>
/// <param name="response">The response of the REST operation.</param>
/// <param name="exception">Any error that occurred during the asynchronous operation.</param>
/// <param name="cancelled">A value indicating whether the asynchronous operation was canceled.</param>
/// <param name="userState">The optional user-supplied state object.</param>
public MethodCompletedEventArgs(T response, Exception exception, bool cancelled, object userState)
: base(exception, cancelled, userState)
{
this.response = response;
}
}
}

View File

@@ -1,86 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Runtime.Serialization;
namespace Spring.Http.Rest
{
/// <summary>
/// Base class for exceptions thrown by <see cref="RestTemplate"/> whenever it encounters client-side HTTP errors.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
#if !SILVERLIGHT
[Serializable]
#endif
public class RestClientException : Exception
{
/// <summary>
/// Creates a new instance of the <see cref="RestClientException"/> class.
/// </summary>
public RestClientException()
{
}
/// <summary>
/// Creates a new instance of the <see cref="RestClientException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
public RestClientException(string message)
: base(message)
{
}
/// <summary>
/// Creates a new instance of the <see cref="RestClientException"/> class.
/// </summary>
/// <param name="message">
/// A message about the exception.
/// </param>
/// <param name="rootCause">
/// The root exception that is being wrapped.
/// </param>
public RestClientException(string message, Exception rootCause)
: base(message, rootCause)
{
}
#if !SILVERLIGHT
/// <summary>
/// Creates a new instance of the <see cref="RestClientException"/> class.
/// </summary>
/// <param name="info">
/// The <see cref="System.Runtime.Serialization.SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="System.Runtime.Serialization.StreamingContext"/>
/// that contains contextual information about the source or destination.
/// </param>
protected RestClientException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,121 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using Spring.Util;
using Spring.Http.Client;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support
{
/// <summary>
/// Request callback implementation that prepares the request's accept headers.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class AcceptHeaderRequestCallback : IRequestCallback
{
#region Logging
#if !SILVERLIGHT
private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(AcceptHeaderRequestCallback));
#endif
#endregion
/// <summary>
/// The expected response body type.
/// </summary>
protected Type responseType;
/// <summary>
/// The list of <see cref="IHttpMessageConverter"/> to use.
/// </summary>
protected IList<IHttpMessageConverter> messageConverters;
/// <summary>
/// Creates a new instance of <see cref="AcceptHeaderRequestCallback"/>.
/// </summary>
/// <param name="responseType">The expected response body type.</param>
/// <param name="messageConverters">The list of <see cref="IHttpMessageConverter"/> to use.</param>
public AcceptHeaderRequestCallback(Type responseType, IList<IHttpMessageConverter> messageConverters)
{
this.responseType = responseType;
this.messageConverters = messageConverters;
}
#region IRequestCallback Membres
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an <see cref="IClientHttpRequest"/> to write data.
/// </summary>
/// <remarks>
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </remarks>
/// <param name="request">The active HTTP request.</param>
public virtual void DoWithRequest(IClientHttpRequest request)
{
if (responseType != null)
{
List<MediaType> allSupportedMediaTypes = new List<MediaType>();
foreach (IHttpMessageConverter messageConverter in this.messageConverters)
{
if (messageConverter.CanRead(responseType, null))
{
foreach (MediaType supportedMediaType in messageConverter.SupportedMediaTypes)
{
if (StringUtils.HasText(supportedMediaType.CharSet))
{
allSupportedMediaTypes.Add(new MediaType(
supportedMediaType.Type, supportedMediaType.Subtype));
}
else
{
allSupportedMediaTypes.Add(supportedMediaType);
}
}
}
}
if (allSupportedMediaTypes.Count > 0)
{
MediaType.SortBySpecificity(allSupportedMediaTypes);
#region Instrumentation
#if !SILVERLIGHT
if (LOG.IsDebugEnabled)
{
LOG.Debug(String.Format(
"Setting request Accept header to '{0}'",
MediaType.ToString(allSupportedMediaTypes)));
}
#endif
#endregion
request.Headers.Accept = allSupportedMediaTypes.ToArray();
}
}
}
#endregion
}
}

View File

@@ -1,96 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using Spring.Http.Client;
namespace Spring.Http.Rest.Support
{
/// <summary>
/// Default implementation of the <see cref="IResponseErrorHandler"/> interface.
/// </summary>
/// <remarks>
/// <para>
/// This error handler checks for the status code on the <see cref="IClientHttpResponse"/> :
/// any client code error (4xx) or server code error (5xx) is considered to be an error.
/// </para>
/// <para>
/// This behavior can be changed by overriding the <see cref="M:HasError(HttpStatusCode)"/> method.
/// </para>
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class DefaultResponseErrorHandler : IResponseErrorHandler
{
#region IResponseErrorHandler Members
/// <summary>
/// Indicates whether the given response has any errors.
/// </summary>
/// <remarks>
/// This implementation delegates to <see cref="M:HasError(HttpStatusCode)"/>
/// with the response status code.
/// </remarks>
/// <param name="response">The response to inspect.</param>
/// <returns>
/// <see langword="true"/> if the response has an error; otherwise <see langword="false"/>.
/// </returns>
public virtual bool HasError(IClientHttpResponse response)
{
return this.HasError(response.StatusCode);
}
/// <summary>
/// Handles the error in the given response.
/// This method is only called when <see cref="M:HasError"/> has returned <see langword="true"/>.
/// </summary>
/// <param name="response">The response with the error</param>
public virtual void HandleError(IClientHttpResponse response)
{
int type = (int)response.StatusCode / 100;
switch (type)
{
case 4 :
throw new HttpClientErrorException(response.StatusCode, response.StatusDescription);
case 5:
throw new HttpServerErrorException(response.StatusCode, response.StatusDescription);
default :
throw new HttpStatusCodeException(response.StatusCode, response.StatusDescription);
}
}
#endregion
/// <summary>
/// Checks if the given status code is a client code error (4xx) or a server code error (5xx).
/// </summary>
/// <param name="statusCode">The HTTP status code.</param>
/// <returns>
/// <see langword="true"/> if the response has an error; otherwise <see langword="false"/>.
/// </returns>
protected virtual bool HasError(HttpStatusCode statusCode)
{
int type = (int)statusCode / 100;
return type == 4 || type == 5;
}
}
}

View File

@@ -1,45 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
using Spring.Http.Client;
namespace Spring.Http.Rest.Support
{
/// <summary>
/// Response extractor that extracts the response HTTP headers.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class HeadersResponseExtractor : IResponseExtractor<HttpHeaders>
{
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an opened <see cref="IClientHttpResponse"/> to extract data.
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </summary>
/// <param name="response">The active HTTP request.</param>
public HttpHeaders ExtractData(IClientHttpResponse response)
{
return response.Headers;
}
}
}

View File

@@ -1,147 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using Spring.Http.Client;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support
{
/// <summary>
/// Request callback implementation that writes the given object to the request stream.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class HttpEntityRequestCallback : AcceptHeaderRequestCallback
{
#region Logging
#if !SILVERLIGHT
private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(HttpEntityRequestCallback));
#endif
#endregion
private HttpEntity requestEntity;
/// <summary>
/// Creates a new instance of <see cref="HttpEntityRequestCallback"/>.
/// </summary>
/// <param name="requestBody">
/// The object to write to the request.
/// Can be a <see cref="HttpEntity"/> in order to add additional HTTP headers to the request.
/// </param>
/// <param name="messageConverters">The list of <see cref="IHttpMessageConverter"/> to use.</param>
public HttpEntityRequestCallback(object requestBody, IList<IHttpMessageConverter> messageConverters) :
this(requestBody, null, messageConverters)
{
}
/// <summary>
/// Creates a new instance of <see cref="HttpEntityRequestCallback"/>.
/// </summary>
/// <param name="requestBody">The object to write to the request.</param>
/// <param name="responseType">The expected response body type.</param>
/// <param name="messageConverters">The list of <see cref="IHttpMessageConverter"/> to use.</param>
public HttpEntityRequestCallback(object requestBody, Type responseType, IList<IHttpMessageConverter> messageConverters) :
base(responseType, messageConverters)
{
if (requestBody is HttpEntity)
{
this.requestEntity = (HttpEntity)requestBody;
}
else
{
this.requestEntity = new HttpEntity(requestBody);
}
}
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an <see cref="IClientHttpRequest"/> to write data.
/// </summary>
/// <remarks>
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </remarks>
/// <param name="request">The active HTTP request.</param>
public override void DoWithRequest(IClientHttpRequest request)
{
base.DoWithRequest(request);
// headers
foreach (string header in requestEntity.Headers)
{
request.Headers[header] = requestEntity.Headers[header];
}
// body
if (requestEntity.HasBody)
{
object requestBody = requestEntity.Body;
MediaType requestContentType = requestEntity.Headers.ContentType;
foreach (IHttpMessageConverter messageConverter in base.messageConverters)
{
if (messageConverter.CanWrite(requestBody.GetType(), requestContentType))
{
#region Instrumentation
#if !SILVERLIGHT
if (LOG.IsDebugEnabled)
{
if (requestContentType != null)
{
LOG.Debug(String.Format(
"Writing [{0}] as '{1}' using [{2}]",
requestBody, requestContentType, messageConverter));
}
else
{
LOG.Debug(String.Format(
"Writing [{0}] using [{1}]",
requestBody, messageConverter));
}
}
#endif
#endregion
messageConverter.Write(requestBody, requestContentType, request);
return;
}
}
string message = String.Format(
"Could not write request: no suitable IHttpMessageConverter found for request type [{0}]",
requestBody.GetType().FullName);
if (requestContentType != null)
{
message = String.Format("{0} and content type [{1}]", message, requestContentType);
}
throw new RestClientException(message);
}
else
{
if (request.Headers.ContentLength == -1)
{
request.Headers.ContentLength = 0;
}
}
}
}
}

View File

@@ -1,44 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
using Spring.Http.Client;
namespace Spring.Http.Rest.Support
{
/// <summary>
/// Response extractor that extracts the HTTP response message with no body.
/// </summary>
/// <author>Bruno Baia</author>
public class HttpMessageResponseExtractor : IResponseExtractor<HttpResponseMessage>
{
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an opened <see cref="IClientHttpResponse"/> to extract data.
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </summary>
/// <param name="response">The active HTTP request.</param>
public HttpResponseMessage ExtractData(IClientHttpResponse response)
{
return new HttpResponseMessage(response.Headers, response.StatusCode, response.StatusDescription);
}
}
}

View File

@@ -1,59 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System.Net;
using System.Collections.Generic;
using Spring.Http.Client;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support
{
/// <summary>
/// Response extractor that extracts the HTTP response message with no body.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class HttpMessageResponseExtractor<T> : IResponseExtractor<HttpResponseMessage<T>> where T : class
{
private MessageConverterResponseExtractor<T> httpMessageConverterExtractor;
/// <summary>
/// Creates a new instance of the <see cref="HttpMessageResponseExtractor{T}"/> class.
/// </summary>
/// <param name="messageConverters">The list of <see cref="IHttpMessageConverter"/> to use.</param>
public HttpMessageResponseExtractor(IList<IHttpMessageConverter> messageConverters)
{
httpMessageConverterExtractor = new MessageConverterResponseExtractor<T>(messageConverters);
}
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an opened <see cref="IClientHttpResponse"/> to extract data.
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </summary>
/// <param name="response">The active HTTP request.</param>
public HttpResponseMessage<T> ExtractData(IClientHttpResponse response)
{
T body = httpMessageConverterExtractor.ExtractData(response);
return new HttpResponseMessage<T>(body, response.Headers, response.StatusCode, response.StatusDescription);
}
}
}

View File

@@ -1,92 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Net;
using System.Collections.Generic;
using Spring.Util;
using Spring.Http.Client;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support
{
/// <summary>
/// Response extractor that uses the given HTTP message converters to convert the response into a type.
/// </summary>
/// <typeparam name="T">The response body type.</typeparam>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class MessageConverterResponseExtractor<T> : IResponseExtractor<T> where T : class
{
#region Logging
#if !SILVERLIGHT
private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(MessageConverterResponseExtractor<T>));
#endif
#endregion
private IList<IHttpMessageConverter> messageConverters;
/// <summary>
/// Creates a new instance of the <see cref="MessageConverterResponseExtractor{T}"/> class.
/// </summary>
/// <param name="messageConverters">The list of <see cref="IHttpMessageConverter"/> to use.</param>
public MessageConverterResponseExtractor(IList<IHttpMessageConverter> messageConverters)
{
this.messageConverters = messageConverters;
}
/// <summary>
/// Gets called by <see cref="RestTemplate"/> with an opened <see cref="IClientHttpResponse"/> to extract data.
/// Does not need to care about closing the request or about handling errors:
/// this will all be handled by the <see cref="RestTemplate"/> class.
/// </summary>
/// <param name="response">The active HTTP request.</param>
public T ExtractData(IClientHttpResponse response)
{
MediaType mediaType = response.Headers.ContentType;
if (mediaType == null)
{
throw new RestClientException("Could not extract response: no Content-Type found");
}
foreach(IHttpMessageConverter messageConverter in messageConverters)
{
if (messageConverter.CanRead(typeof(T), mediaType))
{
#region Instrumentation
#if !SILVERLIGHT
if (LOG.IsDebugEnabled)
{
LOG.Debug(String.Format(
"Reading [{0}] as '{1}' using [{2}]",
typeof(T).FullName, mediaType, messageConverter));
}
#endif
#endregion
return messageConverter.Read<T>(response);
}
}
throw new RestClientException(String.Format(
"Could not extract response: no suitable HttpMessageConverter found for response type [{0}] and content type [{1}]",
typeof(T).FullName, mediaType));
}
}
}

View File

@@ -1,158 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EE04EC0F-4B1F-1D13-B30F-00FAC04F79BC}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ApplicationIcon>
</ApplicationIcon>
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>Spring.Http</AssemblyName>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<OutputType>Library</OutputType>
<RootNamespace>Spring</RootNamespace>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<StartupObject>
</StartupObject>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2005\Spring.Http\Debug\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG;NET_2_0</DefineConstants>
<DocumentationFile>Spring.Http.xml</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2005\Spring.Http\Release\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;NET_2_0</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>true</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>none</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common.Logging, Version=2.1.0.0, Culture=neutral, PublicKeyToken=65e474d141e25e07, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\Common.Logging.dll</HintPath>
</Reference>
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>CommonAssemblyInfo.cs</Link>
<SubType>Code</SubType>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Collections\Specialized\NameValueCollection.cs" />
<Compile Include="Http\Client\ExecuteCompletedEventArgs.cs" />
<Compile Include="Http\Converters\FileInfoHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FormHttpMessageConverter.cs" />
<Compile Include="Http\Converters\HttpMessageConversionException.cs" />
<Compile Include="Http\Converters\HttpMessageNotReadableException.cs" />
<Compile Include="Http\Converters\HttpMessageNotWritableException.cs" />
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\AbstractFeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Json\JsonHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\AbstractXmlHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XElementHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlDocumentHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlSerializableHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\DataContractHttpMessageConverter.cs" />
<Compile Include="Http\Client\IClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\IClientHttpResponse.cs" />
<Compile Include="Http\HttpEntity.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\HttpEntity`1.cs" />
<Compile Include="Http\HttpHeaders.cs" />
<Compile Include="Http\HttpResponseMessage.cs" />
<Compile Include="Http\HttpResponseMessage`1.cs" />
<Compile Include="Http\Client\IClientHttpRequest.cs" />
<Compile Include="Http\IHttpInputMessage.cs" />
<Compile Include="Http\IHttpOutputMessage.cs" />
<Compile Include="Http\Rest\HttpClientErrorException.cs" />
<Compile Include="Http\Rest\HttpServerErrorException.cs" />
<Compile Include="Http\Rest\HttpStatusCodeException.cs" />
<Compile Include="Http\Rest\IResponseErrorHandler.cs" />
<Compile Include="Http\Rest\IRestAsyncOperations.cs" />
<Compile Include="Http\Rest\MethodCompletedEventArgs.cs" />
<Compile Include="Http\Rest\Support\AcceptHeaderRequestCallback.cs" />
<Compile Include="Http\Rest\Support\DefaultResponseErrorHandler.cs" />
<Compile Include="Http\Rest\Support\HttpEntityRequestCallback.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor`1.cs" />
<Compile Include="Http\Rest\Support\HeadersResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor.cs" />
<Compile Include="Http\Converters\AbstractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\ByteArrayHttpMessageConverter.cs" />
<Compile Include="Http\Rest\Support\MessageConverterResponseExtractor.cs" />
<Compile Include="Http\HttpMethod.cs" />
<Compile Include="Http\Converters\IHttpMessageConverter.cs" />
<Compile Include="Http\Rest\IRequestCallback.cs" />
<Compile Include="Http\Rest\IResponseExtractor.cs" />
<Compile Include="Http\Rest\IRestOperations.cs" />
<Compile Include="Http\MediaType.cs" />
<Compile Include="Http\Rest\RestClientException.cs" />
<Compile Include="Http\Rest\RestTemplate.cs" />
<Compile Include="Http\Converters\StringHttpMessageConverter.cs" />
<Compile Include="Http\Client\WebClientHttpRequest.cs" />
<Compile Include="Http\Client\WebClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\WebClientHttpResponse.cs" />
<Compile Include="Util\AssertUtils.cs" />
<Compile Include="Util\IoUtils.cs" />
<Compile Include="Util\StringUtils.cs" />
<Compile Include="Util\UriTemplate.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -1,132 +0,0 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5A955F0B-EEC7-427C-9E6B-A26B8B51558D}</ProjectGuid>
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Spring</RootNamespace>
<AssemblyName>Spring.Http</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<SilverlightApplication>false</SilverlightApplication>
<ValidateXaml>true</ValidateXaml>
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\build\VS.Net.2008-SL\Spring.Http\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;SILVERLIGHT_3</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>Spring.Http.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\build\VS.Net.2008-SL\Spring.Http\Release\</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT;SILVERLIGHT_3</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Windows" />
<Reference Include="mscorlib" />
<Reference Include="system" />
<Reference Include="System.Core" />
<Reference Include="System.Xml" />
<Reference Include="System.Net" />
<Reference Include="System.Windows.Browser" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Collections\Specialized\NameValueCollection.cs" />
<Compile Include="Http\Client\IClientHttpRequest.cs" />
<Compile Include="Http\Client\IClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\IClientHttpResponse.cs" />
<Compile Include="Http\Client\ExecuteCompletedEventArgs.cs" />
<Compile Include="Http\Client\WebClientHttpRequest.cs" />
<Compile Include="Http\Client\WebClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\WebClientHttpResponse.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\AbstractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\ByteArrayHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\AbstractFeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FileInfoHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FormHttpMessageConverter.cs" />
<Compile Include="Http\Converters\HttpMessageConversionException.cs" />
<Compile Include="Http\Converters\HttpMessageNotReadableException.cs" />
<Compile Include="Http\Converters\HttpMessageNotWritableException.cs" />
<Compile Include="Http\Converters\IHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Json\JsonHttpMessageConverter.cs" />
<Compile Include="Http\Converters\StringHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\AbstractXmlHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\DataContractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XElementHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlDocumentHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlSerializableHttpMessageConverter.cs" />
<Compile Include="Http\HttpEntity.cs" />
<Compile Include="Http\HttpEntity`1.cs" />
<Compile Include="Http\HttpHeaders.cs" />
<Compile Include="Http\HttpMethod.cs" />
<Compile Include="Http\HttpResponseMessage.cs" />
<Compile Include="Http\HttpResponseMessage`1.cs" />
<Compile Include="Http\IHttpInputMessage.cs" />
<Compile Include="Http\IHttpOutputMessage.cs" />
<Compile Include="Http\MediaType.cs" />
<Compile Include="Http\Rest\MethodCompletedEventArgs.cs" />
<Compile Include="Http\Rest\HttpClientErrorException.cs" />
<Compile Include="Http\Rest\HttpServerErrorException.cs" />
<Compile Include="Http\Rest\HttpStatusCodeException.cs" />
<Compile Include="Http\Rest\IRequestCallback.cs" />
<Compile Include="Http\Rest\IResponseErrorHandler.cs" />
<Compile Include="Http\Rest\IResponseExtractor.cs" />
<Compile Include="Http\Rest\IRestAsyncOperations.cs" />
<Compile Include="Http\Rest\IRestOperations.cs" />
<Compile Include="Http\Rest\RestClientException.cs" />
<Compile Include="Http\Rest\RestTemplate.cs" />
<Compile Include="Http\Rest\Support\AcceptHeaderRequestCallback.cs" />
<Compile Include="Http\Rest\Support\DefaultResponseErrorHandler.cs" />
<Compile Include="Http\Rest\Support\HeadersResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpEntityRequestCallback.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor`1.cs" />
<Compile Include="Http\Rest\Support\MessageConverterResponseExtractor.cs" />
<Compile Include="Util\AssertUtils.cs" />
<Compile Include="Util\IoUtils.cs" />
<Compile Include="Util\StringUtils.cs" />
<Compile Include="Util\UriTemplate.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\v3.0\Microsoft.Silverlight.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties />
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -1,176 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FAC04F79-4B1F-1D13-B30F-00EE04EC0FBC}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ApplicationIcon>
</ApplicationIcon>
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>Spring.Http</AssemblyName>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<OutputType>Library</OutputType>
<RootNamespace>Spring</RootNamespace>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<StartupObject>
</StartupObject>
<SignAssembly>false</SignAssembly>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkSubset>
</TargetFrameworkSubset>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2008\Spring.Http\Debug\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG;NET_2_0;NET_3_0;NET_3_5</DefineConstants>
<DocumentationFile>Spring.Http.xml</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2008\Spring.Http\Release\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;NET_2_0;NET_3_0;NET_3_5</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>true</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>none</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common.Logging, Version=2.1.0.0, Culture=neutral, PublicKeyToken=65e474d141e25e07, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\Common.Logging.dll</HintPath>
</Reference>
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.ServiceModel.Web">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>CommonAssemblyInfo.cs</Link>
<SubType>Code</SubType>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Collections\Specialized\NameValueCollection.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Client\ExecuteCompletedEventArgs.cs" />
<Compile Include="Http\Client\IClientHttpRequest.cs" />
<Compile Include="Http\Client\IClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\IClientHttpResponse.cs" />
<Compile Include="Http\Client\WebClientHttpRequest.cs" />
<Compile Include="Http\Client\WebClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\WebClientHttpResponse.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\FileInfoHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FormHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\HttpMessageNotReadableException.cs" />
<Compile Include="Http\Converters\HttpMessageNotWritableException.cs" />
<Compile Include="Http\Converters\HttpMessageConversionException.cs" />
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\AbstractFeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Json\JsonHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\AbstractXmlHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XElementHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlDocumentHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlSerializableHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\DataContractHttpMessageConverter.cs" />
<Compile Include="Http\IHttpInputMessage.cs" />
<Compile Include="Http\HttpEntity.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\HttpEntity`1.cs" />
<Compile Include="Http\HttpHeaders.cs" />
<Compile Include="Http\HttpResponseMessage.cs" />
<Compile Include="Http\HttpResponseMessage`1.cs" />
<Compile Include="Http\IHttpOutputMessage.cs" />
<Compile Include="Http\Rest\HttpClientErrorException.cs" />
<Compile Include="Http\Rest\HttpServerErrorException.cs" />
<Compile Include="Http\Rest\HttpStatusCodeException.cs" />
<Compile Include="Http\Rest\IResponseErrorHandler.cs" />
<Compile Include="Http\Rest\IRestAsyncOperations.cs" />
<Compile Include="Http\Rest\MethodCompletedEventArgs.cs" />
<Compile Include="Http\Rest\Support\AcceptHeaderRequestCallback.cs" />
<Compile Include="Http\Rest\Support\DefaultResponseErrorHandler.cs" />
<Compile Include="Http\Rest\Support\HttpEntityRequestCallback.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor`1.cs" />
<Compile Include="Http\Rest\Support\HeadersResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor.cs" />
<Compile Include="Http\Converters\AbstractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\ByteArrayHttpMessageConverter.cs" />
<Compile Include="Http\Rest\Support\MessageConverterResponseExtractor.cs" />
<Compile Include="Http\HttpMethod.cs" />
<Compile Include="Http\Converters\IHttpMessageConverter.cs" />
<Compile Include="Http\Rest\IRequestCallback.cs" />
<Compile Include="Http\Rest\IResponseExtractor.cs" />
<Compile Include="Http\Rest\IRestOperations.cs" />
<Compile Include="Http\MediaType.cs" />
<Compile Include="Http\Rest\RestClientException.cs" />
<Compile Include="Http\Rest\RestTemplate.cs" />
<Compile Include="Http\Converters\StringHttpMessageConverter.cs" />
<Compile Include="Util\AssertUtils.cs" />
<Compile Include="Util\IoUtils.cs" />
<Compile Include="Util\StringUtils.cs" />
<Compile Include="Util\UriTemplate.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -1,139 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{01FA5AEB-20A3-42FF-B2E9-A2FE9A7236D1}</ProjectGuid>
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Spring</RootNamespace>
<AssemblyName>Spring.Http</AssemblyName>
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
<SilverlightApplication>false</SilverlightApplication>
<ValidateXaml>true</ValidateXaml>
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
</PropertyGroup>
<!-- This property group is only here to support building this project using the
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
to set the TargetFrameworkVersion to v3.5 -->
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\build\VS.Net.2010-SL\Spring.Http\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>Spring.Http.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\build\VS.Net.2010-SL\Spring.Http\Release\</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="system" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Windows" />
<Reference Include="System.Windows.Browser" />
<Reference Include="System.Xml" />
<Reference Include="System.Net" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Collections\Specialized\NameValueCollection.cs" />
<Compile Include="Http\Client\ExecuteCompletedEventArgs.cs" />
<Compile Include="Http\Client\IClientHttpRequest.cs" />
<Compile Include="Http\Client\IClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\IClientHttpResponse.cs" />
<Compile Include="Http\Client\WebClientHttpRequest.cs" />
<Compile Include="Http\Client\WebClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\WebClientHttpResponse.cs" />
<Compile Include="Http\Converters\AbstractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\ByteArrayHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\AbstractFeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FileInfoHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FormHttpMessageConverter.cs" />
<Compile Include="Http\Converters\HttpMessageConversionException.cs" />
<Compile Include="Http\Converters\HttpMessageNotReadableException.cs" />
<Compile Include="Http\Converters\HttpMessageNotWritableException.cs" />
<Compile Include="Http\Converters\IHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Json\JsonHttpMessageConverter.cs" />
<Compile Include="Http\Converters\StringHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\AbstractXmlHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\DataContractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XElementHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlDocumentHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlSerializableHttpMessageConverter.cs" />
<Compile Include="Http\HttpEntity.cs" />
<Compile Include="Http\HttpEntity`1.cs" />
<Compile Include="Http\HttpHeaders.cs" />
<Compile Include="Http\HttpMethod.cs" />
<Compile Include="Http\HttpResponseMessage.cs" />
<Compile Include="Http\HttpResponseMessage`1.cs" />
<Compile Include="Http\IHttpInputMessage.cs" />
<Compile Include="Http\IHttpOutputMessage.cs" />
<Compile Include="Http\MediaType.cs" />
<Compile Include="Http\Rest\HttpClientErrorException.cs" />
<Compile Include="Http\Rest\HttpServerErrorException.cs" />
<Compile Include="Http\Rest\HttpStatusCodeException.cs" />
<Compile Include="Http\Rest\IRequestCallback.cs" />
<Compile Include="Http\Rest\IResponseErrorHandler.cs" />
<Compile Include="Http\Rest\IResponseExtractor.cs" />
<Compile Include="Http\Rest\IRestAsyncOperations.cs" />
<Compile Include="Http\Rest\IRestOperations.cs" />
<Compile Include="Http\Rest\MethodCompletedEventArgs.cs" />
<Compile Include="Http\Rest\RestClientException.cs" />
<Compile Include="Http\Rest\RestTemplate.cs" />
<Compile Include="Http\Rest\Support\AcceptHeaderRequestCallback.cs" />
<Compile Include="Http\Rest\Support\DefaultResponseErrorHandler.cs" />
<Compile Include="Http\Rest\Support\HeadersResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpEntityRequestCallback.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor`1.cs" />
<Compile Include="Http\Rest\Support\MessageConverterResponseExtractor.cs" />
<Compile Include="Util\AssertUtils.cs" />
<Compile Include="Util\IoUtils.cs" />
<Compile Include="Util\StringUtils.cs" />
<Compile Include="Util\UriTemplate.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties />
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.20506</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{36227431-B822-461E-A7AF-651E34F23A8C}</ProjectGuid>
<ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Spring</RootNamespace>
<AssemblyName>Spring.Http</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
<TargetFrameworkProfile>WindowsPhone</TargetFrameworkProfile>
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
<SilverlightApplication>false</SilverlightApplication>
<ValidateXaml>true</ValidateXaml>
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\build\VS.Net.2010-WP\Spring.Http\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>Spring.Http.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\build\VS.Net.2010-WP\Spring.Http\Release\</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Servicemodel" />
<Reference Include="System.Servicemodel.Web" />
<Reference Include="System.Windows" />
<Reference Include="system" />
<Reference Include="System.Core" />
<Reference Include="System.Xml" />
<Reference Include="System.Net" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml.Serialization" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Collections\Specialized\NameValueCollection.cs" />
<Compile Include="Http\Client\ExecuteCompletedEventArgs.cs" />
<Compile Include="Http\Client\IClientHttpRequest.cs" />
<Compile Include="Http\Client\IClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\IClientHttpResponse.cs" />
<Compile Include="Http\Client\WebClientHttpRequest.cs" />
<Compile Include="Http\Client\WebClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\WebClientHttpResponse.cs" />
<Compile Include="Http\Converters\AbstractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\ByteArrayHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\AbstractFeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FileInfoHttpMessageConverter.cs" />
<Compile Include="Http\Converters\FormHttpMessageConverter.cs" />
<Compile Include="Http\Converters\HttpMessageConversionException.cs" />
<Compile Include="Http\Converters\HttpMessageNotReadableException.cs" />
<Compile Include="Http\Converters\HttpMessageNotWritableException.cs" />
<Compile Include="Http\Converters\IHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Json\JsonHttpMessageConverter.cs" />
<Compile Include="Http\Converters\StringHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\AbstractXmlHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\DataContractHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XElementHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlDocumentHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Xml\XmlSerializableHttpMessageConverter.cs" />
<Compile Include="Http\HttpEntity.cs" />
<Compile Include="Http\HttpEntity`1.cs" />
<Compile Include="Http\HttpHeaders.cs" />
<Compile Include="Http\HttpMethod.cs" />
<Compile Include="Http\HttpResponseMessage.cs" />
<Compile Include="Http\HttpResponseMessage`1.cs" />
<Compile Include="Http\IHttpInputMessage.cs" />
<Compile Include="Http\IHttpOutputMessage.cs" />
<Compile Include="Http\MediaType.cs" />
<Compile Include="Http\Rest\HttpClientErrorException.cs" />
<Compile Include="Http\Rest\HttpServerErrorException.cs" />
<Compile Include="Http\Rest\HttpStatusCodeException.cs" />
<Compile Include="Http\Rest\IRequestCallback.cs" />
<Compile Include="Http\Rest\IResponseErrorHandler.cs" />
<Compile Include="Http\Rest\IResponseExtractor.cs" />
<Compile Include="Http\Rest\IRestAsyncOperations.cs" />
<Compile Include="Http\Rest\IRestOperations.cs" />
<Compile Include="Http\Rest\MethodCompletedEventArgs.cs" />
<Compile Include="Http\Rest\RestClientException.cs" />
<Compile Include="Http\Rest\RestTemplate.cs" />
<Compile Include="Http\Rest\Support\AcceptHeaderRequestCallback.cs" />
<Compile Include="Http\Rest\Support\DefaultResponseErrorHandler.cs" />
<Compile Include="Http\Rest\Support\HeadersResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpEntityRequestCallback.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor`1.cs" />
<Compile Include="Http\Rest\Support\MessageConverterResponseExtractor.cs" />
<Compile Include="Util\AssertUtils.cs" />
<Compile Include="Util\IoUtils.cs" />
<Compile Include="Util\StringUtils.cs" />
<Compile Include="Util\UriTemplate.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
<ProjectExtensions />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,237 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ApplicationIcon>
</ApplicationIcon>
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>Spring.Http</AssemblyName>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<OutputType>Library</OutputType>
<RootNamespace>Spring</RootNamespace>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<StartupObject>
</StartupObject>
<SignAssembly>false</SignAssembly>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2010\Spring.Http\Debug\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>
<DocumentationFile>Spring.Http.xml</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2010\Spring.Http\Release\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>true</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>none</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common.Logging, Version=2.1.0.0, Culture=neutral, PublicKeyToken=65e474d141e25e07, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\Common.Logging.dll</HintPath>
</Reference>
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.configuration" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web" />
<Reference Include="System.XML" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>CommonAssemblyInfo.cs</Link>
<SubType>Code</SubType>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Collections\Specialized\NameValueCollection.cs" />
<Compile Include="Http\Client\ExecuteCompletedEventArgs.cs" />
<Compile Include="Http\Client\IClientHttpRequest.cs" />
<Compile Include="Http\Client\IClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\IClientHttpResponse.cs" />
<Compile Include="Http\Client\WebClientHttpRequest.cs" />
<Compile Include="Http\Client\WebClientHttpRequestFactory.cs" />
<Compile Include="Http\Client\WebClientHttpResponse.cs" />
<Compile Include="Http\Converters\AbstractHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\ByteArrayHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Feed\AbstractFeedHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\FileInfoHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\FormHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\HttpMessageConversionException.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\HttpMessageNotReadableException.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\HttpMessageNotWritableException.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\IHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Json\JsonHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\StringHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Xml\AbstractXmlHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Xml\DataContractHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Xml\XElementHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Xml\XmlDocumentHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\Converters\Xml\XmlSerializableHttpMessageConverter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Http\IHttpInputMessage.cs" />
<Compile Include="Http\IHttpOutputMessage.cs" />
<Compile Include="Http\HttpEntity.cs" />
<Compile Include="Http\HttpEntity`1.cs" />
<Compile Include="Http\HttpHeaders.cs" />
<Compile Include="Http\HttpResponseMessage.cs" />
<Compile Include="Http\HttpResponseMessage`1.cs" />
<Compile Include="Http\HttpMethod.cs" />
<Compile Include="Http\MediaType.cs" />
<Compile Include="Http\Rest\HttpClientErrorException.cs" />
<Compile Include="Http\Rest\HttpServerErrorException.cs" />
<Compile Include="Http\Rest\HttpStatusCodeException.cs" />
<Compile Include="Http\Rest\IRequestCallback.cs" />
<Compile Include="Http\Rest\IResponseErrorHandler.cs" />
<Compile Include="Http\Rest\IResponseExtractor.cs" />
<Compile Include="Http\Rest\IRestAsyncOperations.cs" />
<Compile Include="Http\Rest\IRestOperations.cs" />
<Compile Include="Http\Rest\MethodCompletedEventArgs.cs" />
<Compile Include="Http\Rest\RestClientException.cs" />
<Compile Include="Http\Rest\RestTemplate.cs" />
<Compile Include="Http\Rest\Support\AcceptHeaderRequestCallback.cs" />
<Compile Include="Http\Rest\Support\DefaultResponseErrorHandler.cs" />
<Compile Include="Http\Rest\Support\HttpEntityRequestCallback.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor`1.cs" />
<Compile Include="Http\Rest\Support\HeadersResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\HttpMessageResponseExtractor.cs" />
<Compile Include="Http\Rest\Support\MessageConverterResponseExtractor.cs" />
<Compile Include="Util\AssertUtils.cs" />
<Compile Include="Util\IoUtils.cs" />
<Compile Include="Util\StringUtils.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Util\UriTemplate.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -1,123 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Globalization;
namespace Spring.Util
{
// From Spring.Core
/// <summary>
/// Assertion utility methods that simplify things such as argument checks.
/// </summary>
/// <remarks>
/// <p>
/// Not intended to be used directly by applications.
/// </p>
/// </remarks>
/// <author>Aleksandar Seovic</author>
/// <author>Erich Eichinger</author>
internal sealed class AssertUtils
{
/// <summary>
/// Checks the value of the supplied <paramref name="argument"/> and throws an
/// <see cref="System.ArgumentNullException"/> if it is <see langword="null"/>.
/// </summary>
/// <param name="argument">The object to check.</param>
/// <param name="name">The argument name.</param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="argument"/> is <see langword="null"/>.
/// </exception>
internal static void ArgumentNotNull(object argument, string name)
{
if (argument == null)
{
throw new ArgumentNullException (name,
String.Format(CultureInfo.InvariantCulture, "Argument '{0}' cannot be null.", name));
}
}
/// <summary>
/// Checks the value of the supplied <paramref name="argument"/> and throws an
/// <see cref="System.ArgumentNullException"/> if it is <see langword="null"/>.
/// </summary>
/// <param name="argument">The object to check.</param>
/// <param name="name">The argument name.</param>
/// <param name="message">
/// An arbitrary message that will be passed to any thrown
/// <see cref="System.ArgumentNullException"/>.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="argument"/> is <see langword="null"/>.
/// </exception>
internal static void ArgumentNotNull(object argument, string name, string message)
{
if (argument == null)
{
throw new ArgumentNullException(name, message);
}
}
/// <summary>
/// Checks the value of the supplied string <paramref name="argument"/> and throws an
/// <see cref="System.ArgumentNullException"/> if it is <see langword="null"/> or
/// contains only whitespace character(s).
/// </summary>
/// <param name="argument">The string to check.</param>
/// <param name="name">The argument name.</param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="argument"/> is <see langword="null"/> or
/// contains only whitespace character(s).
/// </exception>
internal static void ArgumentHasText(string argument, string name)
{
if (!StringUtils.HasText(argument))
{
throw new ArgumentNullException(name,
String.Format (CultureInfo.InvariantCulture,
"Argument '{0}' cannot be null or resolve to an empty string : '{1}'.", name, argument));
}
}
/// <summary>
/// Checks the value of the supplied string <paramref name="argument"/> and throws an
/// <see cref="System.ArgumentNullException"/> if it is <see langword="null"/> or
/// contains only whitespace character(s).
/// </summary>
/// <param name="argument">The string to check.</param>
/// <param name="name">The argument name.</param>
/// <param name="message">
/// An arbitrary message that will be passed to any thrown
/// <see cref="System.ArgumentNullException"/>.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="argument"/> is <see langword="null"/> or
/// contains only whitespace character(s).
/// </exception>
internal static void ArgumentHasText(string argument, string name, string message)
{
if (!StringUtils.HasText(argument))
{
throw new ArgumentNullException(name, message);
}
}
}
}

View File

@@ -1,49 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.IO;
namespace Spring.Util
{
/// <summary>
/// Utility methods for IO handling.
/// </summary>
/// <author>Bruno Baia</author>
internal sealed class IoUtils
{
/// <summary>
/// Copies one stream into another.
/// </summary>
public static void CopyStream(Stream source, Stream destination)
{
#if NET_4_0
source.CopyTo(destination);
#else
int bytesCount;
byte[] buffer = new byte[0x1000];
while ((bytesCount = source.Read(buffer, 0, buffer.Length)) != 0)
{
destination.Write(buffer, 0, bytesCount);
}
#endif
}
}
}

View File

@@ -1,105 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
namespace Spring.Util
{
// From Spring.Core
/// <summary>
/// Miscellaneous <see cref="System.String"/> utility methods.
/// </summary>
/// <remarks>
/// <p>
/// Mainly for internal use within the framework.
/// </p>
/// </remarks>
/// <author>Rod Johnson</author>
/// <author>Juergen Hoeller</author>
/// <author>Keith Donald</author>
/// <author>Aleksandar Seovic (.NET)</author>
/// <author>Mark Pollack (.NET)</author>
/// <author>Rick Evans (.NET)</author>
/// <author>Erich Eichinger (.NET)</author>
internal sealed class StringUtils
{
/// <summary>Checks if a string has length.</summary>
/// <param name="target">
/// The string to check, may be <see langword="null"/>.
/// </param>
/// <returns>
/// <see langword="true"/> if the string has length and is not
/// <see langword="null"/>.
/// </returns>
/// <example>
/// <code lang="C#">
/// StringUtils.HasLength(null) = false
/// StringUtils.HasLength("") = false
/// StringUtils.HasLength(" ") = true
/// StringUtils.HasLength("Hello") = true
/// </code>
/// </example>
internal static bool HasLength(string target)
{
return (target != null && target.Length > 0);
}
/// <summary>
/// Checks if a <see cref="System.String"/> has text.
/// </summary>
/// <remarks>
/// <p>
/// More specifically, returns <see langword="true"/> if the string is
/// not <see langword="null"/>, it's <see cref="String.Length"/> is >
/// zero <c>(0)</c>, and it has at least one non-whitespace character.
/// </p>
/// </remarks>
/// <param name="target">
/// The string to check, may be <see langword="null"/>.
/// </param>
/// <returns>
/// <see langword="true"/> if the <paramref name="target"/> is not
/// <see langword="null"/>,
/// <see cref="String.Length"/> > zero <c>(0)</c>, and does not consist
/// solely of whitespace.
/// </returns>
/// <example>
/// <code language="C#">
/// StringUtils.HasText(null) = false
/// StringUtils.HasText("") = false
/// StringUtils.HasText(" ") = false
/// StringUtils.HasText("12345") = true
/// StringUtils.HasText(" 12345 ") = true
/// </code>
/// </example>
internal static bool HasText(string target)
{
if (target == null)
{
return false;
}
else
{
return HasLength(target.Trim());
}
}
}
}

View File

@@ -1,251 +0,0 @@
#region License
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed 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.
*/
#endregion
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
namespace Spring.Util
{
/// <summary>
/// Represents a URI template. An URI template is a URI-like String that contained variables
/// marked of in braces {}, which can be expanded to produce a URI.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Juergen Hoeller</author>
/// <author>Bruno Baia (.NET)</author>
public class UriTemplate
{
/** Captures URI template variable names. */
#if SILVERLIGHT
private static Regex VARIABLENAMES_REGEX = new Regex(@"\{([^/]+?)\}");
#else
private static Regex VARIABLENAMES_REGEX = new Regex(@"\{([^/]+?)\}", RegexOptions.Compiled);
#endif
/** Replaces template variables in the URI template. */
private static string VARIABLEVALUE_PATTERN = "(?<{0}>.*)";
private const string BRACE_LEFT = "{";
private const string BRACE_RIGHT = "}";
private string uriTemplate;
private string[] variableNames;
private Regex matchRegex;
/// <summary>
/// Gets the names of the variables in the template, in order.
/// </summary>
public string[] VariableNames
{
get { return this.variableNames; }
}
/// <summary>
/// Creates a new instance of <see cref="UriTemplate"/> with the given URI String.
/// </summary>
/// <param name="uriTemplate">The URI template string.</param>
public UriTemplate(string uriTemplate)
{
this.uriTemplate = uriTemplate;
Parser parser = new Parser(uriTemplate);
this.variableNames = parser.GetVariableNames();
this.matchRegex = parser.GetMatchRegex();
}
/// <summary>
/// Given the dictionary of variables, expands this template into a full URI.
/// The dictionary keys represent variable names, the dicitonary values variable values.
/// The order of variables is not significant.
/// </summary>
/// <example>
/// <code>
/// UriTemplate template = new UriTemplate("http://example.com/hotels/{hotel}/bookings/{booking}");
/// IDictionary&lt;string, object&gt; uriVariables = new Dictionary&lt;string, object&gt;();
/// uriVariables.Add("booking", "42");
/// uriVariables.Add("hotel", 1);
/// Console.Out.WriteLine(template.Expand(uriVariables));
/// </code>
/// will print: <blockquote>http://example.com/hotels/1/bookings/42</blockquote>
/// </example>
/// <param name="uriVariables">The dictionary of URI variables.</param>
/// <returns>The expanded URI</returns>
public Uri Expand(IDictionary<string, object> uriVariables)
{
if (uriVariables.Count != this.variableNames.Length)
{
throw new ArgumentException(String.Format(
"Invalid amount of variables values in '{0}': expected {1}; got {2}",
this.uriTemplate, this.variableNames.Length, uriVariables.Count));
}
string uri = this.uriTemplate;
foreach (string variableName in this.variableNames)
{
if (!uriVariables.ContainsKey(variableName))
{
throw new ArgumentException(String.Format(
"'uriVariables' dictionary has no value for '{0}'",
variableName));
}
uri = Replace(uri, variableName, uriVariables[variableName]);
}
return new Uri(uri, UriKind.RelativeOrAbsolute);
}
/// <summary>
/// Given an array of variables, expands this template into a full URI.
/// The array represent variable values. The order of variables is significant.
/// </summary>
/// <example>
/// <code>
/// UriTemplate template = new UriTemplate("http://example.com/hotels/{hotel}/bookings/{booking}");
/// Console.Out.WriteLine(template.Expand(1, "42"));
/// </code>
/// will print: <blockquote>http://example.com/hotels/1/bookings/42</blockquote>
/// </example>
/// <param name="uriVariableValues">The array of URI variables.</param>
/// <returns>The expanded URI</returns>
public Uri Expand(params object[] uriVariableValues)
{
if (uriVariableValues.Length != this.variableNames.Length)
{
throw new ArgumentException(String.Format(
"Invalid amount of variables values in '{0}': expected {1}; got {2}",
this.uriTemplate, this.variableNames.Length, uriVariableValues.Length));
}
string uri = this.uriTemplate;
for (int i = 0; i < this.variableNames.Length; i++)
{
uri = Replace(uri, this.variableNames[i], uriVariableValues[i]);
}
return new Uri(uri, UriKind.RelativeOrAbsolute);
}
/// <summary>
/// Indicates whether the given URI matches this template.
/// </summary>
/// <param name="uri">The URI to match to.</param>
/// <returns><see langword="true"/> if it matches; otherwise <see langword="false"/></returns>
public bool Matches(string uri)
{
if (uri == null)
{
return false;
}
return this.matchRegex.IsMatch(uri);
}
/// <summary>
/// Match the given URI to a dictionary of variable values. Keys in the returned map are variable names,
/// values are variable values, as occurred in the given URI
/// </summary>
/// <example>
/// <code>
/// UriTemplate template = new UriTemplate("http://example.com/hotels/{hotel}/bookings/{booking}");
/// Console.Out.WriteLine(template.Match("http://example.com/hotels/1/bookings/42"));
/// </code>
/// will print: <blockquote>{hotel=1, booking=42}</blockquote>
/// </example>
/// <param name="uri">The URI to match to.</param>
/// <returns>A dictionary of variable values.</returns>
public IDictionary<string, string> Match(string uri)
{
AssertUtils.ArgumentNotNull(uri, "uri");
IDictionary<string, string> result = new Dictionary<string, string>();
Match match = this.matchRegex.Match(uri);
for (int i = 1; i < match.Groups.Count; i++ )
{
result.Add(this.matchRegex.GroupNameFromNumber(i), match.Groups[i].Value);
}
return result;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object."/>
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object."/>.
/// </returns>
public override string ToString()
{
return this.uriTemplate;
}
private static string Replace(string uriTemplate, string token, object value)
{
string quotedToken = BRACE_LEFT + token + BRACE_RIGHT;
return uriTemplate.Replace(quotedToken, (value == null) ? String.Empty : value.ToString());
}
// Static inner class to parse uri template strings into a matching regular expression.
private class Parser
{
private List<String> variableNames = new List<String>();
private StringBuilder patternBuilder = new StringBuilder();
public Parser(string uriTemplate)
{
AssertUtils.ArgumentNotNull(uriTemplate, "'uriTemplate' must not be null");
int index = 0;
this.patternBuilder.Append("^");
foreach (Match match in VARIABLENAMES_REGEX.Matches(uriTemplate))
{
string variableName = match.Groups[1].Value;
if (!variableNames.Contains(variableName))
{
variableNames.Add(variableName);
}
this.patternBuilder.Append(Escape(uriTemplate, index, match.Index - index));
this.patternBuilder.Append(String.Format(VARIABLEVALUE_PATTERN, variableName));
index = match.Index + match.Length;
}
this.patternBuilder.Append(Escape(uriTemplate, index, uriTemplate.Length - index));
this.patternBuilder.Append("$");
}
private static string Escape(String fullPath, int start, int end)
{
if (start == end)
{
return "";
}
return Regex.Escape(fullPath.Substring(start, end));
}
public string[] GetVariableNames()
{
return this.variableNames.ToArray();
}
public Regex GetMatchRegex()
{
return new Regex(this.patternBuilder.ToString());
}
}
}
}