aboutsummaryrefslogblamecommitdiffstats
path: root/lib/xmlrpc.js
blob: 69bb77e1290ceb9448ad1e684a9ef028f804b8b0 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
















                                                                               
                                                                                





















































































































































                                                                      
// Released under the MIT/X11 license
// http://www.opensource.org/licenses/mit-license.php
"use strict";
/*
 *
 * xmlrpc.js beta version 1 Tool for creating XML-RPC formatted requests in
 * JavaScript
 *
 * Copyright 2001 Scott Andrew LePera scott@scottandrew.com
 * http://www.scottandrew.com/xml-rpc
 *
 * License: You are granted the right to use and/or redistribute this code only
 * if this license and the copyright notice are included and you accept that no
 * warranty of any kind is made or implied by the author.
 *
 */

var XMLRPCMessage = exports.XMLRPCMessage = function XMLRPCMessage(methodname) {
    this.method = methodname || "system.listMethods";
    this.params = [];
    return this;
}

XMLRPCMessage.prototype.setMethod = function(methodName) {
    if (!methodName) return;
    this.method = methodName;
};

XMLRPCMessage.prototype.addParameter = function(data) {
    if (arguments.length == 0) return;
    this.params[this.params.length] = data;
};

XMLRPCMessage.prototype.xml = function() {

    let method = this.method;

    // assemble the XML message header
    let xml = "";

    xml += "<?xml version=\"1.0\"?>\n";
    xml += "<methodCall>\n";
    xml += "<methodName>" + method + "</methodName>\n";
    xml += "<params>\n";

    // do individual parameters
    for ( let i = 0; i < this.params.length; i++) {
        let data = this.params[i];
        xml += "<param>\n";
        xml += "<value>"
                + this.getParamXML(this.dataTypeOf(data),
                        data) + "</value>\n";
        xml += "</param>\n";
    }

    xml += "</params>\n";
    xml += "</methodCall>";

    return xml; // for now
};

XMLRPCMessage.prototype.dataTypeOf = function(o) {
    // identifies the data type
    let type = typeof (o);
    type = type.toLowerCase();
    switch (type) {
    case "number":
        if (Math.round(o) == o)
            type = "i4";
        else
            type = "double";
        break;
    case "object":
        let con = o.constructor;
        if (con == Date)
            type = "date";
        else if (con == Array)
            type = "array";
        else
            type = "struct";
        break;
    }
    return type;
};

XMLRPCMessage.prototype.doValueXML = function(type, data) {
    let xml = "<" + type + ">" + data + "</" + type + ">";
    return xml;
};

XMLRPCMessage.prototype.doBooleanXML = function(data) {
    let value = (data == true) ? 1 : 0;
    let xml = "<boolean>" + value + "</boolean>";
    return xml;
};

XMLRPCMessage.prototype.doDateXML = function(data) {
    let leadingZero = function (n) {
        // pads a single number with a leading zero. Heh.
        if (n.length == 1)
            n = "0" + n;
        return n;
    };
    let dateToISO8601 = function(date) {
        // wow I hate working with the Date object
        let year = new String(date.getYear());
        let month = this.leadingZero(new String(date.getMonth()));
        let day = this.leadingZero(new String(date.getDate()));
        let time = this.leadingZero(new String(date.getHours())) + ":"
        + this.leadingZero(new String(date.getMinutes())) + ":"
        + this.leadingZero(new String(date.getSeconds()));

        let converted = year + month + day + "T" + time;
        return converted;
    };

    let xml = "<dateTime.iso8601>";
    xml += dateToISO8601(data);
    xml += "</dateTime.iso8601>";
    return xml;
};

XMLRPCMessage.prototype.doArrayXML = function(data) {
    let xml = "<array><data>\n";
    for ( let i = 0; i < data.length; i++) {
        xml += "<value>"
                + this.getParamXML(this.dataTypeOf(data[i]),
                        data[i]) + "</value>\n";
    }
    xml += "</data></array>\n";
    return xml;
};

XMLRPCMessage.prototype.doStructXML = function(data) {
    let xml = "<struct>\n";
    for ( let i in data) {
        xml += "<member>\n";
        xml += "<name>" + i + "</name>\n";
        xml += "<value>"
                + this.getParamXML(this.dataTypeOf(data[i]),
                        data[i]) + "</value>\n";
        xml += "</member>\n";
    }
    xml += "</struct>\n";
    return xml;
};

XMLRPCMessage.prototype.getParamXML = function(type, data) {
    let xml;
    switch (type) {
    case "date":
        xml = this.doDateXML(data);
        break;
    case "array":
        xml = this.doArrayXML(data);
        break;
    case "struct":
        xml = this.doStructXML(data);
        break;
    case "boolean":
        xml = this.doBooleanXML(data);
        break;
    default:
        xml = this.doValueXML(type, data);
        break;
    }
    return xml;
};