using System;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceModel.Web;
using System.Xml;
using System.ServiceModel;
using System.ServiceModel.Channels;
#if ORCASB2
using HttpBodyFormatMessagePropertySystem.ServiceModel.Channels.HttpBodyFormatMessageProperty;
#endif
namespace dasBlog.Storage{
public class WebStorageNode : IWebStorageNode
{
StorageBus storageBus;
public WebStorageNode()
{
this.storageBus = StorageBus.Current;
}
private XmlReader GetSchemaInternal(string scopeid, string nodeName, string xsd)
{
Moniker uri = new Moniker(scopeid, new PathSegmentName(nodeName));
IStorageNode node = storageBus.FindNode(uri);
if (node != null)
{
var ut = new UriTemplate("/{scopeid}/{node}/");
var ui = ut.BindByPosition(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri,
scopeid, nodeName);
return node.GetItemSchema(ui.ToString(), xsd).GetReaderAtBodyContents();
}
return null;
}
public Message Select(string scopeid, string nodeName)
{
var replyAction = OperationContext.Current.EndpointDispatcher.DispatchRuntime.Operations["Select"].ReplyAction;
if (WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters.AllKeys.Contains("xsd") ||
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters[null] == "xsd")
{
return Message.CreateMessage(
OperationContext.Current.IncomingMessageVersion,
replyAction,
GetSchemaInternal(scopeid, nodeName, WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["xsd"]));
}
else
{
return Message.CreateMessage(
OperationContext.Current.IncomingMessageVersion,
replyAction,
SelectInternal(new Moniker(scopeid, new PathSegmentName(nodeName))));
}
}
private XmlReader SelectInternal(Moniker moniker)
{
QueryDescription query = null;
var queryParameters = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
string format = queryParameters["format"];
string pag = queryParameters["pag"];
if (format == "json")
{
OperationContext.Current.OutgoingMessageProperties.Add(
HttpBodyFormatMessageProperty.Name,
new HttpBodyFormatMessageProperty(WebContentFormat.Json));
}
if (pag != null)
{
return Aggregate(moniker, pag);
}
else
{
string queryName = queryParameters["q"];
if (queryName != null)
{
query = new QueryDescription(
queryName,
(from string key in queryParameters.Keys where key != "q" && key != "format" select new QueryArgument(key, queryParameters[key])).ToArray());
}
IStorageNode node = storageBus.FindNode(moniker);
if (node != null)
{
var result = node.Select(
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri.ToString(),
moniker, MonikerMatch.Exact, query, SerializationMode.Native);
if (result == null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return null;
}
return result.GetReaderAtBodyContents();
}
else
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return null;
}
}
}
public Message Subselect(string scopeid, string nodeName, string id, string substg)
{
var replyAction = OperationContext.Current.EndpointDispatcher.DispatchRuntime.Operations["Subselect"].ReplyAction;
var result = SelectInternal(new Moniker(scopeid, new PathSegmentName(nodeName), id, new PathSegmentName(substg)));
if ( result == null )
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return Message.CreateMessage(OperationContext.Current.IncomingMessageVersion, replyAction);
}
else
{
return Message.CreateMessage(OperationContext.Current.IncomingMessageVersion,
replyAction,result);
}
}
public Message GetItem(string scopeid, string nodeName, string id)
{
var replyAction = OperationContext.Current.EndpointDispatcher.DispatchRuntime.Operations["GetItem"].ReplyAction;
string format = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["format"];
if (format == "json")
{
OperationContext.Current.OutgoingMessageProperties.Add(
HttpBodyFormatMessageProperty.Name,
new HttpBodyFormatMessageProperty(WebContentFormat.Json));
}
Moniker moniker = new Moniker(scopeid, new PathSegmentName(nodeName), id);
IStorageNode node = storageBus.FindNode(moniker);
if (node != null)
{
if (node is IStreamStorageNode &&
!WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters.AllKeys.Contains("info"))
{
var template = new UriTemplate("/bin/{scopeid}/{node}/{streamId}");
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.MovedPermanently;
WebOperationContext.Current.OutgoingResponse.Location = template.BindByPosition(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri, scopeid, nodeName, id).ToString().TrimEnd('/');
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return Message.CreateMessage(OperationContext.Current.IncomingMessageVersion, replyAction);
}
var result = node.Get(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri.ToString(), moniker, SerializationMode.Native);
if (result == null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return Message.CreateMessage(OperationContext.Current.IncomingMessageVersion, replyAction);
}
return Message.CreateMessage(
OperationContext.Current.IncomingMessageVersion,
replyAction,
result.GetReaderAtBodyContents());
}
else
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return Message.CreateMessage(OperationContext.Current.IncomingMessageVersion, replyAction);
}
}
public void DeleteItem(string scopeid, string nodeName, string id)
{
Moniker moniker = new Moniker(scopeid, new PathSegmentName(nodeName), id);
IStorageNode node = storageBus.FindNode(moniker);
if (node != null)
{
node.Delete(moniker);
}
}
public void AddItem(string scopeid, string nodeName, XmlElement item)
{
var queryParameters = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
string format = queryParameters["format"];
if (format == "json")
{
OperationContext.Current.OutgoingMessageProperties.Add(
HttpBodyFormatMessageProperty.Name,
new HttpBodyFormatMessageProperty(WebContentFormat.Json));
}
Moniker moniker = new Moniker(scopeid, new PathSegmentName(nodeName));
IStorageNode node = storageBus.FindNode(moniker);
if ( node != null )
{
string location = node.Store(moniker, item, SerializationMode.Native).ToString();
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Created;
WebOperationContext.Current.OutgoingResponse.Location = new Moniker(location).ToUri(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri).ToString();
}
}
public void AddSubitem(string scopeid, string nodeName, string id, string substg, XmlElement xitem)
{
var queryParameters = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
string format = queryParameters["format"];
var moniker = new Moniker(scopeid, new PathSegmentName(nodeName), id, new PathSegmentName(substg));
IStorageNode node = storageBus.FindNode(moniker);
if (node != null)
{
string location = node.Store(moniker, xitem, SerializationMode.Native).ToString();
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Created;
WebOperationContext.Current.OutgoingResponse.Location = new Moniker(location).ToUri(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri).ToString();
}
}
public void UpdateItem(string scopeid, string nodeName, string id, XmlElement item)
{
var queryParameters = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
string format = queryParameters["format"];
var moniker = new Moniker(scopeid, new PathSegmentName(nodeName), id);
IStorageNode node = storageBus.FindNode(moniker);
if (node != null)
{
if (node is IStreamStorageNode &&
!WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters.AllKeys.Contains("info"))
{
var template = new UriTemplate("/{scopeid}/{node}/{streamId}/binary/");
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.MovedPermanently;
WebOperationContext.Current.OutgoingResponse.Location = template.BindByPosition(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri, scopeid, nodeName, id).ToString().TrimEnd('/');
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return;
}
node.Store(new Moniker(scopeid, new PathSegmentName(nodeName), id), item, SerializationMode.Native);
}
}
public Stream GetStream(string scopeid, string nodeName, string streamId)
{
Moniker moniker = new Moniker(scopeid, new PathSegmentName(nodeName), streamId);
IStreamStorageNode node = storageBus.FindNode(moniker) as IStreamStorageNode;
if (node != null )
{
var result = node.GetStream(new StreamStorageGetRequest { itemId = moniker });
if (result == null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return null;
}
else
{
WebOperationContext.Current.OutgoingResponse.ContentType = result.StreamInfo.ContentType;
}
return result.Stream;
}
else
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return null;
}
}
public string SetStream(string scopeid, string nodeName, string streamId, Stream stream)
{
Moniker uri = new Moniker(scopeid, new PathSegmentName(nodeName), streamId);
IStreamStorageNode node = storageBus.FindNode(uri) as IStreamStorageNode;
if (node != null)
{
var result = node.SetStream(
new StreamStorageSetRequest
{
moniker = uri,
contentType = WebOperationContext.Current.IncomingRequest.ContentType,
name = streamId,
Stream = stream
}
);
if (result == null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotAcceptable;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return null;
}
else
{
WebOperationContext.Current.OutgoingResponse.ContentType = result.StreamInfo.ContentType;
}
return result.StreamInfo.Id.ToString();
}
else
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return null;
}
}
#region IWebStorageNode Members
private XmlReader Aggregate(Moniker moniker, string propname)
{
var queryParameters = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
string format = queryParameters["format"];
if (format == "json")
{
OperationContext.Current.OutgoingMessageProperties.Add(
HttpBodyFormatMessageProperty.Name,
new HttpBodyFormatMessageProperty(WebContentFormat.Json));
}
IStorageNode node = storageBus.FindNode(moniker);
if (node != null)
{
var result = node.Aggregate(
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri.ToString(),
moniker, MonikerMatch.Exact, propname, SerializationMode.Native);
if (result == null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
}
return result.GetReaderAtBodyContents();
}
else
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true;
return null;
}
}
#endregion
}
}
|