<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: odata/handler.js</title>
    
    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <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/handler.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/handler */


var utils    = require('./../utils.js');
var oDataUtils    = require('./odatautils.js');

// Imports.
var assigned = utils.assigned;
var extend = utils.extend;
var trimString = utils.trimString;
var maxVersion = oDataUtils.maxVersion;
var MAX_DATA_SERVICE_VERSION = "4.0";

/** Parses a string into an object with media type and properties.
 * @param {String} str - String with media type to parse.
 * @return null if the string is empty; an object with 'mediaType' and a 'properties' dictionary otherwise.
 */
function contentType(str) {

    if (!str) {
        return null;
    }

    var contentTypeParts = str.split(";");
    var properties = {};

    var i, len;
    for (i = 1, len = contentTypeParts.length; i &lt; len; i++) {
        var contentTypeParams = contentTypeParts[i].split("=");
        properties[trimString(contentTypeParams[0])] = contentTypeParams[1];
    }

    return { mediaType: trimString(contentTypeParts[0]), properties: properties };
}

/** Serializes an object with media type and properties dictionary into a string.
 * @param contentType - Object with media type and properties dictionary to serialize.
 * @return String representation of the media type object; undefined if contentType is null or undefined.
 */
function contentTypeToString(contentType) {
    if (!contentType) {
        return undefined;
    }

    var result = contentType.mediaType;
    var property;
    for (property in contentType.properties) {
        result += ";" + property + "=" + contentType.properties[property];
    }
    return result;
}

/** Creates an object that is going to be used as the context for the handler's parser and serializer.
 * @param contentType - Object with media type and properties dictionary.
 * @param {String} dataServiceVersion - String indicating the version of the protocol to use.
 * @param context - Operation context.
 * @param handler - Handler object that is processing a resquest or response.
 * @return Context object.
 */
function createReadWriteContext(contentType, dataServiceVersion, context, handler) {

    var rwContext = {};
    extend(rwContext, context);
    extend(rwContext, {
        contentType: contentType,
        dataServiceVersion: dataServiceVersion,
        handler: handler
    });

    return rwContext;
}

/** Sets a request header's value. If the header has already a value other than undefined, null or empty string, then this method does nothing.
 * @param request - Request object on which the header will be set.
 * @param {String} name - Header name.
 * @param {String} value - Header value.
 */
function fixRequestHeader(request, name, value) {
    if (!request) {
        return;
    }

    var headers = request.headers;
    if (!headers[name]) {
        headers[name] = value;
    }
}

/** Sets the DataServiceVersion header of the request if its value is not yet defined or of a lower version.
 * @param request - Request object on which the header will be set.
 * @param {String} version - Version value.
 *  If the request has already a version value higher than the one supplied the this function does nothing.
 */
function fixDataServiceVersionHeader(request, version) {   

    if (request) {
        var headers = request.headers;
        var dsv = headers["OData-Version"];
        headers["OData-Version"] = dsv ? maxVersion(dsv, version) : version;
    }
}

/** Gets the value of a request or response header.
 * @param requestOrResponse - Object representing a request or a response.
 * @param {String} name - Name of the header to retrieve.
 * @returns {String} String value of the header; undefined if the header cannot be found.
 */
function getRequestOrResponseHeader(requestOrResponse, name) {

    var headers = requestOrResponse.headers;
    return (headers && headers[name]) || undefined;
}

/** Gets the value of the Content-Type header from a request or response.
 * @param requestOrResponse - Object representing a request or a response.
 * @returns {Object} Object with 'mediaType' and a 'properties' dictionary; null in case that the header is not found or doesn't have a value.
 */
function getContentType(requestOrResponse) {

    return contentType(getRequestOrResponseHeader(requestOrResponse, "Content-Type"));
}

var versionRE = /^\s?(\d+\.\d+);?.*$/;
/** Gets the value of the DataServiceVersion header from a request or response.
 * @param requestOrResponse - Object representing a request or a response.
 * @returns {String} Data service version; undefined if the header cannot be found.
 */
function getDataServiceVersion(requestOrResponse) {

    var value = getRequestOrResponseHeader(requestOrResponse, "OData-Version");
    if (value) {
        var matches = versionRE.exec(value);
        if (matches && matches.length) {
            return matches[1];
        }
    }

    // Fall through and return undefined.
}

