Source: odata.js

/*
 * 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 */

// Imports
var odataUtils    = exports.utils     = require('./odata/odatautils.js');
var odataHandler  = exports.handler   = require('./odata/handler.js');
var odataMetadata = exports.metadata  = require('./odata/metadata.js');
var odataNet      = exports.net       = require('./odata/net.js');
var odataJson     = exports.json      = require('./odata/json.js');
                    exports.batch     = require('./odata/batch.js');
                    


var utils = require('./utils.js');
var assigned = utils.assigned;

var defined = utils.defined;
var throwErrorCallback = utils.throwErrorCallback;

var invokeRequest = odataUtils.invokeRequest;
var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
var prepareRequest = odataUtils.prepareRequest;
var metadataParser = odataMetadata.metadataParser;

// CONTENT START

var handlers = [odataJson.jsonHandler, odataHandler.textHandler];

/** Dispatches an operation to handlers.
 * @param {String} handlerMethod - Name of handler method to invoke.
 * @param {Object} requestOrResponse - request/response argument for delegated call.
 * @param {Object} context - context argument for delegated call.
 */
function dispatchHandler(handlerMethod, requestOrResponse, context) {

    var i, len;
    for (i = 0, len = handlers.length; i < len && !handlers[i][handlerMethod](requestOrResponse, context); i++) {
    }

    if (i === len) {
        throw { message: "no handler for data" };
    }
}

/** Default success handler for OData.
 * @param data - Data to process.
 */
exports.defaultSuccess = function (data) {

    window.alert(window.JSON.stringify(data));
};

exports.defaultError = throwErrorCallback;

exports.defaultHandler = {

        /** Reads the body of the specified response by delegating to JSON handlers.
        * @param response - Response object.
        * @param context - Operation context.
        */
        read: function (response, context) {

            if (response && assigned(response.body) && response.headers["Content-Type"]) {
                dispatchHandler("read", response, context);
            }
        },

        /** Write the body of the specified request by delegating to JSON handlers.
        * @param request - Reques tobject.
        * @param context - Operation context.
        */
        write: function (request, context) {

            dispatchHandler("write", request, context);
        },

        maxDataServiceVersion: MAX_DATA_SERVICE_VERSION,
        accept: "application/json;q=0.9, */*;q=0.1"
    };

exports.defaultMetadata = []; //TODO check why is the defaultMetadata an Array? and not an Object.

/** Reads data from the specified URL.
 * @param urlOrRequest - URL to read data from.
 * @param {Function} [success] - 
 * @param {Function} [error] - 
 * @param {Object} [handler] - 
 * @param {Object} [httpClient] - 
 * @param {Object} [metadata] - 
 */
exports.read = function (urlOrRequest, success, error, handler, httpClient, metadata) {

    var request;
    if (urlOrRequest instanceof String || typeof urlOrRequest === "string") {
        request = { requestUri: urlOrRequest };
    } else {
        request = urlOrRequest;
    }

    return exports.request(request, success, error, handler, httpClient, metadata);
};

/** Sends a request containing OData payload to a server.
 * @param {Object} request - Object that represents the request to be sent.
 * @param {Function} [success] - 
 * @param {Function} [error] - 
 * @param {Object} [handler] - 
 * @param {Object} [httpClient] - 
 * @param {Object} [metadata] - 
 */
exports.request = function (request, success, error, handler, httpClient, metadata) {

    success = success || exports.defaultSuccess;
    error = error || exports.defaultError;
    handler = handler || exports.defaultHandler;
    httpClient = httpClient || odataNet.defaultHttpClient;
    metadata = metadata || exports.defaultMetadata;

    // Augment the request with additional defaults.
    request.recognizeDates = utils.defined(request.recognizeDates, odataJson.jsonHandler.recognizeDates);
    request.callbackParameterName = utils.defined(request.callbackParameterName, odataNet.defaultHttpClient.callbackParameterName);
    request.formatQueryString = utils.defined(request.formatQueryString, odataNet.defaultHttpClient.formatQueryString);
    request.enableJsonpCallback = utils.defined(request.enableJsonpCallback, odataNet.defaultHttpClient.enableJsonpCallback);

    // Create the base context for read/write operations, also specifying complete settings.
    var context = {
        metadata: metadata,
        recognizeDates: request.recognizeDates,
        callbackParameterName: request.callbackParameterName,
        formatQueryString: request.formatQueryString,
        enableJsonpCallback: request.enableJsonpCallback
    };

    try {
        odataUtils.prepareRequest(request, handler, context);
        return odataUtils.invokeRequest(request, success, error, handler, httpClient, context);
    } catch (err) {
        // errors in success handler for sync requests are catched here and result in error handler calls. 
        // So here we fix this and throw that error further.
        if (err.bIsSuccessHandlerError) {
            throw err;
        } else {
            error(err);
        }
    }

};

/** Parses the csdl metadata to ODataJS metatdata format. This method can be used when the metadata is retrieved using something other than odatajs
 * @param {string} csdlMetadataDocument - A string that represents the entire csdl metadata.
 * @returns {Object} An object that has the representation of the metadata in odatajs format.
 */
exports.parseMetadata = function (csdlMetadataDocument) {

    return metadataParser(null, csdlMetadataDocument);
};

// Configure the batch handler to use the default handler for the batch parts.
exports.batch.batchHandler.partHandler = exports.defaultHandler;
exports.metadataHandler =  odataMetadata.metadataHandler;
exports.jsonHandler =  odataJson.jsonHandler;