<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: odata/batch.js</title>
    
    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">
    
    <h1 class="page-title">Source: odata/batch.js</h1>
    
    


    
    <section>
        <article>
            <pre class="prettyprint source"><code>﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
'use strict';

/** @module odata/batch */

var utils    = require('./../utils.js');
var odataUtils    = require('./odatautils.js');
var odataHandler = require('./handler.js');

var extend = utils.extend;
var isArray = utils.isArray;
var trimString = utils.trimString;

var contentType = odataHandler.contentType;
var handler = odataHandler.handler;
var isBatch = odataUtils.isBatch;
var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
var normalizeHeaders = odataUtils.normalizeHeaders;
//TODO var payloadTypeOf = odata.payloadTypeOf;
var prepareRequest = odataUtils.prepareRequest;


// Imports

// CONTENT START
var batchMediaType = "multipart/mixed";
var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
var responseHeaderRegex = /^([^()&lt;>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;

/** Calculates a random 16 bit number and returns it in hexadecimal format.
 * @returns {String} A 16-bit number in hex format.
 */
function hex16() {

    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substr(1);
}

/** Creates a string that can be used as a multipart request boundary.
 * @param {String} [prefix] - 
 * @returns {String} Boundary string of the format: &lt;prefix>&lt;hex16>-&lt;hex16>-&lt;hex16>
 */
function createBoundary(prefix) {

    return prefix + hex16() + "-" + hex16() + "-" + hex16();
}

/** Gets the handler for data serialization of individual requests / responses in a batch.
 * @param context - Context used for data serialization.
 * @returns Handler object
 */
function partHandler(context) {

    return context.handler.partHandler;
}

/** Gets the current boundary used for parsing the body of a multipart response.
 * @param context - Context used for parsing a multipart response.
 * @returns {String} Boundary string.
 */
function currentBoundary(context) {
    var boundaries = context.boundaries;
    return boundaries[boundaries.length - 1];
}

/** Parses a batch response.
 * @param handler - This handler.
 * @param {String} text - Batch text.
 * @param {Object} context - Object with parsing context.
 * @return An object representation of the batch.
 */
function batchParser(handler, text, context) {

    var boundary = context.contentType.properties["boundary"];
    return { __batchResponses: readBatch(text, { boundaries: [boundary], handlerContext: context }) };
}

/** Serializes a batch object representation into text.
 * @param handler - This handler.
 * @param {Object} data - Representation of a batch.
 * @param {Object} context - Object with parsing context.
 * @return An text representation of the batch object; undefined if not applicable.#
 */
function batchSerializer(handler, data, context) {

    var cType = context.contentType = context.contentType || contentType(batchMediaType);
    if (cType.mediaType === batchMediaType) {
        return writeBatch(data, context);
    }
}

/** Parses a multipart/mixed response body from from the position defined by the context.
 * @param {String}  text - Body of the multipart/mixed response.
 * @param context - Context used for parsing.
 * @return Array of objects representing the individual responses.
 */
function readBatch(text, context) {
    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 = null;

    while (partEnd !== "--" && context.position &lt; 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 &lt;= 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;
}

/** Parses the http headers in the text from the position defined by the context.
 * @param {String} text - Text containing an http response's headers
 * @param context - Context used for parsing.
 * @returns Object containing the headers as key value pairs.
 * This function doesn't support split headers and it will stop reading when it hits two consecutive line breaks.
*/
function readHeaders(text, context) {
    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;
}

/** Parses an HTTP response.
 * @param {String} text -Text representing the http response.
 * @param context optional - Context used for parsing.
 * @param {String} delimiter -String used as delimiter of the multipart response parts.
 * @return Object representing the http response.
 */
function readResponse(text, context, delimiter) {
    // 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)
    };
}

/** Returns a substring from the position defined by the context up to the next line break (CRLF).
 * @param {String} text - Input string.
 * @param context - Context used for reading the input string.
 * @returns {String} Substring to the first ocurrence of a line break or null if none can be found. 
 */
function readLine(text, context) {

    return readTo(text, context, "\r\n");
}

/** 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.
 * @param {String} text - Input string.
 * @param context - Context used for reading the input string.
 * @param {String} [str] - Substring to read up to.
 * @returns {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.
 */
function readTo(text, context, str) {
    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);
}

/** Serializes a batch request object to a string.
 * @param data - Batch request object in payload representation format
 * @param context - Context used for the serialization
 * @returns {String} String representing the batch request
 */
function writeBatch(data, context) {
    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 &lt; 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;
}

/** Creates the delimiter that indicates that start or end of an individual request.
 * @param {String} boundary Boundary string used to indicate the start of the request
 * @param {Boolean} close - Flag indicating that a close delimiter string should be generated
 * @returns {String} Delimiter string
 */
function writeBatchPartDelimiter(boundary, close) {
    var result = "\r\n--" + boundary;
    if (close) {
        result += "--";
    }

    return result + "\r\n";
}

/** 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.
 * @param part - Request or change set object in payload representation format
 * @param context - Object containing context information used for the serialization
 * @param {boolean} [nested] - 
 * @returns {String} String representing the serialized part
 * A change set is an array of request objects and they cannot be nested inside other change sets.
 */
function writeBatchPart(part, context, nested) {
    

    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 &lt; 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;
}

/** Serializes a request object to a string.
 * @param request - Request object to serialize
 * @returns {String} String representing the serialized request
 */
function writeRequest(request) {
    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;
}



/** batchHandler (see {@link module:odata/batch~batchParser}) */
exports.batchHandler = handler(batchParser, batchSerializer, batchMediaType, MAX_DATA_SERVICE_VERSION);

/** batchSerializer (see {@link module:odata/batch~batchSerializer}) */
exports.batchSerializer = batchSerializer;

/** writeRequest (see {@link module:odata/batch~writeRequest}) */
exports.writeRequest = writeRequest;</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-cache.html">cache</a></li><li><a href="source.html">cache/source</a></li><li><a href="module-odata.html">odata</a></li><li><a href="batch.html">odata/batch</a></li><li><a href="handler.html">odata/handler</a></li><li><a href="json.html">odata/json</a></li><li><a href="metadata.html">odata/metadata</a></li><li><a href="net.html">odata/net</a></li><li><a href="utils.html">odata/utils</a></li><li><a href="deferred.html">odatajs/deferred</a></li><li><a href="utils_.html">odatajs/utils</a></li><li><a href="xml.html">odatajs/xml</a></li><li><a href="module-store.html">store</a></li><li><a href="dom.html">store/dom</a></li><li><a href="indexeddb.html">store/indexeddb</a></li><li><a href="memory.html">store/memory</a></li></ul><h3>Classes</h3><ul><li><a href="DataCache.html">DataCache</a></li><li><a href="DataCacheOperation.html">DataCacheOperation</a></li><li><a href="DjsDeferred.html">DjsDeferred</a></li><li><a href="dom-DomStore.html">DomStore</a></li><li><a href="indexeddb-IndexedDBStore.html">IndexedDBStore</a></li><li><a href="memory-MemoryStore.html">MemoryStore</a></li><li><a href="ODataCacheSource.html">ODataCacheSource</a></li></ul><h3><a href="global.html">Global</a></h3>
</nav>

<br clear="both">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Apr 09 2015 08:31:26 GMT+0200 (MESZ)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
