http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/e387fc92/JSLib/src/odata-batch.js
----------------------------------------------------------------------
diff --git a/JSLib/src/odata-batch.js b/JSLib/src/odata-batch.js
index 770d875..3060223 100644
--- a/JSLib/src/odata-batch.js
+++ b/JSLib/src/odata-batch.js
@@ -1,393 +1,393 @@
-/// <reference path="odata-utils.js" />
-
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation
-// files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-
-// odata-batch.js
-
-(function (window, undefined) {
-
- var datajs = window.datajs || {};
- var odata = window.OData || {};
-
- // Imports
-
- var extend = datajs.extend;
- var isArray = datajs.isArray;
- var trimString = datajs.trimString;
-
- var contentType = odata.contentType;
- var handler = odata.handler;
- var isBatch = odata.isBatch;
- var MAX_DATA_SERVICE_VERSION = odata.MAX_DATA_SERVICE_VERSION;
- var normalizeHeaders = odata.normalizeHeaders;
- var payloadTypeOf = odata.payloadTypeOf;
- var prepareRequest = odata.prepareRequest;
-
- // CONTENT START
- var batchMediaType = "multipart/mixed";
- var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
- var responseHeaderRegex = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;
-
- var hex16 = function () {
- /// <summary>
- /// Calculates a random 16 bit number and returns it in hexadecimal
format.
- /// </summary>
- /// <returns type="String">A 16-bit number in hex format.</returns>
-
- return Math.floor((1 + Math.random()) *
0x10000).toString(16).substr(1);
- };
-
- var createBoundary = function (prefix) {
- /// <summary>
- /// Creates a string that can be used as a multipart request boundary.
- /// </summary>
- /// <param name="prefix" type="String" optional="true">String to use
as the start of the boundary string</param>
- /// <returns type="String">Boundary string of the format:
<prefix><hex16>-<hex16>-<hex16></returns>
-
- return prefix + hex16() + "-" + hex16() + "-" + hex16();
- };
-
- var partHandler = function (context) {
- /// <summary>
- /// Gets the handler for data serialization of individual requests /
responses in a batch.
- /// </summary>
- /// <param name="context">Context used for data serialization.</param>
- /// <returns>Handler object.</returns>
-
- return context.handler.partHandler;
- };
-
- var currentBoundary = function (context) {
- /// <summary>
- /// Gets the current boundary used for parsing the body of a multipart
response.
- /// </summary>
- /// <param name="context">Context used for parsing a multipart
response.</param>
- /// <returns type="String">Boundary string.</returns>
-
- var boundaries = context.boundaries;
- return boundaries[boundaries.length - 1];
- };
-
- var batchParser = function (handler, text, context) {
- /// <summary>Parses a batch response.</summary>
- /// <param name="handler">This handler.</param>
- /// <param name="text" type="String">Batch text.</param>
- /// <param name="context" type="Object">Object with parsing
context.</param>
- /// <returns>An object representation of the batch.</returns>
-
- var boundary = context.contentType.properties["boundary"];
- return { __batchResponses: readBatch(text, { boundaries: [boundary],
handlerContext: context }) };
- };
-
- var batchSerializer = function (handler, data, context) {
- /// <summary>Serializes a batch object representation into
text.</summary>
- /// <param name="handler">This handler.</param>
- /// <param name="data" type="Object">Representation of a batch.</param>
- /// <param name="context" type="Object">Object with parsing
context.</param>
- /// <returns>An text representation of the batch object; undefined if
not applicable.</returns>
-
- var cType = context.contentType = context.contentType ||
contentType(batchMediaType);
- if (cType.mediaType === batchMediaType) {
- return writeBatch(data, context);
- }
- };
-
- var readBatch = function (text, context) {
- /// <summary>
- /// Parses a multipart/mixed response body from from the position
defined by the context.
- /// </summary>
- /// <param name="text" type="String" optional="false">Body of the
multipart/mixed response.</param>
- /// <param name="context">Context used for parsing.</param>
- /// <returns>Array of objects representing the individual
responses.</returns>
-
- var delimiter = "--" + currentBoundary(context);
-
- // Move beyond the delimiter and read the complete batch
- readTo(text, context, delimiter);
-
- // Ignore the incoming line
- readLine(text, context);
-
- // Read the batch parts
- var responses = [];
- var partEnd;
-
- while (partEnd !== "--" && context.position < text.length) {
- var partHeaders = readHeaders(text, context);
- var partContentType = contentType(partHeaders["Content-Type"]);
-
- var changeResponses;
- if (partContentType && partContentType.mediaType ===
batchMediaType) {
-
context.boundaries.push(partContentType.properties["boundary"]);
- try {
- changeResponses = readBatch(text, context);
- } catch (e) {
- e.response = readResponse(text, context, delimiter);
- changeResponses = [e];
- }
- responses.push({ __changeResponses: changeResponses });
- context.boundaries.pop();
- readTo(text, context, "--" + currentBoundary(context));
- } else {
- if (!partContentType || partContentType.mediaType !==
"application/http") {
- throw { message: "invalid MIME part type " };
- }
- // Skip empty line
- readLine(text, context);
- // Read the response
- var response = readResponse(text, context, delimiter);
- try {
- if (response.statusCode >= 200 && response.statusCode <=
299) {
- partHandler(context.handlerContext).read(response,
context.handlerContext);
- } else {
- // Keep track of failed responses and continue
processing the batch.
- response = { message: "HTTP request failed", response:
response };
- }
- } catch (e) {
- response = e;
- }
-
- responses.push(response);
- }
-
- partEnd = text.substr(context.position, 2);
-
- // Ignore the incoming line.
- readLine(text, context);
- }
- return responses;
- };
-
- var readHeaders = function (text, context) {
- /// <summary>
- /// Parses the http headers in the text from the position defined by
the context.
- /// </summary>
- /// <param name="text" type="String" optional="false">Text containing
an http response's headers</param>
- /// <param name="context">Context used for parsing.</param>
- /// <returns>Object containing the headers as key value
pairs.</returns>
- /// <remarks>
- /// This function doesn't support split headers and it will stop
reading when it hits two consecutive line breaks.
- /// </remarks>
-
- var headers = {};
- var parts;
- var line;
- var pos;
-
- do {
- pos = context.position;
- line = readLine(text, context);
- parts = responseHeaderRegex.exec(line);
- if (parts !== null) {
- headers[parts[1]] = parts[2];
- } else {
- // Whatever was found is not a header, so reset the context
position.
- context.position = pos;
- }
- } while (line && parts);
-
- normalizeHeaders(headers);
-
- return headers;
- };
-
- var readResponse = function (text, context, delimiter) {
- /// <summary>
- /// Parses an HTTP response.
- /// </summary>
- /// <param name="text" type="String" optional="false">Text
representing the http response.</param>
- /// <param name="context" optional="false">Context used for
parsing.</param>
- /// <param name="delimiter" type="String" optional="false">String used
as delimiter of the multipart response parts.</param>
- /// <returns>Object representing the http response.</returns>
-
- // Read the status line.
- var pos = context.position;
- var match = responseStatusRegex.exec(readLine(text, context));
-
- var statusCode;
- var statusText;
- var headers;
-
- if (match) {
- statusCode = match[1];
- statusText = match[2];
- headers = readHeaders(text, context);
- readLine(text, context);
- } else {
- context.position = pos;
- }
-
- return {
- statusCode: statusCode,
- statusText: statusText,
- headers: headers,
- body: readTo(text, context, "\r\n" + delimiter)
- };
- };
-
- var readLine = function (text, context) {
- /// <summary>
- /// Returns a substring from the position defined by the context up to
the next line break (CRLF).
- /// </summary>
- /// <param name="text" type="String" optional="false">Input
string.</param>
- /// <param name="context" optional="false">Context used for reading
the input string.</param>
- /// <returns type="String">Substring to the first ocurrence of a line
break or null if none can be found. </returns>
-
- return readTo(text, context, "\r\n");
- };
-
- var readTo = function (text, context, str) {
- /// <summary>
- /// Returns a substring from the position given by the context up to
value defined by the str parameter and increments the position in the context.
- /// </summary>
- /// <param name="text" type="String" optional="false">Input
string.</param>
- /// <param name="context" type="Object" optional="false">Context used
for reading the input string.</param>
- /// <param name="str" type="String" optional="true">Substring to read
up to.</param>
- /// <returns type="String">Substring to the first ocurrence of str or
the end of the input string if str is not specified. Null if the marker is not
found.</returns>
-
- var start = context.position || 0;
- var end = text.length;
- if (str) {
- end = text.indexOf(str, start);
- if (end === -1) {
- return null;
- }
- context.position = end + str.length;
- } else {
- context.position = end;
- }
-
- return text.substring(start, end);
- };
-
- var writeBatch = function (data, context) {
- /// <summary>
- /// Serializes a batch request object to a string.
- /// </summary>
- /// <param name="data" optional="false">Batch request object in
payload representation format</param>
- /// <param name="context" optional="false">Context used for the
serialization</param>
- /// <returns type="String">String representing the batch
request</returns>
-
- if (!isBatch(data)) {
- throw { message: "Data is not a batch object." };
- }
-
- var batchBoundary = createBoundary("batch_");
- var batchParts = data.__batchRequests;
- var batch = "";
- var i, len;
- for (i = 0, len = batchParts.length; i < len; i++) {
- batch += writeBatchPartDelimiter(batchBoundary, false) +
- writeBatchPart(batchParts[i], context);
- }
- batch += writeBatchPartDelimiter(batchBoundary, true);
-
- // Register the boundary with the request content type.
- var contentTypeProperties = context.contentType.properties;
- contentTypeProperties.boundary = batchBoundary;
-
- return batch;
- };
-
- var writeBatchPartDelimiter = function (boundary, close) {
- /// <summary>
- /// Creates the delimiter that indicates that start or end of an
individual request.
- /// </summary>
- /// <param name="boundary" type="String" optional="false">Boundary
string used to indicate the start of the request</param>
- /// <param name="close" type="Boolean">Flag indicating that a close
delimiter string should be generated</param>
- /// <returns type="String">Delimiter string</returns>
-
- var result = "\r\n--" + boundary;
- if (close) {
- result += "--";
- }
-
- return result + "\r\n";
- };
-
- var writeBatchPart = function (part, context, nested) {
- /// <summary>
- /// Serializes a part of a batch request to a string. A part can be
either a GET request or
- /// a change set grouping several CUD (create, update, delete)
requests.
- /// </summary>
- /// <param name="part" optional="false">Request or change set object
in payload representation format</param>
- /// <param name="context" optional="false">Object containing context
information used for the serialization</param>
- /// <param name="nested" type="boolean" optional="true">Flag
indicating that the part is nested inside a change set</param>
- /// <returns type="String">String representing the serialized
part</returns>
- /// <remarks>
- /// A change set is an array of request objects and they cannot be
nested inside other change sets.
- /// </remarks>
-
- var changeSet = part.__changeRequests;
- var result;
- if (isArray(changeSet)) {
- if (nested) {
- throw { message: "Not Supported: change set nested in other
change set" };
- }
-
- var changeSetBoundary = createBoundary("changeset_");
- result = "Content-Type: " + batchMediaType + "; boundary=" +
changeSetBoundary + "\r\n";
- var i, len;
- for (i = 0, len = changeSet.length; i < len; i++) {
- result += writeBatchPartDelimiter(changeSetBoundary, false) +
- writeBatchPart(changeSet[i], context, true);
- }
-
- result += writeBatchPartDelimiter(changeSetBoundary, true);
- } else {
- result = "Content-Type:
application/http\r\nContent-Transfer-Encoding: binary\r\n\r\n";
- var partContext = extend({}, context);
- partContext.handler = handler;
- partContext.request = part;
- partContext.contentType = null;
-
- prepareRequest(part, partHandler(context), partContext);
- result += writeRequest(part);
- }
-
- return result;
- };
-
- var writeRequest = function (request) {
- /// <summary>
- /// Serializes a request object to a string.
- /// </summary>
- /// <param name="request" optional="false">Request object to
serialize</param>
- /// <returns type="String">String representing the serialized
request</returns>
-
- var result = (request.method ? request.method : "GET") + " " +
request.requestUri + " HTTP/1.1\r\n";
- for (var name in request.headers) {
- if (request.headers[name]) {
- result = result + name + ": " + request.headers[name] + "\r\n";
- }
- }
-
- result += "\r\n";
-
- if (request.body) {
- result += request.body;
- }
-
- return result;
- };
-
- odata.batchHandler = handler(batchParser, batchSerializer, batchMediaType,
MAX_DATA_SERVICE_VERSION);
-
- // DATAJS INTERNAL START
- odata.batchSerializer = batchSerializer;
- odata.writeRequest = writeRequest;
- // DATAJS INTERNAL END
-
- // CONTENT END
+/// <reference path="odata-utils.js" />
+
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy,
+// modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+
+// odata-batch.js
+
+(function (window, undefined) {
+
+ var datajs = window.datajs || {};
+ var odata = window.OData || {};
+
+ // Imports
+
+ var extend = datajs.extend;
+ var isArray = datajs.isArray;
+ var trimString = datajs.trimString;
+
+ var contentType = odata.contentType;
+ var handler = odata.handler;
+ var isBatch = odata.isBatch;
+ var MAX_DATA_SERVICE_VERSION = odata.MAX_DATA_SERVICE_VERSION;
+ var normalizeHeaders = odata.normalizeHeaders;
+ var payloadTypeOf = odata.payloadTypeOf;
+ var prepareRequest = odata.prepareRequest;
+
+ // CONTENT START
+ var batchMediaType = "multipart/mixed";
+ var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
+ var responseHeaderRegex = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;
+
+ var hex16 = function () {
+ /// <summary>
+ /// Calculates a random 16 bit number and returns it in hexadecimal
format.
+ /// </summary>
+ /// <returns type="String">A 16-bit number in hex format.</returns>
+
+ return Math.floor((1 + Math.random()) *
0x10000).toString(16).substr(1);
+ };
+
+ var createBoundary = function (prefix) {
+ /// <summary>
+ /// Creates a string that can be used as a multipart request boundary.
+ /// </summary>
+ /// <param name="prefix" type="String" optional="true">String to use
as the start of the boundary string</param>
+ /// <returns type="String">Boundary string of the format:
<prefix><hex16>-<hex16>-<hex16></returns>
+
+ return prefix + hex16() + "-" + hex16() + "-" + hex16();
+ };
+
+ var partHandler = function (context) {
+ /// <summary>
+ /// Gets the handler for data serialization of individual requests /
responses in a batch.
+ /// </summary>
+ /// <param name="context">Context used for data serialization.</param>
+ /// <returns>Handler object.</returns>
+
+ return context.handler.partHandler;
+ };
+
+ var currentBoundary = function (context) {
+ /// <summary>
+ /// Gets the current boundary used for parsing the body of a multipart
response.
+ /// </summary>
+ /// <param name="context">Context used for parsing a multipart
response.</param>
+ /// <returns type="String">Boundary string.</returns>
+
+ var boundaries = context.boundaries;
+ return boundaries[boundaries.length - 1];
+ };
+
+ var batchParser = function (handler, text, context) {
+ /// <summary>Parses a batch response.</summary>
+ /// <param name="handler">This handler.</param>
+ /// <param name="text" type="String">Batch text.</param>
+ /// <param name="context" type="Object">Object with parsing
context.</param>
+ /// <returns>An object representation of the batch.</returns>
+
+ var boundary = context.contentType.properties["boundary"];
+ return { __batchResponses: readBatch(text, { boundaries: [boundary],
handlerContext: context }) };
+ };
+
+ var batchSerializer = function (handler, data, context) {
+ /// <summary>Serializes a batch object representation into
text.</summary>
+ /// <param name="handler">This handler.</param>
+ /// <param name="data" type="Object">Representation of a batch.</param>
+ /// <param name="context" type="Object">Object with parsing
context.</param>
+ /// <returns>An text representation of the batch object; undefined if
not applicable.</returns>
+
+ var cType = context.contentType = context.contentType ||
contentType(batchMediaType);
+ if (cType.mediaType === batchMediaType) {
+ return writeBatch(data, context);
+ }
+ };
+
+ var readBatch = function (text, context) {
+ /// <summary>
+ /// Parses a multipart/mixed response body from from the position
defined by the context.
+ /// </summary>
+ /// <param name="text" type="String" optional="false">Body of the
multipart/mixed response.</param>
+ /// <param name="context">Context used for parsing.</param>
+ /// <returns>Array of objects representing the individual
responses.</returns>
+
+ var delimiter = "--" + currentBoundary(context);
+
+ // Move beyond the delimiter and read the complete batch
+ readTo(text, context, delimiter);
+
+ // Ignore the incoming line
+ readLine(text, context);
+
+ // Read the batch parts
+ var responses = [];
+ var partEnd;
+
+ while (partEnd !== "--" && context.position < text.length) {
+ var partHeaders = readHeaders(text, context);
+ var partContentType = contentType(partHeaders["Content-Type"]);
+
+ var changeResponses;
+ if (partContentType && partContentType.mediaType ===
batchMediaType) {
+
context.boundaries.push(partContentType.properties["boundary"]);
+ try {
+ changeResponses = readBatch(text, context);
+ } catch (e) {
+ e.response = readResponse(text, context, delimiter);
+ changeResponses = [e];
+ }
+ responses.push({ __changeResponses: changeResponses });
+ context.boundaries.pop();
+ readTo(text, context, "--" + currentBoundary(context));
+ } else {
+ if (!partContentType || partContentType.mediaType !==
"application/http") {
+ throw { message: "invalid MIME part type " };
+ }
+ // Skip empty line
+ readLine(text, context);
+ // Read the response
+ var response = readResponse(text, context, delimiter);
+ try {
+ if (response.statusCode >= 200 && response.statusCode <=
299) {
+ partHandler(context.handlerContext).read(response,
context.handlerContext);
+ } else {
+ // Keep track of failed responses and continue
processing the batch.
+ response = { message: "HTTP request failed", response:
response };
+ }
+ } catch (e) {
+ response = e;
+ }
+
+ responses.push(response);
+ }
+
+ partEnd = text.substr(context.position, 2);
+
+ // Ignore the incoming line.
+ readLine(text, context);
+ }
+ return responses;
+ };
+
+ var readHeaders = function (text, context) {
+ /// <summary>
+ /// Parses the http headers in the text from the position defined by
the context.
+ /// </summary>
+ /// <param name="text" type="String" optional="false">Text containing
an http response's headers</param>
+ /// <param name="context">Context used for parsing.</param>
+ /// <returns>Object containing the headers as key value
pairs.</returns>
+ /// <remarks>
+ /// This function doesn't support split headers and it will stop
reading when it hits two consecutive line breaks.
+ /// </remarks>
+
+ var headers = {};
+ var parts;
+ var line;
+ var pos;
+
+ do {
+ pos = context.position;
+ line = readLine(text, context);
+ parts = responseHeaderRegex.exec(line);
+ if (parts !== null) {
+ headers[parts[1]] = parts[2];
+ } else {
+ // Whatever was found is not a header, so reset the context
position.
+ context.position = pos;
+ }
+ } while (line && parts);
+
+ normalizeHeaders(headers);
+
+ return headers;
+ };
+
+ var readResponse = function (text, context, delimiter) {
+ /// <summary>
+ /// Parses an HTTP response.
+ /// </summary>
+ /// <param name="text" type="String" optional="false">Text
representing the http response.</param>
+ /// <param name="context" optional="false">Context used for
parsing.</param>
+ /// <param name="delimiter" type="String" optional="false">String used
as delimiter of the multipart response parts.</param>
+ /// <returns>Object representing the http response.</returns>
+
+ // Read the status line.
+ var pos = context.position;
+ var match = responseStatusRegex.exec(readLine(text, context));
+
+ var statusCode;
+ var statusText;
+ var headers;
+
+ if (match) {
+ statusCode = match[1];
+ statusText = match[2];
+ headers = readHeaders(text, context);
+ readLine(text, context);
+ } else {
+ context.position = pos;
+ }
+
+ return {
+ statusCode: statusCode,
+ statusText: statusText,
+ headers: headers,
+ body: readTo(text, context, "\r\n" + delimiter)
+ };
+ };
+
+ var readLine = function (text, context) {
+ /// <summary>
+ /// Returns a substring from the position defined by the context up to
the next line break (CRLF).
+ /// </summary>
+ /// <param name="text" type="String" optional="false">Input
string.</param>
+ /// <param name="context" optional="false">Context used for reading
the input string.</param>
+ /// <returns type="String">Substring to the first ocurrence of a line
break or null if none can be found. </returns>
+
+ return readTo(text, context, "\r\n");
+ };
+
+ var readTo = function (text, context, str) {
+ /// <summary>
+ /// Returns a substring from the position given by the context up to
value defined by the str parameter and increments the position in the context.
+ /// </summary>
+ /// <param name="text" type="String" optional="false">Input
string.</param>
+ /// <param name="context" type="Object" optional="false">Context used
for reading the input string.</param>
+ /// <param name="str" type="String" optional="true">Substring to read
up to.</param>
+ /// <returns type="String">Substring to the first ocurrence of str or
the end of the input string if str is not specified. Null if the marker is not
found.</returns>
+
+ var start = context.position || 0;
+ var end = text.length;
+ if (str) {
+ end = text.indexOf(str, start);
+ if (end === -1) {
+ return null;
+ }
+ context.position = end + str.length;
+ } else {
+ context.position = end;
+ }
+
+ return text.substring(start, end);
+ };
+
+ var writeBatch = function (data, context) {
+ /// <summary>
+ /// Serializes a batch request object to a string.
+ /// </summary>
+ /// <param name="data" optional="false">Batch request object in
payload representation format</param>
+ /// <param name="context" optional="false">Context used for the
serialization</param>
+ /// <returns type="String">String representing the batch
request</returns>
+
+ if (!isBatch(data)) {
+ throw { message: "Data is not a batch object." };
+ }
+
+ var batchBoundary = createBoundary("batch_");
+ var batchParts = data.__batchRequests;
+ var batch = "";
+ var i, len;
+ for (i = 0, len = batchParts.length; i < len; i++) {
+ batch += writeBatchPartDelimiter(batchBoundary, false) +
+ writeBatchPart(batchParts[i], context);
+ }
+ batch += writeBatchPartDelimiter(batchBoundary, true);
+
+ // Register the boundary with the request content type.
+ var contentTypeProperties = context.contentType.properties;
+ contentTypeProperties.boundary = batchBoundary;
+
+ return batch;
+ };
+
+ var writeBatchPartDelimiter = function (boundary, close) {
+ /// <summary>
+ /// Creates the delimiter that indicates that start or end of an
individual request.
+ /// </summary>
+ /// <param name="boundary" type="String" optional="false">Boundary
string used to indicate the start of the request</param>
+ /// <param name="close" type="Boolean">Flag indicating that a close
delimiter string should be generated</param>
+ /// <returns type="String">Delimiter string</returns>
+
+ var result = "\r\n--" + boundary;
+ if (close) {
+ result += "--";
+ }
+
+ return result + "\r\n";
+ };
+
+ var writeBatchPart = function (part, context, nested) {
+ /// <summary>
+ /// Serializes a part of a batch request to a string. A part can be
either a GET request or
+ /// a change set grouping several CUD (create, update, delete)
requests.
+ /// </summary>
+ /// <param name="part" optional="false">Request or change set object
in payload representation format</param>
+ /// <param name="context" optional="false">Object containing context
information used for the serialization</param>
+ /// <param name="nested" type="boolean" optional="true">Flag
indicating that the part is nested inside a change set</param>
+ /// <returns type="String">String representing the serialized
part</returns>
+ /// <remarks>
+ /// A change set is an array of request objects and they cannot be
nested inside other change sets.
+ /// </remarks>
+
+ var changeSet = part.__changeRequests;
+ var result;
+ if (isArray(changeSet)) {
+ if (nested) {
+ throw { message: "Not Supported: change set nested in other
change set" };
+ }
+
+ var changeSetBoundary = createBoundary("changeset_");
+ result = "Content-Type: " + batchMediaType + "; boundary=" +
changeSetBoundary + "\r\n";
+ var i, len;
+ for (i = 0, len = changeSet.length; i < len; i++) {
+ result += writeBatchPartDelimiter(changeSetBoundary, false) +
+ writeBatchPart(changeSet[i], context, true);
+ }
+
+ result += writeBatchPartDelimiter(changeSetBoundary, true);
+ } else {
+ result = "Content-Type:
application/http\r\nContent-Transfer-Encoding: binary\r\n\r\n";
+ var partContext = extend({}, context);
+ partContext.handler = handler;
+ partContext.request = part;
+ partContext.contentType = null;
+
+ prepareRequest(part, partHandler(context), partContext);
+ result += writeRequest(part);
+ }
+
+ return result;
+ };
+
+ var writeRequest = function (request) {
+ /// <summary>
+ /// Serializes a request object to a string.
+ /// </summary>
+ /// <param name="request" optional="false">Request object to
serialize</param>
+ /// <returns type="String">String representing the serialized
request</returns>
+
+ var result = (request.method ? request.method : "GET") + " " +
request.requestUri + " HTTP/1.1\r\n";
+ for (var name in request.headers) {
+ if (request.headers[name]) {
+ result = result + name + ": " + request.headers[name] + "\r\n";
+ }
+ }
+
+ result += "\r\n";
+
+ if (request.body) {
+ result += request.body;
+ }
+
+ return result;
+ };
+
+ odata.batchHandler = handler(batchParser, batchSerializer, batchMediaType,
MAX_DATA_SERVICE_VERSION);
+
+ // DATAJS INTERNAL START
+ odata.batchSerializer = batchSerializer;
+ odata.writeRequest = writeRequest;
+ // DATAJS INTERNAL END
+
+ // CONTENT END
})(this);
\ No newline at end of file