/** Checks that a handler can process a particular mime type.
 * @param handler - Handler object that is processing a resquest or response.
 * @param cType - Object with 'mediaType' and a 'properties' dictionary.
 * @returns {Boolean} True if the handler can process the mime type; false otherwise.
 *
 * The following check isn't as strict because if cType.mediaType = application/; it will match an accept value of "application/xml";
 * however in practice we don't not expect to see such "suffixed" mimeTypes for the handlers.
 */
function handlerAccepts(handler, cType) {
    return handler.accept.indexOf(cType.mediaType) >= 0;
}

/** Invokes the parser associated with a handler for reading the payload of a HTTP response.
 * @param handler - Handler object that is processing the response.
 * @param {Function} parseCallback - Parser function that will process the response payload.
 * @param response - HTTP response whose payload is going to be processed.
 * @param context - Object used as the context for processing the response.
 * @returns {Boolean} True if the handler processed the response payload and the response.data property was set; false otherwise.
 */
function handlerRead(handler, parseCallback, response, context) {

    if (!response || !response.headers) {
        return false;
    }

    var cType = getContentType(response);
    var version = getDataServiceVersion(response) || "";
    var body = response.body;

    if (!assigned(body)) {
        return false;
    }

    if (handlerAccepts(handler, cType)) {
        var readContext = createReadWriteContext(cType, version, context, handler);
        readContext.response = response;
        response.data = parseCallback(handler, body, readContext);
        return response.data !== undefined;
    }

    return false;
}

/** Invokes the serializer associated with a handler for generating the payload of a HTTP request.
 * @param handler - Handler object that is processing the request.
 * @param {Function} serializeCallback - Serializer function that will generate the request payload.
 * @param request - HTTP request whose payload is going to be generated.
 * @param context - Object used as the context for serializing the request.
 * @returns {Boolean} True if the handler serialized the request payload and the request.body property was set; false otherwise.
 */
function handlerWrite(handler, serializeCallback, request, context) {
    if (!request || !request.headers) {
        return false;
    }

    var cType = getContentType(request);
    var version = getDataServiceVersion(request);

    if (!cType || handlerAccepts(handler, cType)) {
        var writeContext = createReadWriteContext(cType, version, context, handler);
        writeContext.request = request;

        request.body = serializeCallback(handler, request.data, writeContext);

        if (request.body !== undefined) {
            fixDataServiceVersionHeader(request, writeContext.dataServiceVersion || "4.0");

            fixRequestHeader(request, "Content-Type", contentTypeToString(writeContext.contentType));
            fixRequestHeader(request, "OData-MaxVersion", handler.maxDataServiceVersion);
            return true;
        }
    }

    return false;
}

/** Creates a handler object for processing HTTP requests and responses.
 * @param {Function} parseCallback - Parser function that will process the response payload.
 * @param {Function} serializeCallback - Serializer function that will generate the request payload.
 * @param {String} accept - String containing a comma separated list of the mime types that this handler can work with.
 * @param {String} maxDataServiceVersion - String indicating the highest version of the protocol that this handler can work with.
 * @returns {Object} Handler object.
 */
function handler(parseCallback, serializeCallback, accept, maxDataServiceVersion) {

    return {
        accept: accept,
        maxDataServiceVersion: maxDataServiceVersion,

        read: function (response, context) {
            return handlerRead(this, parseCallback, response, context);
        },

        write: function (request, context) {
            return handlerWrite(this, serializeCallback, request, context);
        }
    };
}

function textParse(handler, body /*, context */) {
    return body;
}

function textSerialize(handler, data /*, context */) {
    if (assigned(data)) {
        return data.toString();
    } else {
        return undefined;
    }
}




exports.textHandler = handler(textParse, textSerialize, "text/plain", MAX_DATA_SERVICE_VERSION);
exports.contentType = contentType;
exports.contentTypeToString = contentTypeToString;
exports.handler = handler;
exports.createReadWriteContext = createReadWriteContext;
exports.fixRequestHeader = fixRequestHeader;
exports.getRequestOrResponseHeader = getRequestOrResponseHeader;
exports.getContentType = getContentType;
exports.getDataServiceVersion = getDataServiceVersion;
exports.MAX_DATA_SERVICE_VERSION = MAX_DATA_SERVICE_VERSION;</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>
