init
This commit is contained in:
729
jssource/src_files/include/jsolait/init.js
Normal file
729
jssource/src_files/include/jsolait/init.js
Normal file
@@ -0,0 +1,729 @@
|
||||
/*
|
||||
Copyright (c) 2003 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Evaluates script in a global scope.
|
||||
@param [0] The code to evaluate.
|
||||
*/
|
||||
globalEval=function(){
|
||||
return eval(arguments[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Creates a new class object which inherits from superClass.
|
||||
@param className="anonymous" The name of the new class.
|
||||
If the created class is a public member of a module then
|
||||
the className is automatically set.
|
||||
@param superClass=Object The class to inherit from (super class).
|
||||
@param classScope A function which is executed for class construction.
|
||||
As 1st parameter it will get the new class' protptype for
|
||||
overrideing or extending the super class. As 2nd parameter it will get
|
||||
the super class' wrapper for calling inherited methods.
|
||||
*/
|
||||
Class = function(className, superClass, classScope){
|
||||
if(arguments.length == 2){
|
||||
classScope = superClass;
|
||||
if(typeof className != "string"){
|
||||
superClass = className;
|
||||
className = "anonymous";
|
||||
}else{
|
||||
superClass = Object;
|
||||
}
|
||||
}else if(arguments.length == 1){
|
||||
classScope = className;
|
||||
superClass = Object;
|
||||
className = "anonymous";
|
||||
}
|
||||
|
||||
//this is the constructor for the new objects created from the new class.
|
||||
//if and only if it is NOT used for prototyping/subclassing the init method of the newly created object will be called.
|
||||
var NewClass = function(calledBy){
|
||||
if(calledBy !== Class){
|
||||
return this.init.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
//This will create a new prototype object of the new class.
|
||||
NewClass.createPrototype = function(){
|
||||
return new NewClass(Class);
|
||||
}
|
||||
//setting class properties for the new class.
|
||||
NewClass.superClass = superClass;
|
||||
NewClass.className=className;
|
||||
NewClass.toString = function(){
|
||||
return "[class %s]".format(NewClass.className);
|
||||
};
|
||||
if(superClass.createPrototype!=null){//see if the super class can create prototypes. (creating an object without calling init())
|
||||
NewClass.prototype = superClass.createPrototype();
|
||||
}else{//just create an object of the super class
|
||||
NewClass.prototype = new superClass();
|
||||
}
|
||||
//reset the constructor for new objects to the actual constructor.
|
||||
NewClass.prototype.constructor = NewClass;
|
||||
|
||||
if(superClass == Object){//all other objects already have a nice toString method.
|
||||
NewClass.prototype.toString = function(){
|
||||
return "[object %s]".format(this.constructor.className);
|
||||
};
|
||||
}
|
||||
|
||||
if(NewClass.prototype.init==null){
|
||||
NewClass.prototype.init=function(){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//create a supr function to be used to call methods of the super class
|
||||
var supr = function(self){
|
||||
//set up super class functionality so a call to super(this) will return an object with all super class methods
|
||||
//the methods can be called like super(this).foo and the this object will be bound to that method
|
||||
var wrapper = {};
|
||||
var superProto = superClass.prototype;
|
||||
for(var n in superProto){
|
||||
if(typeof superProto[n] == "function"){
|
||||
wrapper[n] = function(){
|
||||
var f = arguments.callee;
|
||||
return superProto[f._name].apply(self, arguments);
|
||||
}
|
||||
wrapper[n]._name = n;
|
||||
}
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
//execute the scope of the class
|
||||
classScope(NewClass.prototype, supr);
|
||||
|
||||
return NewClass;
|
||||
}
|
||||
Class.toString = function(){
|
||||
return "[object Class]";
|
||||
}
|
||||
Class.createPrototype=function(){
|
||||
throw "Can't use Class as a super class.";
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a new module and registers it.
|
||||
@param name The name of the module.
|
||||
@param version The version of a module.
|
||||
@param moduleScope A function which is executed for module creation.
|
||||
As 1st parameter it will get the module variable.
|
||||
*/
|
||||
Module = function(name, version, moduleScope){
|
||||
var mod = new Object();
|
||||
mod.version = version;
|
||||
mod.name = name;
|
||||
mod.toString=function(){
|
||||
return "[module '%s' version: %s]".format(mod.name, mod.version);
|
||||
}
|
||||
|
||||
/**
|
||||
Base class for all module-Exceptions.
|
||||
*/
|
||||
mod.Exception=Class("Exception", function(publ){
|
||||
/**
|
||||
Initializes a new Exception.
|
||||
@param msg The error message for the user.
|
||||
@param trace=null The error causing this Exception if available.
|
||||
*/
|
||||
publ.init=function(msg, trace){
|
||||
this.name = this.constructor.className;
|
||||
this.message = msg;
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
publ.toString=function(){
|
||||
var s = "%s %s\n\n".format(this.name, this.module);
|
||||
s += this.message;
|
||||
return s;
|
||||
}
|
||||
/**
|
||||
Returns the complete trace of the exception.
|
||||
@return The error trace.
|
||||
*/
|
||||
publ.toTraceString=function(){
|
||||
var s = "%s %s:\n ".format(this.name, this.module );
|
||||
s+="%s\n\n".format(this.message);
|
||||
if(this.trace){
|
||||
if(this.trace.toTraceString){
|
||||
s+= this.trace.toTraceString();
|
||||
}else{
|
||||
s+= this.trace;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
///The name of the Exception(className).
|
||||
publ.name;
|
||||
///The error message.
|
||||
publ.message;
|
||||
///The module the Exception belongs to.
|
||||
publ.module = mod;
|
||||
///The error which caused the Exception or null.
|
||||
publ.trace;
|
||||
})
|
||||
|
||||
//execute the scope of the module
|
||||
moduleScope(mod);
|
||||
|
||||
//todo: set classNames for anonymous classes.
|
||||
for(var n in mod){
|
||||
if(mod[n].className == "anonymous"){
|
||||
mod[n].className = n;
|
||||
}
|
||||
}
|
||||
|
||||
if(name != "jsolait"){
|
||||
jsolait.registerModule(mod);
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
Module.toString = function(){
|
||||
return "[object Module]";
|
||||
}
|
||||
Module.createPrototype=function(){
|
||||
throw "Can't use Module as a super class.";
|
||||
}
|
||||
|
||||
//docstart
|
||||
/**
|
||||
The root module for jsolait.
|
||||
It provides some global functionality for loading modules,
|
||||
some String enhancements.
|
||||
*/
|
||||
Module("jsolait", "0.1.0", function(mod){
|
||||
///The global jsolait object.
|
||||
jsolait=mod;
|
||||
|
||||
///base url for user modules.
|
||||
mod.baseURL=".";
|
||||
///The URL where jsolait is installed.
|
||||
mod.libURL ="./jsolait";
|
||||
///Collection of all loaded modules.(module cache)
|
||||
mod.modules = new Array();
|
||||
///The URLs of there the modules, part of jsolait.
|
||||
mod.moduleURLs = {};
|
||||
/*
|
||||
mod.moduleURLs = {urllib:"%(libURL)s/lib/urllib.js",
|
||||
xml:"%(libURL)s/lib/xml.js",
|
||||
crypto:"%(libURL)s/lib/crypto.js",
|
||||
codecs:"%(libURL)s/lib/codecs.js",
|
||||
jsonrpc:"%(libURL)s/lib/jsonrpc.js",
|
||||
lang:"%(libURL)s/lib/lang.js",
|
||||
xmlrpc:"%(libURL)s/lib/xmlrpc.js"};
|
||||
*/
|
||||
|
||||
mod.init=function(){
|
||||
if(typeof(WScript) != 'undefined') {
|
||||
initWS();
|
||||
}
|
||||
|
||||
// //make jsolait work with WScript
|
||||
// var ws = null;
|
||||
// try{//see if WScript is available
|
||||
// ws = WScript;
|
||||
// }catch(e){
|
||||
// }
|
||||
// if(ws != null){
|
||||
// initWS();
|
||||
// }
|
||||
}
|
||||
|
||||
///initializes jsolait for using it with WScript
|
||||
var initWS = function(){
|
||||
print=function(msg){
|
||||
WScript.echo(msg);
|
||||
}
|
||||
alert=function(msg){
|
||||
print(msg);
|
||||
}
|
||||
var args = WScript.arguments;
|
||||
try{
|
||||
//get script to execute
|
||||
var url = args(0);
|
||||
url = url.replace(/\\/g, "/");
|
||||
url = url.split("/");
|
||||
url = url.slice(0, url.length-1);
|
||||
//set base for user module loading
|
||||
mod.baseURL = url.join("/");
|
||||
}catch(e){
|
||||
throw new mod.Exception("Missing script filename to be run.", e);
|
||||
}
|
||||
|
||||
//location of jsolait/init.js
|
||||
url = WScript.ScriptFullName;
|
||||
|
||||
if(args(0).replace("file://","").toLowerCase() == url.toLowerCase()){
|
||||
WScript.stderr.write("Can't run myself! exiting ... \n");
|
||||
return;
|
||||
}
|
||||
url = url.replace(/\\/g, "/");
|
||||
url = url.split("/");
|
||||
url = url.slice(0, url.length-1);
|
||||
mod.libURL = "file://" + url.join("/");
|
||||
try{
|
||||
mod.loadScript(args(0));
|
||||
}catch(e){
|
||||
WScript.stdErr.write("%s(1,1) jsolait runtime error:\n%s\n".format(args(0).replace("file://",""), e.toTraceString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Imports a module given its name(someModule.someSubModule).
|
||||
A module's file location is determined by treating each module name as a directory.
|
||||
Only the last one points to a file.
|
||||
If the module's URL is not known to jsolait then it will be searched for in jsolait.baseURL which is "." by default.
|
||||
@param name The name of the module to load.
|
||||
@return The module object.
|
||||
*/
|
||||
mod.importModule = function(name){
|
||||
|
||||
if (mod.modules[name]){ //module already loaded
|
||||
return mod.modules[name];
|
||||
}else{
|
||||
var src,modURL;
|
||||
//check if jsolait already knows the url of the module(moduleURLs contains urls to modules)
|
||||
if(mod.moduleURLs[name]){
|
||||
modURL = mod.moduleURLs[name].format(mod);
|
||||
}else{
|
||||
/*
|
||||
assume it's a user module and located at baseURL
|
||||
*/
|
||||
modURL = "%s/%s.js".format(mod.baseURL, name.split(".").join("/"));
|
||||
}
|
||||
try{//to load module from location calculated above
|
||||
src = getFile(modURL);
|
||||
}catch(e){//module could not be found at the location.
|
||||
throw new mod.ModuleImportFailed(name, modURL, e);
|
||||
}
|
||||
|
||||
try{//interpret the script
|
||||
globalEval(src);
|
||||
}catch(e){
|
||||
throw new mod.ModuleImportFailed(name, modURL, e);
|
||||
}
|
||||
//the module should have registered itself
|
||||
return mod.modules[name];
|
||||
}
|
||||
}
|
||||
//make it global
|
||||
importModule = mod.importModule;
|
||||
|
||||
/**
|
||||
Loads and interprets a script file.
|
||||
@param url The url of the script to load.
|
||||
*/
|
||||
mod.loadScript=function(url){
|
||||
var src = getFile(url);
|
||||
try{//to interpret the source
|
||||
globalEval(src);
|
||||
}catch(e){
|
||||
throw new mod.EvalFailed(url, e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Registers a new module.
|
||||
Registered modules can be imported with importModule(...).
|
||||
@param module The module to register.
|
||||
*/
|
||||
mod.registerModule = function(module){
|
||||
this.modules[module.name] = module;
|
||||
}
|
||||
|
||||
/**
|
||||
Creates an HTTP request object for retreiving files.
|
||||
@return HTTP request object.
|
||||
*/
|
||||
var getHTTP=function() {
|
||||
var obj;
|
||||
try{ //to get the mozilla httprequest object
|
||||
obj = new XMLHttpRequest();
|
||||
}catch(e){
|
||||
try{ //to get MS HTTP request object
|
||||
obj=new ActiveXObject("Msxml2.XMLHTTP.4.0");
|
||||
}catch(e){
|
||||
try{ //to get MS HTTP request object
|
||||
obj=new ActiveXObject("Msxml2.XMLHTTP");
|
||||
}catch(e){
|
||||
try{// to get the old MS HTTP request object
|
||||
obj = new ActiveXObject("microsoft.XMLHTTP");
|
||||
}catch(e){
|
||||
throw new mod.Exception("Unable to get an HTTP request object.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
Retrieves a file given its URL.
|
||||
@param url The url to load.
|
||||
@param headers=[] The headers to use.
|
||||
@return The content of the file.
|
||||
*/
|
||||
var getFile=function(url, headers) {
|
||||
//if callback is defined then the operation is done async
|
||||
headers = (headers != null) ? headers : [];
|
||||
//setup the request
|
||||
try{
|
||||
var xmlhttp= getHTTP();
|
||||
xmlhttp.open("GET", url, false);
|
||||
for(var i=0;i< headers.length;i++){
|
||||
xmlhttp.setRequestHeader(headers[i][0], headers[i][1]);
|
||||
}
|
||||
xmlhttp.send("");
|
||||
}catch(e){
|
||||
throw new mod.Exception("Unable to load URL: '%s'.".format(url), e);
|
||||
}
|
||||
if(xmlhttp.status == 200 || xmlhttp.status == 0){
|
||||
return xmlhttp.responseText;
|
||||
}else{
|
||||
throw new mod.Exception("File not loaded: '%s'.".format(url));
|
||||
}
|
||||
}
|
||||
|
||||
Error.prototype.toTraceString = function(){
|
||||
if(this.message){
|
||||
return "%s\n".format(this.message);
|
||||
}
|
||||
if (this.description){
|
||||
return "%s\n".format(this.description);
|
||||
}
|
||||
return "unknown error\n";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Thrown when a module could not be found.
|
||||
*/
|
||||
mod.ModuleImportFailed=Class(mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes a new ModuleImportFailed Exception.
|
||||
@param name The name of the module.
|
||||
@param url The url of the module.
|
||||
@param trace The error cousing this Exception.
|
||||
*/
|
||||
publ.init=function(moduleName, url, trace){
|
||||
supr(this).init("Failed to import module: '%s' from URL:'%s'".format(moduleName, url), trace);
|
||||
this.moduleName = moduleName;
|
||||
this.url = url;
|
||||
}
|
||||
///The name of the module that was not found.
|
||||
publ.moduleName;
|
||||
///The url the module was expected to be found at.
|
||||
publ.url;
|
||||
})
|
||||
|
||||
/**
|
||||
Thrown when a source could not be loaded due to an interpretation error.
|
||||
*/
|
||||
mod.EvalFailed=Class(mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes a new EvalFailed exception.
|
||||
@param url The url of the module.
|
||||
@param trace The exception that was thrown while interpreting the module's source code.
|
||||
*/
|
||||
publ.init=function(url, trace){
|
||||
supr(this).init("File '%s' Eval of script failed.".format(url), trace);
|
||||
this.url = url;
|
||||
}
|
||||
///The url the module was expected to be found at.
|
||||
publ.url;
|
||||
})
|
||||
|
||||
/**
|
||||
Displays an exception and it's trace.
|
||||
This works better than alert(e) because traces are taken into account.
|
||||
@param exception The exception to display.
|
||||
*/
|
||||
mod.reportException=function(exception){
|
||||
if(exception.toTraceString){
|
||||
var s= exception.toTraceString();
|
||||
}else{
|
||||
var s = exception.toString();
|
||||
}
|
||||
var ws = null;
|
||||
try{//see if WScript is available
|
||||
ws = WScript;
|
||||
}catch(e){
|
||||
}
|
||||
if(ws != null){
|
||||
WScript.stderr.write(s);
|
||||
}else{
|
||||
alert(s);
|
||||
}
|
||||
}
|
||||
///The global exception report method;
|
||||
reportException = mod.reportException;
|
||||
})
|
||||
|
||||
//stringmod
|
||||
/**
|
||||
String formatting module.
|
||||
It allows python like string formatting ("some text %s" % "something").
|
||||
Also similar to sprintf from C.
|
||||
*/
|
||||
Module("stringformat", "0.1.0", function(mod){
|
||||
/**
|
||||
Creates a format specifier object.
|
||||
*/
|
||||
var FormatSpecifier=function(s){
|
||||
var s = s.match(/%(\(\w+\)){0,1}([ 0-]){0,1}(\+){0,1}(\d+){0,1}(\.\d+){0,1}(.)/);
|
||||
if(s[1]){
|
||||
this.key=s[1].slice(1,-1);
|
||||
}else{
|
||||
this.key = null;
|
||||
}
|
||||
this.paddingFlag = s[2];
|
||||
if(this.paddingFlag==""){
|
||||
this.paddingFlag =" "
|
||||
}
|
||||
this.signed=(s[3] == "+");
|
||||
this.minLength = parseInt(s[4]);
|
||||
if(isNaN(this.minLength)){
|
||||
this.minLength=0;
|
||||
}
|
||||
if(s[5]){
|
||||
this.percision = parseInt(s[5].slice(1,s[5].length));
|
||||
}else{
|
||||
this.percision=-1;
|
||||
}
|
||||
this.type = s[6];
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string replacing formatting specifiers with values provided as arguments
|
||||
which are formatted according to the specifier.
|
||||
This is an implementation of python's % operator for strings and is similar to sprintf from C.
|
||||
Usage:
|
||||
resultString = formatString.format(value1, v2, ...);
|
||||
|
||||
Each formatString can contain any number of formatting specifiers which are
|
||||
replaced with the formated values.
|
||||
|
||||
specifier([...]-items are optional):
|
||||
"%(key)[flag][sign][min][percision]typeOfValue"
|
||||
|
||||
(key) If specified the 1st argument is treated as an object/associative array and the formating values
|
||||
are retrieved from that object using the key.
|
||||
|
||||
flag:
|
||||
0 Use 0s for padding.
|
||||
- Left justify result, padding it with spaces.
|
||||
Use spaces for padding.
|
||||
sign:
|
||||
+ Numeric values will contain a +|- infront of the number.
|
||||
min:
|
||||
l The string will be padded with the padding character until it has a minimum length of l.
|
||||
percision:
|
||||
.x Where x is the percision for floating point numbers and the lenght for 0 padding for integers.
|
||||
typeOfValue:
|
||||
d Signed integer decimal.
|
||||
i Signed integer decimal.
|
||||
b Unsigned binary. //This does not exist in python!
|
||||
o Unsigned octal.
|
||||
u Unsigned decimal.
|
||||
x Unsigned hexidecimal (lowercase).
|
||||
X Unsigned hexidecimal (uppercase).
|
||||
e Floating point exponential format (lowercase).
|
||||
E Floating point exponential format (uppercase).
|
||||
f Floating point decimal format.
|
||||
F Floating point decimal format.
|
||||
c Single character (accepts byte or single character string).
|
||||
s String (converts any object using object.toString()).
|
||||
|
||||
Examples:
|
||||
"%02d".format(8) == "08"
|
||||
"%05.2f".format(1.234) == "01.23"
|
||||
"123 in binary is: %08b".format(123) == "123 in binary is: 01111011"
|
||||
|
||||
@param * Each parameter is treated as a formating value.
|
||||
@return The formated String.
|
||||
*/
|
||||
String.prototype.format=function(){
|
||||
var sf = this.match(/(%(\(\w+\)){0,1}[ 0-]{0,1}(\+){0,1}(\d+){0,1}(\.\d+){0,1}[dibouxXeEfFgGcrs%])|([^%]+)/g);
|
||||
if(sf){
|
||||
if(sf.join("") != this){
|
||||
throw new mod.Exception("Unsupported formating string.");
|
||||
}
|
||||
}else{
|
||||
throw new mod.Exception("Unsupported formating string.");
|
||||
}
|
||||
var rslt ="";
|
||||
var s;
|
||||
var obj;
|
||||
var cnt=0;
|
||||
var frmt;
|
||||
var sign="";
|
||||
|
||||
for(var i=0;i<sf.length;i++){
|
||||
s=sf[i];
|
||||
if(s == "%%"){
|
||||
s = "%";
|
||||
}else if(s.slice(0,1) == "%"){
|
||||
frmt = new FormatSpecifier(s);//get the formating object
|
||||
if(frmt.key){//an object was given as formating value
|
||||
if((typeof arguments[0]) == "object" && arguments.length == 1){
|
||||
obj = arguments[0][frmt.key];
|
||||
}else{
|
||||
throw new mod.Exception("Object or associative array expected as formating value.");
|
||||
}
|
||||
}else{//get the current value
|
||||
if(cnt>=arguments.length){
|
||||
throw new mod.Exception("Not enough arguments for format string");
|
||||
}else{
|
||||
obj=arguments[cnt];
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if(frmt.type == "s"){//String
|
||||
if (obj == null){
|
||||
obj = "null";
|
||||
}
|
||||
s=obj.toString().pad(frmt.paddingFlag, frmt.minLength);
|
||||
|
||||
}else if(frmt.type == "c"){//Character
|
||||
if(frmt.paddingFlag == "0"){
|
||||
frmt.paddingFlag=" ";//padding only spaces
|
||||
}
|
||||
if(typeof obj == "number"){//get the character code
|
||||
s = String.fromCharCode(obj).pad(frmt.paddingFlag , frmt.minLength) ;
|
||||
}else if(typeof obj == "string"){
|
||||
if(obj.length == 1){
|
||||
/*
|
||||
make sure it's a single character
|
||||
*/
|
||||
s=obj.pad(frmt.paddingFlag, frmt.minLength);
|
||||
}else{
|
||||
throw new mod.Exception("Character of length 1 required.");
|
||||
}
|
||||
}else{
|
||||
throw new mod.Exception("Character or Byte required.");
|
||||
}
|
||||
}else if(typeof obj == "number"){
|
||||
//get sign of the number
|
||||
if(obj < 0){
|
||||
obj = -obj;
|
||||
sign = "-"; //negative signs are always needed
|
||||
}else if(frmt.signed){
|
||||
sign = "+"; // if sign is always wanted add it
|
||||
}else{
|
||||
sign = "";
|
||||
}
|
||||
//do percision padding and number conversions
|
||||
switch(frmt.type){
|
||||
case "f": //floats
|
||||
case "F":
|
||||
if(frmt.percision > -1){
|
||||
s = obj.toFixed(frmt.percision).toString();
|
||||
}else{
|
||||
s = obj.toString();
|
||||
}
|
||||
break;
|
||||
case "E"://exponential
|
||||
case "e":
|
||||
if(frmt.percision > -1){
|
||||
s = obj.toExponential(frmt.percision);
|
||||
}else{
|
||||
s = obj.toExponential();
|
||||
}
|
||||
s = s.replace("e", frmt.type);
|
||||
break;
|
||||
case "b"://binary
|
||||
s = obj.toString(2);
|
||||
s = s.pad("0", frmt.percision);
|
||||
break;
|
||||
case "o"://octal
|
||||
s = obj.toString(8);
|
||||
s = s.pad("0", frmt.percision);
|
||||
break;
|
||||
case "x"://hexadecimal
|
||||
s = obj.toString(16).toLowerCase();
|
||||
s = s.pad("0", frmt.percision);
|
||||
break;
|
||||
case "X"://hexadecimal
|
||||
s = obj.toString(16).toUpperCase();
|
||||
s = s.pad("0", frmt.percision);
|
||||
break;
|
||||
default://integers
|
||||
s = parseInt(obj).toString();
|
||||
s = s.pad("0", frmt.percision);
|
||||
break;
|
||||
}
|
||||
if(frmt.paddingFlag == "0"){//do 0-padding
|
||||
//make sure that the length of the possible sign is not ignored
|
||||
s=s.pad("0", frmt.minLength - sign.length);
|
||||
}
|
||||
s=sign + s;//add sign
|
||||
s=s.pad(frmt.paddingFlag, frmt.minLength);//do padding and justifiing
|
||||
}else{
|
||||
throw new mod.Exception("Number required.");
|
||||
}
|
||||
}
|
||||
rslt += s;
|
||||
}
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/**
|
||||
Padds a String with a character to have a minimum length.
|
||||
|
||||
@param flag "-": to padd with " " and left justify the string.
|
||||
Other: the character to use for padding.
|
||||
@param len The minimum length of the resulting string.
|
||||
*/
|
||||
String.prototype.pad = function(flag, len){
|
||||
var s = "";
|
||||
if(flag == "-"){
|
||||
var c = " ";
|
||||
}else{
|
||||
var c = flag;
|
||||
}
|
||||
for(var i=0;i<len-this.length;i++){
|
||||
s += c;
|
||||
}
|
||||
if(flag == "-"){
|
||||
s = this + s;
|
||||
}else{
|
||||
s += this;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
Repeats a string.
|
||||
@param c The count how often the string should be repeated.
|
||||
*/
|
||||
String.prototype.mul = function(c){
|
||||
var a = new Array(this.length * c);
|
||||
var s=""+ this;
|
||||
for(var i=0;i<c;i++){
|
||||
a[i] = s;
|
||||
}
|
||||
return a.join("");
|
||||
}
|
||||
})
|
||||
//let jsolait do some startup initialization
|
||||
jsolait.init();
|
||||
|
||||
168
jssource/src_files/include/jsolait/lib/codecs.js
Normal file
168
jssource/src_files/include/jsolait/lib/codecs.js
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
Copyright (c) 2004 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Codecs for encoding decoding Strings.
|
||||
To add new encoders simply create new String.prototype.encode_yourCodec methods.
|
||||
To add new decoders simply create new String.prototype.decode_yourCodec methods.
|
||||
*/
|
||||
Module("codecs", "0.1.2", function(mod){
|
||||
/**
|
||||
Returns all all available encoders.
|
||||
@return An array of encoder names.
|
||||
*/
|
||||
mod.listEncoders=function(){
|
||||
var c=[];
|
||||
for(var attr in String.prototype){
|
||||
if(attr.slice(0, 7) == "encode_"){
|
||||
c.push(attr.slice(7));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
/**
|
||||
Returns all all available decoders.
|
||||
@return An array of decoder names.
|
||||
*/
|
||||
mod.listDecoders=function(){
|
||||
var c=[];
|
||||
for(var attr in String.prototype){
|
||||
if(attr.slice(0, 7) == "decode_"){
|
||||
c.push(attr.slice(7));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
Decodes an encoded string.
|
||||
Parameters but the codec parameter are forwardet to the codec.
|
||||
@param codec The codec to use.
|
||||
*/
|
||||
String.prototype.decode = function(codec){
|
||||
var n ="decode_" + codec;
|
||||
if(String.prototype[n]){
|
||||
var args=[];
|
||||
for(var i=1;i<arguments.length;i++){
|
||||
args[i-1] = arguments[i];
|
||||
}
|
||||
return String.prototype[n].apply(this, args);
|
||||
}else{
|
||||
throw new mod.Exception("Decoder '%s' not found.".format(codec));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Encodes a string.
|
||||
Parameters but the codec parameter are forwardet to the codec.
|
||||
@param codec The codec to use.
|
||||
*/
|
||||
String.prototype.encode = function(codec){
|
||||
var n ="encode_" + codec;
|
||||
if(String.prototype[n]){
|
||||
var args=[];
|
||||
for(var i=1;i<arguments.length;i++){
|
||||
args[i-1] = arguments[i];
|
||||
}
|
||||
return String.prototype[n].apply(this, args);
|
||||
}else{
|
||||
throw new mod.Exception("Ecnoder '%s' not found.".format(codec));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Decodes a Base64 encoded string to a byte string.
|
||||
*/
|
||||
String.prototype.decode_base64=function(){
|
||||
if((this.length % 4) == 0){
|
||||
if(typeof(atob) != "undefined"){//try using mozillas builtin codec
|
||||
return atob(this);
|
||||
}else{
|
||||
var nBits;
|
||||
//create a result buffer, this is much faster than having strings concatinated.
|
||||
var sDecoded = new Array(this.length /4);
|
||||
var base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
for(var i=0; i < this.length; i+=4){
|
||||
nBits = (base64.indexOf(this.charAt(i)) & 0xff) << 18 |
|
||||
(base64.indexOf(this.charAt(i+1)) & 0xff) << 12 |
|
||||
(base64.indexOf(this.charAt(i+2)) & 0xff) << 6 |
|
||||
base64.indexOf(this.charAt(i+3)) & 0xff;
|
||||
sDecoded[i] = String.fromCharCode((nBits & 0xff0000) >> 16, (nBits & 0xff00) >> 8, nBits & 0xff);
|
||||
}
|
||||
//make sure padding chars are left out.
|
||||
sDecoded[sDecoded.length-1] = sDecoded[sDecoded.length-1].substring(0, 3 - ((this.charCodeAt(i - 2) == 61) ? 2 : (this.charCodeAt(i - 1) == 61 ? 1 : 0)));
|
||||
return sDecoded.join("");
|
||||
}
|
||||
}else{
|
||||
throw new mod.Exception("String length must be divisible by 4.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Encodes a string using Base64.
|
||||
*/
|
||||
String.prototype.encode_base64=function(){
|
||||
if(typeof(btoa) != "undefined"){//try using mozillas builtin codec
|
||||
return btoa(this);
|
||||
}else{
|
||||
var base64 = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
||||
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
|
||||
'0','1','2','3','4','5','6','7','8','9','+','/'];
|
||||
var sbin;
|
||||
var pad=0;
|
||||
var s="" + this;
|
||||
if((s.length % 3) == 1){
|
||||
s+=String.fromCharCode(0);
|
||||
s+=String.fromCharCode(0);
|
||||
pad=2;
|
||||
}else if((s.length % 3) == 2){
|
||||
s+=String.fromCharCode(0);
|
||||
pad=1;
|
||||
}
|
||||
//create a result buffer, this is much faster than having strings concatinated.
|
||||
var rslt=new Array(s.length / 3);
|
||||
var ri=0;
|
||||
for(var i=0;i<s.length; i+=3){
|
||||
sbin=((s.charCodeAt(i) & 0xff) << 16) | ((s.charCodeAt(i+1) & 0xff ) << 8) | (s.charCodeAt(i+2) & 0xff);
|
||||
rslt[ri] = (base64[(sbin >> 18) & 0x3f] + base64[(sbin >> 12) & 0x3f] + base64[(sbin >>6) & 0x3f] + base64[sbin & 0x3f]);
|
||||
ri++;
|
||||
}
|
||||
if(pad>0){
|
||||
rslt[rslt.length-1] = rslt[rslt.length-1].substr(0, 4-pad) + ((pad==2) ? "==" : (pad==1) ? "=" : "");
|
||||
}
|
||||
return rslt.join("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Decodes a URI using decodeURI.
|
||||
*/
|
||||
String.prototype.decode_uri=function(){
|
||||
return decodeURI(this);
|
||||
}
|
||||
|
||||
/**
|
||||
Encodes a URI using encodeURI.
|
||||
*/
|
||||
String.prototype.encode_uri=function(){
|
||||
return encodeURI(this);
|
||||
}
|
||||
})
|
||||
149
jssource/src_files/include/jsolait/lib/crypto.js
Normal file
149
jssource/src_files/include/jsolait/lib/crypto.js
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
Copyright (c) 2003 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
Cryptography module.
|
||||
Provides String encryption/decryption and hashing.
|
||||
*/
|
||||
Module("crypto", "0.1.2", function(mod){
|
||||
/**
|
||||
Returns all all available encrypters.
|
||||
@return An array of encrypters names.
|
||||
*/
|
||||
mod.listEncrypters=function(){
|
||||
var c=[];
|
||||
for(var attr in String.prototype){
|
||||
if(attr.slice(0, 8) == "encrypt_"){
|
||||
c.push(attr.slice(8));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
/**
|
||||
Returns all all available decrypters.
|
||||
@return An array of decrypters names.
|
||||
*/
|
||||
mod.listDecrypters=function(){
|
||||
var c=[];
|
||||
for(var attr in String.prototype){
|
||||
if(attr.slice(0, 8) == "decrypt_"){
|
||||
c.push(attr.slice(8));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
Encrypts a string.
|
||||
Parameters but the crypdec parameter are forwardet to the crypdec.
|
||||
@param codec The codec to use.
|
||||
*/
|
||||
String.prototype.encrypt=function(crydec){
|
||||
var n = "encrypt_" + crydec;
|
||||
if(String.prototype[n]){
|
||||
var args=[];
|
||||
for(var i=1;i<arguments.length;i++){
|
||||
args[i-1] = arguments[i];
|
||||
}
|
||||
return String.prototype[n].apply(this, args);
|
||||
}else{
|
||||
throw new mod.Exception("Decrypter '%s' not found.".format(crydec));
|
||||
}
|
||||
}
|
||||
/**
|
||||
Decrypts a string.
|
||||
Parameters but the crypdec parameter are forwardet to the crypdec.
|
||||
@param codec The codec to use.
|
||||
*/
|
||||
String.prototype.decrypt=function(crydec){
|
||||
var n = "decrypt_" + crydec;
|
||||
if(String.prototype[n]){
|
||||
var args=[];
|
||||
for(var i=1;i<arguments.length;i++){
|
||||
args[i-1] = arguments[i];
|
||||
}
|
||||
return String.prototype[n].apply(this, args);
|
||||
}else{
|
||||
throw new mod.Exception("Encrypter '%s' not found.".format(crydec));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Encrypts a string using XOR.
|
||||
The whole String will be XORed with the key.
|
||||
If the key is shorter than the String then it will be multiplied to fit the length of the String.
|
||||
@param key The key to use for encryption.
|
||||
*/
|
||||
String.prototype.encrypt_xor=function(key){
|
||||
var e=new Array(this.length);
|
||||
var l=key.length;
|
||||
for(var i=0;i<this.length;i++){
|
||||
e[i] = String.fromCharCode(this.charCodeAt(i) ^ key.charCodeAt(i % l));
|
||||
}
|
||||
return e.join("");
|
||||
}
|
||||
/**
|
||||
Decrypts a string using XOR.
|
||||
Since XORing is symetric it is the same as the encrypter.
|
||||
@param key The key to use for decryption.
|
||||
*/
|
||||
String.prototype.decrypt_xor=String.prototype.encrypt_xor;
|
||||
/**
|
||||
Encrypts a string using the ARC4 algorithm.
|
||||
@param key The key to use for encryption.
|
||||
*/
|
||||
String.prototype.encrypt_rc4=function(key){
|
||||
//generate substitution box
|
||||
var sbox = new Array (256);
|
||||
for (var i=0; i<256; i++){
|
||||
sbox[i]=i;
|
||||
}
|
||||
|
||||
//swap things around
|
||||
var j=0;
|
||||
for (var i=0; i < 256; i++) {
|
||||
j = (j + sbox[i] + key.charCodeAt(i % key.length)) % 256;
|
||||
var tmp = sbox[i];
|
||||
sbox[i] = sbox[j];
|
||||
sbox[j] = tmp;
|
||||
}
|
||||
|
||||
//calculate the result
|
||||
var i=256;
|
||||
var j=256;
|
||||
var rslt=new Array(this.length);
|
||||
for (var k=0; k < this.length; k++) {
|
||||
i = (i + 1) % 256;
|
||||
j = (j + sbox[i]) % 256;
|
||||
var tmp = sbox[i];
|
||||
sbox[i] = sbox[j];
|
||||
sbox[j] = tmp;
|
||||
t = (sbox[i] + sbox[j]) % 256;
|
||||
rslt[k] = String.fromCharCode(this.charCodeAt(k) ^ sbox[t]);
|
||||
}
|
||||
return rslt.join("");
|
||||
}
|
||||
/**
|
||||
Decrypts a string using the ARC4 algorithm.
|
||||
Since it is symetric it is the same as the encrypter.
|
||||
@param key The key to use for decryption.
|
||||
*/
|
||||
String.prototype.decrypt_rc4=String.prototype.encrypt_rc4;
|
||||
})
|
||||
401
jssource/src_files/include/jsolait/lib/jsonrpc.js
Normal file
401
jssource/src_files/include/jsolait/lib/jsonrpc.js
Normal file
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
Copyright (c) 2003-2004 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
Provides an JSON-RPC imlementation.
|
||||
*/
|
||||
Module("jsonrpc", "0.3.2", function(mod){
|
||||
|
||||
var lang = importModule("lang");
|
||||
var tokens = lang.tokens;
|
||||
|
||||
var ObjectBuffer=Class("ObjectBuffer", function(publ, supr){
|
||||
publ.init=function(){
|
||||
this.data="";
|
||||
}
|
||||
publ.getObjects=function(data){
|
||||
this.data += data;
|
||||
var t = new lang.Tokenizer(this.data);
|
||||
var brCnt= 0;
|
||||
var objects = [];
|
||||
var readCnt = 0
|
||||
while(! t.finished()){
|
||||
var n = t.next();
|
||||
if(n.type != tokens.ERR){
|
||||
if(n.value == "{"){
|
||||
brCnt+=1;
|
||||
}else if(n.value == "}"){
|
||||
brCnt-=1;
|
||||
if(brCnt==0){
|
||||
var s = this.data.slice(readCnt, n.pos+1);
|
||||
readCnt += s.length;
|
||||
objects.push(s);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.data = this.data.slice(readCnt);
|
||||
return objects;
|
||||
}
|
||||
})
|
||||
|
||||
var nameAllowed=function(name){
|
||||
return name.match(/^[a-zA-Z]\w*$/) != null;
|
||||
}
|
||||
|
||||
var getMethodByName=function(obj, name){
|
||||
try{//to get a method by asking the service
|
||||
obj = obj._getMethodByName(name)
|
||||
}catch(e){
|
||||
var names = name.split(".");
|
||||
for(var i=0;i<names.length;i++){
|
||||
name = names[i];
|
||||
if(nameAllowed(name)){
|
||||
obj = obj[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
var Response=Class("Response", function(publ, supr){
|
||||
publ.init=function(id, result, error){
|
||||
this.id=id;
|
||||
this.result = result;
|
||||
this.error = error;
|
||||
}
|
||||
publ._toJSON=function(){
|
||||
var p = [lang.objToJson(this.id), lang.objToJson(this.result),lang.objToJson(this.error)];
|
||||
return '{"id":' + p[0] + ', "result":' + p[1] + ', "error":' + p[2] + "}";
|
||||
}
|
||||
})
|
||||
|
||||
var Request=Class("Request", function(publ, supr){
|
||||
publ.init=function(id, method, params){
|
||||
this.id=id;
|
||||
this.method = method;
|
||||
this.params = params;
|
||||
/*
|
||||
var str = '';
|
||||
for(hello in this.params)
|
||||
{
|
||||
str += "var:"+hello+":"+this.params[hello]+":\n";
|
||||
}
|
||||
alert(str);
|
||||
*/
|
||||
}
|
||||
publ._toJSON=function(){
|
||||
var p = [lang.objToJson(this.id), lang.objToJson(this.method),lang.objToJson(this.params)];
|
||||
return '{"id":' + p[0] + ', "method":' + p[1] + ', "params":' + p[2] + "}";
|
||||
}
|
||||
})
|
||||
|
||||
var Notification=Class("Notification", function(publ, supr){
|
||||
publ.init=function(method, params){
|
||||
this.method = method;
|
||||
this.params = params;
|
||||
}
|
||||
publ._toJSON=function(){
|
||||
var p = [lang.objToJson(this.method),lang.objToJson(this.params)];
|
||||
return '{"method":' + p[0] + ', "params":' + p[1] + "}";
|
||||
}
|
||||
})
|
||||
|
||||
var ResponseHandler=Class("ResponseHandler", function(publ, supr){
|
||||
publ.init=function(callback){
|
||||
this.callback=callback;
|
||||
}
|
||||
publ.handleResponse=function(resp){
|
||||
this.callback(resp.result, resp.error);
|
||||
}
|
||||
})
|
||||
|
||||
var RPCLib = Class("RPCLib", function(publ, supr){
|
||||
|
||||
})
|
||||
|
||||
var BaseConnectionHandler = Class("BaseConnectionHandler", function(publ, supr){
|
||||
publ.init=function(service){
|
||||
this.service = service;
|
||||
this.jsonParser = new lang.JSONParser();
|
||||
this.jsonParser.addLib(new RPCLib(), "rpc", []);
|
||||
this.respHandlers = [];
|
||||
this.objBuffer = new ObjectBuffer();
|
||||
}
|
||||
|
||||
publ.addResponseHandler=function(cb){
|
||||
var id=1;
|
||||
while(this.respHandlers[""+id] ){
|
||||
id+=1;
|
||||
}
|
||||
id="" + id;
|
||||
this.respHandlers[id] = new ResponseHandler(cb);
|
||||
return id;
|
||||
}
|
||||
|
||||
publ.send = function(data){
|
||||
}
|
||||
|
||||
publ.sendNotify = function(name, args){
|
||||
var n = new Notification(name, args);
|
||||
n = this.jsonParser.objToJson(n);
|
||||
this.send(n)
|
||||
}
|
||||
|
||||
publ.sendRequest = function(name, args, callback){
|
||||
var id = this.addResponseHandler(callback);
|
||||
var r = new Request(id, name, args);
|
||||
r = this.jsonParser.objToJson(r);
|
||||
this.send(r);
|
||||
}
|
||||
|
||||
publ.sendResponse = function(id, result, error){
|
||||
var r = new Response(id, result, error);
|
||||
r = this.jsonParser.objToJson(r);
|
||||
this.send(r);
|
||||
}
|
||||
|
||||
publ.handleRequest = function(req){
|
||||
var name = req.method;
|
||||
var params = req.params;
|
||||
var id=req.id;
|
||||
if(this.service[name]){
|
||||
try{
|
||||
var rslt = this.service[name].apply(this.service,params);
|
||||
this.sendResponse(id, rslt, null)
|
||||
}catch(e){
|
||||
this.sendResponse(id, null, new ApplicationError("" + e))
|
||||
}
|
||||
}else{
|
||||
this.sendResponse(id, null, new MethodNotFound());
|
||||
}
|
||||
}
|
||||
|
||||
publ.handleNotification = function(notif){
|
||||
if(this.service[notif.method]){
|
||||
try{
|
||||
this.service[notif.method].apply(this.service, notif.params);
|
||||
}catch(e){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publ.handleResponse = function(resp){
|
||||
var id=resp.id;
|
||||
var h = this.respHandlers[id];
|
||||
h.handleResponse(resp)
|
||||
delete this.respHandlers[id]
|
||||
}
|
||||
|
||||
publ.handleData = function(data){
|
||||
var objs = this.objBuffer.getObjects(data);
|
||||
for(var i=0;i<objs.length;i++){
|
||||
try{
|
||||
var obj = this.jsonParser.jsonToObj(objs[i]);
|
||||
}catch(e){
|
||||
throw "Not well formed";
|
||||
}
|
||||
if(obj.method != null){
|
||||
if(obj.id != null){
|
||||
this.handleRequest(new Request(obj.id, obj.method, obj.params));
|
||||
}else{
|
||||
this.handleNotification(new Notification(obj.method, obj.params));
|
||||
}
|
||||
}else if(obj.id != null){
|
||||
this.handleResponse(new Response(obj.id, obj.result, obj.error));
|
||||
}else{
|
||||
throw "Unknown Data";
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
var SocketConnectionHandler = Class("SocketConnectionHandler", BaseConnectionHandler, function(publ, supr){
|
||||
publ.init=function(socket, localService){
|
||||
this.socket = socket;
|
||||
socket.addEventListener("connectionData", this, false);
|
||||
supr(this).init( localService);
|
||||
}
|
||||
|
||||
publ.handleEvent=function(evt){
|
||||
this.handleData(evt.data);
|
||||
}
|
||||
|
||||
publ.send=function(data){
|
||||
this.socket.send(data);
|
||||
}
|
||||
|
||||
publ.close=function(data){
|
||||
this.socket.close();
|
||||
}
|
||||
})
|
||||
|
||||
var HTTPConnectionHandler = Class("HTTPConnectionHandler", BaseConnectionHandler, function(publ, supr){
|
||||
var urllib;
|
||||
publ.request_id = 1;
|
||||
publ.init=function(url, localService){
|
||||
urllib=importModule("urllib");
|
||||
this.url = url;
|
||||
supr(this).init( localService);
|
||||
}
|
||||
|
||||
publ.handleData = function(data){
|
||||
|
||||
try{
|
||||
var obj = JSON.parse(data);
|
||||
}catch(e){;
|
||||
throw " Not well formed\n\n" + e + "\n\nResponse from server:\n\n " + data;
|
||||
}
|
||||
if(obj.id != null){
|
||||
return obj;
|
||||
}else{
|
||||
throw "Unknown Data (No id property found)";
|
||||
}
|
||||
}
|
||||
|
||||
publ.sendRequest = function(name, args, callback){
|
||||
var sync = false;
|
||||
if(typeof callback != "function"){//see if it is sync
|
||||
args.push(callback);
|
||||
sync=true;
|
||||
}
|
||||
var data = new Request(this.request_id++, name, args);
|
||||
// cn: bug 12274 - defend against CSRF
|
||||
data = JSON.stringify(data); // creates security envelope wrapped JSON object
|
||||
|
||||
if(sync){
|
||||
var rsp = urllib.postURL(this.url, data, [["Content-Type", "text/plain"]]);
|
||||
rsp = this.handleData(rsp.responseText);
|
||||
if(rsp.error){
|
||||
throw rsp.error;
|
||||
}else{
|
||||
return rsp.result;
|
||||
}
|
||||
}else{//async connection uses the respHandler to handle the repsonse
|
||||
var self = this;
|
||||
var request_id = this.request_id;
|
||||
urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){
|
||||
try{
|
||||
rsp = self.handleData(rsp.responseText);
|
||||
}catch(e){
|
||||
//callback(null,e);
|
||||
callback(request_id,null,e);
|
||||
return;
|
||||
}
|
||||
callback(request_id,rsp.result, rsp.error);
|
||||
//callback(this.request_id,rsp.result, rsp.error);
|
||||
//callback(rsp.result, rsp.error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
publ.sendNotify = function(name, args){
|
||||
var data = new Notification(name, args);
|
||||
data = this.jsonParser.objToJson(data);
|
||||
urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){});
|
||||
}
|
||||
})
|
||||
|
||||
var PeerObject=Class("PeerObject", function(publ, supr){
|
||||
publ.init=function(name, conn){
|
||||
var fn=function(){
|
||||
var args=[];
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
var cb=args.pop();
|
||||
return conn.sendRequest(name, args, cb);
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
})
|
||||
|
||||
var PeerNotifyObject=Class("PeerNotifyObject", function(publ, supr){
|
||||
publ.init=function(name, conn){
|
||||
var fn=function(){
|
||||
var args=[];
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
conn.sendNotify(name, args);
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
})
|
||||
|
||||
var BasePeer = Class("BasePeer", function(publ, supr){
|
||||
publ.init=function(conn, methodNames){
|
||||
this._conn = conn;
|
||||
this.notify = new PeerObject("notify", conn);
|
||||
this._add(methodNames);
|
||||
}
|
||||
|
||||
var setupPeerMethod=function(root, methodName, conn, MethClass){
|
||||
var names = methodName.split(".");
|
||||
var obj = root;
|
||||
for(var n=0;n<names.length-1;n++){
|
||||
var name = names[n];
|
||||
if(obj[name]){
|
||||
obj = obj[name];
|
||||
}else{
|
||||
obj[name] = new Object();
|
||||
obj = obj[name];
|
||||
}
|
||||
}
|
||||
var name = names[names.length-1];
|
||||
if(obj[name]){
|
||||
}else{
|
||||
var mth = new MethClass(methodName, conn);
|
||||
obj[name] = mth;
|
||||
}
|
||||
}
|
||||
|
||||
publ._add = function(methodNames){
|
||||
for(var i=0;i<methodNames.length;i++){
|
||||
setupPeerMethod(this, methodNames[i], this._conn, PeerObject);
|
||||
setupPeerMethod(this.notify, methodNames[i], this._conn, PeerNotifyObject);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
mod.ServiceProxy = Class("ServiceProxy", BasePeer, function(publ, supr){
|
||||
publ.init = function(url, methodNames, localService){
|
||||
var n = url.match(/^jsonrpc:\/\/(.*:\d*)$/);
|
||||
if(n!=null){//is it json-rpc over TCP protocoll
|
||||
var hostaddr = n[1];
|
||||
try{
|
||||
var socket = createConnection();
|
||||
}catch(e){
|
||||
throw "Can't create a socket connection."
|
||||
}
|
||||
socket.connect(hostaddr);
|
||||
supr(this).init( new SocketConnectionHandler(socket, localService), methodNames);
|
||||
}else{//or is it json-rpc over http
|
||||
this.httpConn = new HTTPConnectionHandler(url, localService);
|
||||
supr(this).init( this.httpConn, methodNames);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
406
jssource/src_files/include/jsolait/lib/jsonrpclite.js
Normal file
406
jssource/src_files/include/jsolait/lib/jsonrpclite.js
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
Copyright (c) 2003-2004 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
// SUGARCRM:
|
||||
// USES the langlite.php instead of lang.php
|
||||
Provides an JSON-RPC imlementation.
|
||||
*/
|
||||
Module("jsonrpclite", "0.3.2", function(mod){
|
||||
|
||||
// SUGARCRM:
|
||||
var lang = importModule("langlite");
|
||||
// END SUGARCRM
|
||||
var tokens = lang.tokens;
|
||||
|
||||
var ObjectBuffer=Class("ObjectBuffer", function(publ, supr){
|
||||
publ.init=function(){
|
||||
this.data="";
|
||||
}
|
||||
publ.getObjects=function(data){
|
||||
this.data += data;
|
||||
var t = new lang.Tokenizer(this.data);
|
||||
var brCnt= 0;
|
||||
var objects = [];
|
||||
var readCnt = 0
|
||||
while(! t.finished()){
|
||||
var n = t.next();
|
||||
if(n.type != tokens.ERR){
|
||||
if(n.value == "{"){
|
||||
brCnt+=1;
|
||||
}else if(n.value == "}"){
|
||||
brCnt-=1;
|
||||
if(brCnt==0){
|
||||
var s = this.data.slice(readCnt, n.pos+1);
|
||||
readCnt += s.length;
|
||||
objects.push(s);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.data = this.data.slice(readCnt);
|
||||
return objects;
|
||||
}
|
||||
})
|
||||
|
||||
var nameAllowed=function(name){
|
||||
return name.match(/^[a-zA-Z]\w*$/) != null;
|
||||
}
|
||||
|
||||
var getMethodByName=function(obj, name){
|
||||
try{//to get a method by asking the service
|
||||
obj = obj._getMethodByName(name)
|
||||
}catch(e){
|
||||
var names = name.split(".");
|
||||
for(var i=0;i<names.length;i++){
|
||||
name = names[i];
|
||||
if(nameAllowed(name)){
|
||||
obj = obj[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
var Response=Class("Response", function(publ, supr){
|
||||
publ.init=function(id, result, error){
|
||||
this.id=id;
|
||||
this.result = result;
|
||||
this.error = error;
|
||||
}
|
||||
publ._toJSON=function(){
|
||||
var p = [lang.objToJson(this.id), lang.objToJson(this.result),lang.objToJson(this.error)];
|
||||
return '{"id":' + p[0] + ', "result":' + p[1] + ', "error":' + p[2] + "}";
|
||||
}
|
||||
})
|
||||
|
||||
var Request=Class("Request", function(publ, supr){
|
||||
publ.init=function(id, method, params){
|
||||
this.id=id;
|
||||
this.method = method;
|
||||
this.params = params;
|
||||
/*
|
||||
var str = '';
|
||||
for(hello in this.params)
|
||||
{
|
||||
str += "var:"+hello+":"+this.params[hello]+":\n";
|
||||
}
|
||||
alert(str);
|
||||
*/
|
||||
}
|
||||
publ._toJSON=function(){
|
||||
var p = [lang.objToJson(this.id), lang.objToJson(this.method),lang.objToJson(this.params)];
|
||||
return '{"id":' + p[0] + ', "method":' + p[1] + ', "params":' + p[2] + "}";
|
||||
}
|
||||
})
|
||||
|
||||
var Notification=Class("Notification", function(publ, supr){
|
||||
publ.init=function(method, params){
|
||||
this.method = method;
|
||||
this.params = params;
|
||||
}
|
||||
publ._toJSON=function(){
|
||||
var p = [lang.objToJson(this.method),lang.objToJson(this.params)];
|
||||
return '{"method":' + p[0] + ', "params":' + p[1] + "}";
|
||||
}
|
||||
})
|
||||
|
||||
var ResponseHandler=Class("ResponseHandler", function(publ, supr){
|
||||
publ.init=function(callback){
|
||||
this.callback=callback;
|
||||
}
|
||||
publ.handleResponse=function(resp){
|
||||
this.callback(resp.result, resp.error);
|
||||
}
|
||||
})
|
||||
|
||||
var RPCLib = Class("RPCLib", function(publ, supr){
|
||||
|
||||
})
|
||||
|
||||
var BaseConnectionHandler = Class("BaseConnectionHandler", function(publ, supr){
|
||||
publ.init=function(service){
|
||||
this.service = service;
|
||||
this.jsonParser = new lang.JSONParser();
|
||||
this.jsonParser.addLib(new RPCLib(), "rpc", []);
|
||||
this.respHandlers = [];
|
||||
this.objBuffer = new ObjectBuffer();
|
||||
}
|
||||
|
||||
publ.addResponseHandler=function(cb){
|
||||
var id=1;
|
||||
while(this.respHandlers[""+id] ){
|
||||
id+=1;
|
||||
}
|
||||
id="" + id;
|
||||
this.respHandlers[id] = new ResponseHandler(cb);
|
||||
return id;
|
||||
}
|
||||
|
||||
publ.send = function(data){
|
||||
}
|
||||
|
||||
publ.sendNotify = function(name, args){
|
||||
var n = new Notification(name, args);
|
||||
n = this.jsonParser.objToJson(n);
|
||||
this.send(n)
|
||||
}
|
||||
|
||||
publ.sendRequest = function(name, args, callback){
|
||||
var id = this.addResponseHandler(callback);
|
||||
var r = new Request(id, name, args);
|
||||
r = this.jsonParser.objToJson(r);
|
||||
this.send(r);
|
||||
}
|
||||
|
||||
publ.sendResponse = function(id, result, error){
|
||||
var r = new Response(id, result, error);
|
||||
r = this.jsonParser.objToJson(r);
|
||||
this.send(r);
|
||||
}
|
||||
|
||||
publ.handleRequest = function(req){
|
||||
var name = req.method;
|
||||
var params = req.params;
|
||||
var id=req.id;
|
||||
if(this.service[name]){
|
||||
try{
|
||||
var rslt = this.service[name].apply(this.service,params);
|
||||
this.sendResponse(id, rslt, null)
|
||||
}catch(e){
|
||||
this.sendResponse(id, null, new ApplicationError("" + e))
|
||||
}
|
||||
}else{
|
||||
this.sendResponse(id, null, new MethodNotFound());
|
||||
}
|
||||
}
|
||||
|
||||
publ.handleNotification = function(notif){
|
||||
if(this.service[notif.method]){
|
||||
try{
|
||||
this.service[notif.method].apply(this.service, notif.params);
|
||||
}catch(e){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publ.handleResponse = function(resp){
|
||||
var id=resp.id;
|
||||
var h = this.respHandlers[id];
|
||||
h.handleResponse(resp)
|
||||
delete this.respHandlers[id]
|
||||
}
|
||||
|
||||
publ.handleData = function(data){
|
||||
var objs = this.objBuffer.getObjects(data);
|
||||
for(var i=0;i<objs.length;i++){
|
||||
try{
|
||||
var obj = this.jsonParser.jsonToObj(objs[i]);
|
||||
}catch(e){
|
||||
throw "Not well formed";
|
||||
}
|
||||
if(obj.method != null){
|
||||
if(obj.id != null){
|
||||
this.handleRequest(new Request(obj.id, obj.method, obj.params));
|
||||
}else{
|
||||
this.handleNotification(new Notification(obj.method, obj.params));
|
||||
}
|
||||
}else if(obj.id != null){
|
||||
this.handleResponse(new Response(obj.id, obj.result, obj.error));
|
||||
}else{
|
||||
throw "Unknown Data";
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
var SocketConnectionHandler = Class("SocketConnectionHandler", BaseConnectionHandler, function(publ, supr){
|
||||
publ.init=function(socket, localService){
|
||||
this.socket = socket;
|
||||
socket.addEventListener("connectionData", this, false);
|
||||
supr(this).init( localService);
|
||||
}
|
||||
|
||||
publ.handleEvent=function(evt){
|
||||
this.handleData(evt.data);
|
||||
}
|
||||
|
||||
publ.send=function(data){
|
||||
this.socket.send(data);
|
||||
}
|
||||
|
||||
publ.close=function(data){
|
||||
this.socket.close();
|
||||
}
|
||||
})
|
||||
|
||||
var HTTPConnectionHandler = Class("HTTPConnectionHandler", BaseConnectionHandler, function(publ, supr){
|
||||
var urllib;
|
||||
publ.request_id = 1;
|
||||
publ.init=function(url, localService){
|
||||
urllib=importModule("urllib");
|
||||
this.url = url;
|
||||
supr(this).init( localService);
|
||||
}
|
||||
|
||||
publ.handleData = function(data){
|
||||
|
||||
try{
|
||||
var obj = JSON.parse(data);
|
||||
}catch(e){;
|
||||
throw " Not well formed\n\n" + e + "\n\nResponse from server:\n\n " + data;
|
||||
}
|
||||
if(obj.id != null){
|
||||
return obj;
|
||||
}else{
|
||||
throw "Unknown Data (No id property found)";
|
||||
}
|
||||
}
|
||||
|
||||
publ.sendRequest = function(name, args, callback){
|
||||
var sync = false;
|
||||
if(typeof callback != "function"){//see if it is sync
|
||||
args.push(callback);
|
||||
sync=true;
|
||||
}
|
||||
var data = new Request(this.request_id++, name, args);
|
||||
// cn: bug 12274 - defend against CSRF
|
||||
data = JSON.stringify(data); // creates security envelope wrapped JSON object
|
||||
|
||||
if(sync){
|
||||
var rsp = urllib.postURL(this.url, data, [["Content-Type", "text/plain"]]);
|
||||
rsp = this.handleData(rsp.responseText);
|
||||
if(rsp.error){
|
||||
throw rsp.error;
|
||||
}else{
|
||||
return rsp.result;
|
||||
}
|
||||
}else{//async connection uses the respHandler to handle the repsonse
|
||||
var self = this;
|
||||
var request_id = this.request_id;
|
||||
urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){
|
||||
try{
|
||||
rsp = self.handleData(rsp.responseText);
|
||||
}catch(e){
|
||||
//callback(null,e);
|
||||
callback(request_id,null,e);
|
||||
return;
|
||||
}
|
||||
callback(request_id,rsp.result, rsp.error);
|
||||
//callback(this.request_id,rsp.result, rsp.error);
|
||||
//callback(rsp.result, rsp.error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
publ.sendNotify = function(name, args){
|
||||
var data = new Notification(name, args);
|
||||
data = this.jsonParser.objToJson(data);
|
||||
urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){});
|
||||
}
|
||||
})
|
||||
|
||||
var PeerObject=Class("PeerObject", function(publ, supr){
|
||||
publ.init=function(name, conn){
|
||||
var fn=function(){
|
||||
var args=[];
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
var cb=args.pop();
|
||||
return conn.sendRequest(name, args, cb);
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
})
|
||||
|
||||
var PeerNotifyObject=Class("PeerNotifyObject", function(publ, supr){
|
||||
publ.init=function(name, conn){
|
||||
var fn=function(){
|
||||
var args=[];
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
conn.sendNotify(name, args);
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
})
|
||||
|
||||
var BasePeer = Class("BasePeer", function(publ, supr){
|
||||
publ.init=function(conn, methodNames){
|
||||
this._conn = conn;
|
||||
this.notify = new PeerObject("notify", conn);
|
||||
this._add(methodNames);
|
||||
}
|
||||
|
||||
var setupPeerMethod=function(root, methodName, conn, MethClass){
|
||||
var names = methodName.split(".");
|
||||
var obj = root;
|
||||
for(var n=0;n<names.length-1;n++){
|
||||
var name = names[n];
|
||||
if(obj[name]){
|
||||
obj = obj[name];
|
||||
}else{
|
||||
obj[name] = new Object();
|
||||
obj = obj[name];
|
||||
}
|
||||
}
|
||||
var name = names[names.length-1];
|
||||
if(obj[name]){
|
||||
}else{
|
||||
var mth = new MethClass(methodName, conn);
|
||||
obj[name] = mth;
|
||||
}
|
||||
}
|
||||
|
||||
publ._add = function(methodNames){
|
||||
for(var i=0;i<methodNames.length;i++){
|
||||
setupPeerMethod(this, methodNames[i], this._conn, PeerObject);
|
||||
setupPeerMethod(this.notify, methodNames[i], this._conn, PeerNotifyObject);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
mod.ServiceProxy = Class("ServiceProxy", BasePeer, function(publ, supr){
|
||||
publ.init = function(url, methodNames, localService){
|
||||
|
||||
var n = url.match(/^jsonrpc:\/\/(.*:\d*)$/);
|
||||
if(n!=null){//is it json-rpc over TCP protocoll
|
||||
var hostaddr = n[1];
|
||||
try{
|
||||
var socket = createConnection();
|
||||
}catch(e){
|
||||
throw "Can't create a socket connection."
|
||||
}
|
||||
socket.connect(hostaddr);
|
||||
supr(this).init( new SocketConnectionHandler(socket, localService), methodNames);
|
||||
}else{//or is it json-rpc over http
|
||||
this.httpConn = new HTTPConnectionHandler(url, localService);
|
||||
supr(this).init( this.httpConn, methodNames);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
485
jssource/src_files/include/jsolait/lib/lang.js
Normal file
485
jssource/src_files/include/jsolait/lib/lang.js
Normal file
@@ -0,0 +1,485 @@
|
||||
/*
|
||||
Copyright (c) 2004 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
Module providing language services like tokenizing JavaScript code
|
||||
or converting JavaScript objects to and from JSON (see json.org).
|
||||
To customize JSON serialization of Objects just overwrite the toJSON method in your class.
|
||||
*/
|
||||
Module("lang", "0.3.7", function(mod){
|
||||
|
||||
var ISODate = function(d){
|
||||
if(/^(\d{4})(\d{2})(\d{2})T(\d{2}):(\d{2}):(\d{2})/.test(d)){
|
||||
return new Date(Date.UTC(RegExp.$1, RegExp.$2-1, RegExp.$3, RegExp.$4, RegExp.$5, RegExp.$6));
|
||||
}else{ //todo error message
|
||||
throw new mod.Exception("Not an ISO date: " + d);
|
||||
}
|
||||
}
|
||||
|
||||
mod.JSONParser=Class("JSONParser", function(publ, supr){
|
||||
publ.init=function(){
|
||||
this.libs = {};
|
||||
var sys = {"ISODate" : ISODate};
|
||||
this.addLib(sys, "sys", ["ISODate"]);
|
||||
}
|
||||
|
||||
publ.addLib = function(obj, name, exports){
|
||||
if(exports == null){
|
||||
this.libs[name] = obj;
|
||||
}else{
|
||||
for(var i=0;i<exports.length;i++){
|
||||
this.libs[name + "." + exports[i]] = obj[exports[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var EmptyValue = {};
|
||||
var SeqSep = {};
|
||||
|
||||
var parseValue = function(tkns, libs){
|
||||
var tkn = tkns.nextNonWS();
|
||||
switch(tkn.type){
|
||||
case mod.tokens.STR:
|
||||
case mod.tokens.NUM:
|
||||
return eval(tkn.value);
|
||||
case mod.tokens.NAME:
|
||||
return parseName(tkn.value);
|
||||
case mod.tokens.OP:
|
||||
switch(tkn.value){
|
||||
case "[":
|
||||
return parseArray(tkns, libs);
|
||||
break;
|
||||
case "{":
|
||||
return parseObj(tkns, libs);
|
||||
break;
|
||||
case "}": case "]":
|
||||
return EmptyValue;
|
||||
case ",":
|
||||
return SeqSep;
|
||||
default:
|
||||
throw new mod.Exception("expected '[' or '{' but found: '" + tkn.value + "'");
|
||||
}
|
||||
}
|
||||
return EmptyValue;
|
||||
}
|
||||
|
||||
var parseArray = function(tkns, libs){
|
||||
var a = [];
|
||||
while(! tkns.finished()){
|
||||
var v = parseValue(tkns, libs);
|
||||
if(v == EmptyValue){
|
||||
return a;
|
||||
}else{
|
||||
a.push(v);
|
||||
v = parseValue(tkns, libs);
|
||||
if(v == EmptyValue){
|
||||
return a;
|
||||
}else if(v != SeqSep){
|
||||
throw new mod.Exception("',' expected but found: '" + v + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new mod.Exception("']' expected");
|
||||
}
|
||||
|
||||
var parseObj = function(tkns, libs){
|
||||
var obj = {};
|
||||
var nme =""
|
||||
while(! tkns.finished()){
|
||||
var tkn = tkns.nextNonWS();
|
||||
if(tkn.type == mod.tokens.STR){
|
||||
var nme = eval(tkn.value);
|
||||
tkn = tkns.nextNonWS();
|
||||
if(tkn.value == ":"){
|
||||
var v = parseValue(tkns, libs);
|
||||
if(v == SeqSep || v == EmptyValue){
|
||||
throw new mod.Exception("value expected");
|
||||
}else{
|
||||
obj[nme] = v;
|
||||
v = parseValue(tkns, libs);
|
||||
if(v == EmptyValue){
|
||||
return transformObj(obj, libs);
|
||||
}else if(v != SeqSep){
|
||||
throw new mod.Exception("',' expected");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
throw new mod.Exception("':' expected but found: '" + tkn.value + "'");
|
||||
}
|
||||
}else if(tkn.value == "}"){
|
||||
return transformObj(obj, libs);
|
||||
}else{
|
||||
throw new mod.Exception("String expected");
|
||||
}
|
||||
}
|
||||
throw new mod.Exception("'}' expected.")
|
||||
}
|
||||
|
||||
var transformObj = function(obj, libs){
|
||||
var o2;
|
||||
if(obj.jsonclass != null){
|
||||
var clsName = obj.jsonclass[0];
|
||||
var params = obj.jsonclass[1]
|
||||
if(libs[clsName]){
|
||||
o2 = libs[clsName].apply(this, params);
|
||||
for(var nme in obj){
|
||||
if(nme != "jsonclass"){
|
||||
if(typeof obj[nme] != "function"){
|
||||
o2[nme] = obj[nme];
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
throw new mod.Exception("jsonclass not found: " + clsName);
|
||||
}
|
||||
}else{
|
||||
o2 = obj;
|
||||
}
|
||||
return o2;
|
||||
}
|
||||
|
||||
var parseName = function(name){
|
||||
switch(name){
|
||||
case "null":
|
||||
return null;
|
||||
case "true":
|
||||
return true;
|
||||
case "false":
|
||||
return false;
|
||||
default:
|
||||
throw new mod.Exception("'null', 'true', 'false' expected but found: '" + name + "'");
|
||||
}
|
||||
}
|
||||
|
||||
publ.jsonToObj = function(data){
|
||||
var t = new mod.Tokenizer(data);
|
||||
return parseValue(t, this.libs);
|
||||
}
|
||||
|
||||
publ.objToJson=function(obj){
|
||||
if(obj == null){
|
||||
return "null";
|
||||
}else{
|
||||
return obj.toJSON();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
mod.parser = new mod.JSONParser();
|
||||
|
||||
/**
|
||||
Turns JSON code into JavaScript objects.
|
||||
@param src The source as a String.
|
||||
*/
|
||||
mod.jsonToObj=function(src){
|
||||
return mod.parser.jsonToObj(src);
|
||||
}
|
||||
|
||||
/**
|
||||
Turns an object into JSON.
|
||||
This is the same as calling obj.toJSON();
|
||||
@param obj The object to marshall.
|
||||
*/
|
||||
mod.objToJson=function(obj){
|
||||
return mod.parser.objToJson(obj);
|
||||
}
|
||||
|
||||
///Token constants for the tokenizer.
|
||||
mod.tokens = {};
|
||||
mod.tokens.WSP = 0;
|
||||
mod.tokens.OP =1;
|
||||
mod.tokens.STR = 2;
|
||||
mod.tokens.NAME = 3;
|
||||
mod.tokens.NUM = 4;
|
||||
mod.tokens.ERR = 5;
|
||||
mod.tokens.NL = 6;
|
||||
mod.tokens.COMMENT = 7;
|
||||
mod.tokens.DOCCOMMENT = 8;
|
||||
mod.tokens.REGEXP = 9;
|
||||
|
||||
|
||||
//todo:doc
|
||||
mod.Token=Class(function(publ, supr){
|
||||
|
||||
publ.init=function(type, value, pos, err){
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.pos = pos;
|
||||
this.err= err;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
/**
|
||||
Tokenizer Class which incrementally parses JavaScript code and returns the language tokens.
|
||||
*/
|
||||
mod.Tokenizer=Class("Tokenizer", function(publ, supr){
|
||||
publ.init=function(s){
|
||||
this._working = s;
|
||||
this._pos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns weather or not the code was parsed.
|
||||
@return True if the complete code was parsed, false otherwise.
|
||||
*/
|
||||
publ.finished=function(){
|
||||
return this._working.length == 0;
|
||||
}
|
||||
|
||||
publ.nextNonWS = function(nlIsWS){
|
||||
var tkn = this.next();
|
||||
while((tkn.type == mod.tokens.WSP) || (nlIsWS && (tkn.type == mod.tokens.NL))){
|
||||
tkn = this.next();
|
||||
}
|
||||
return tkn;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the next token.
|
||||
@return The next token.
|
||||
*/
|
||||
publ.next = function(){
|
||||
if(this._working ==""){
|
||||
throw new mod.Exception("Empty");
|
||||
}
|
||||
var s1 = this._working.charAt(0);
|
||||
var s2 = s1 + this._working.charAt(1);
|
||||
var s3 = s2 + this._working.charAt(2);
|
||||
var rslt=[];
|
||||
switch(s1){
|
||||
case '"': case "'":
|
||||
try{
|
||||
s1 = extractQString(this._working);
|
||||
rslt= new mod.Token(mod.tokens.STR, s1, this._pos);
|
||||
}catch(e){
|
||||
rslt= new mod.Token(mod.tokens.ERR, s1, this._pos, e);
|
||||
}
|
||||
break;
|
||||
case "\n": case "\r":
|
||||
rslt =new mod.Token(mod.tokens.NL, s1, this._pos);
|
||||
break;
|
||||
case "-": //check for negative numbers
|
||||
s1=this._working.match(/-\d+\.\d+|-\d+/)[0];
|
||||
if(/^-\d|-\d\.\d/.test(s1)){//number
|
||||
rslt = new mod.Token(mod.tokens.NUM, s1, this._pos);
|
||||
break;
|
||||
}
|
||||
|
||||
case "{": case "}": case "[": case "]": case "(": case ")":
|
||||
case ":": case ",": case ".": case ";":
|
||||
case "*": case "-": case "+":
|
||||
case "=": case "<": case ">": case "!":
|
||||
case "|": case "&":
|
||||
switch(s2){
|
||||
case "==": case "!=": case "<>": case "<=": case ">=":case "||": case "&&":
|
||||
rslt = new mod.Token(mod.tokens.OP, s2, this._pos);
|
||||
break;
|
||||
default:
|
||||
rslt = new mod.Token(mod.tokens.OP, s1, this._pos);
|
||||
}
|
||||
break;
|
||||
case "/":
|
||||
if(s2 == "//" || s3 =="///"){
|
||||
s1 = extractSLComment(this._working);
|
||||
rslt = new mod.Token(s1.charAt(2) != "/" ? mod.tokens.COMMENT:mod.tokens.DOCCOMMENT, s1, this._pos);
|
||||
}else if(s2 == "/*" || s3 =="/**"){
|
||||
try{
|
||||
s1 = extractMLComment(this._working);
|
||||
rslt = new mod.Token(s3 !="/**" ? mod.tokens.COMMENT: mod.tokens.DOCCOMMENT, s1, this._pos);
|
||||
}catch(e){
|
||||
rslt= new mod.Token(mod.tokens.ERR, s3 != "/**" ? s2 : s3, this._pos, e);
|
||||
}
|
||||
}else{
|
||||
try{
|
||||
s1 = extractRegExp(this._working);
|
||||
rslt = new mod.Token(mod.tokens.REGEXP, s1, this._pos);
|
||||
}catch(e){
|
||||
rslt = new mod.Token(mod.tokens.OP, s1, this._pos, e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case " ":
|
||||
var i = 0;
|
||||
var s="";
|
||||
while(this._working.charAt(i) == " "){
|
||||
s+=" ";
|
||||
i++;
|
||||
}
|
||||
rslt = new mod.Token(mod.tokens.WSP, s, this._pos);
|
||||
break;
|
||||
default:
|
||||
s1=this._working.match(/\d+\.\d+|\d+|\w+/)[0];
|
||||
if(/^\d|\d\.\d/.test(s1)){//number
|
||||
rslt = new mod.Token(mod.tokens.NUM, s1, this._pos);
|
||||
}else{//name
|
||||
rslt =new mod.Token(mod.tokens.NAME, s1, this._pos);
|
||||
}
|
||||
}
|
||||
|
||||
this._working=this._working.slice(rslt.value.length);
|
||||
this._pos += rslt.value.length;
|
||||
return rslt;
|
||||
}
|
||||
|
||||
var searchQoute = function(s, q){
|
||||
if(q=="'"){
|
||||
return s.search(/[\\']/);
|
||||
}else{
|
||||
return s.search(/[\\"]/);
|
||||
}
|
||||
}
|
||||
|
||||
var extractQString=function(s){
|
||||
if(s.charAt(0) == "'"){
|
||||
var q="'";
|
||||
}else{
|
||||
var q='"';
|
||||
}
|
||||
s=s.slice(1);
|
||||
var rs="";
|
||||
var p= searchQoute(s, q);
|
||||
while(p >= 0){
|
||||
if(p >=0){
|
||||
if(s.charAt(p) == q){
|
||||
rs += s.slice(0, p+1);
|
||||
s = s.slice(p+1);
|
||||
return q + rs;
|
||||
}else{
|
||||
rs+=s.slice(0, p+2);
|
||||
s = s.slice(p+2);
|
||||
}
|
||||
}
|
||||
p = searchQoute(s, q);
|
||||
}
|
||||
throw new mod.Exception("End of String expected.");
|
||||
}
|
||||
|
||||
var extractSLComment=function(s){
|
||||
var p = s.search(/\n/);
|
||||
if(p>=0){
|
||||
return s.slice(0,p+1);
|
||||
}else{
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
var extractMLComment=function(s){
|
||||
var p = s.search(/\*\//);
|
||||
if(p>=0){
|
||||
return s.slice(0,p+2);
|
||||
}else{
|
||||
throw new mod.Exception("End of comment expected.");
|
||||
}
|
||||
}
|
||||
|
||||
var extractRegExp=function(s){
|
||||
var p=0;
|
||||
for(var i=0;i<s.length;i++){
|
||||
if(s.charAt(i) == "/"){
|
||||
p=i;
|
||||
}
|
||||
if(s.charAt(i) == "\n"){
|
||||
i = s.length;
|
||||
}
|
||||
}
|
||||
return s.slice(0,p+1);
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
Converts an object to JSON.
|
||||
*/
|
||||
Object.prototype.toJSON = function(){
|
||||
var v=[];
|
||||
for(attr in this){
|
||||
if(typeof this[attr] != "function"){
|
||||
v.push('"' + attr + '": ' + mod.objToJson(this[attr]));
|
||||
}
|
||||
}
|
||||
return "{" + v.join(", ") + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
Converts a String to JSON.
|
||||
*/
|
||||
String.prototype.toJSON = function(){
|
||||
var s = '"' + this.replace(/(["\\])/g, '\\$1') + '"';
|
||||
s = s.replace(/(\n)/g,"\\n");
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
Converts a Number to JSON.
|
||||
*/
|
||||
Number.prototype.toJSON = function(){
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
Converts a Boolean to JSON.
|
||||
*/
|
||||
Boolean.prototype.toJSON = function(){
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
Converts a Date to JSON.
|
||||
Date representation is not defined in JSON.
|
||||
*/
|
||||
Date.prototype.toJSON= function(){
|
||||
var padd=function(s, p){
|
||||
s=p+s
|
||||
return s.substring(s.length - p.length)
|
||||
}
|
||||
var y = padd(this.getUTCFullYear(), "0000");
|
||||
var m = padd(this.getUTCMonth() + 1, "00");
|
||||
var d = padd(this.getUTCDate(), "00");
|
||||
var h = padd(this.getUTCHours(), "00");
|
||||
var min = padd(this.getUTCMinutes(), "00");
|
||||
var s = padd(this.getUTCSeconds(), "00");
|
||||
|
||||
var isodate = y + m + d + "T" + h + ":" + min + ":" + s
|
||||
|
||||
return '{"jsonclass":["sys.ISODate", ["' + isodate + '"]]}';
|
||||
}
|
||||
|
||||
/**
|
||||
Converts an Array to JSON.
|
||||
*/
|
||||
Array.prototype.toJSON = function(){
|
||||
var v = [];
|
||||
for(var i=0;i<this.length;i++){
|
||||
v.push(mod.objToJson(this[i])) ;
|
||||
}
|
||||
return "[" + v.join(", ") + "]";
|
||||
}
|
||||
|
||||
mod.test=function(){
|
||||
try{
|
||||
print(mod.jsonToObj("['sds', -12377,-1212.1212, 12, '-2312']").toJSON());
|
||||
}catch(e){
|
||||
print(e.toTraceString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
138
jssource/src_files/include/jsolait/lib/langlite.js
Normal file
138
jssource/src_files/include/jsolait/lib/langlite.js
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
Copyright (c) 2004 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
FOR SUGARCRM
|
||||
This is a stripped down version of lang.php, all it does is:
|
||||
convert JavaScript objects to JSON (see json.org).
|
||||
but *does not* add toJSON() function to every class that is derived from Object
|
||||
*/
|
||||
Module("langlite", "0.3.7", function(mod){
|
||||
|
||||
mod.JSONParser=Class("JSONParser", function(publ, supr){
|
||||
publ.init=function(){
|
||||
this.libs = {};
|
||||
}
|
||||
|
||||
publ.addLib = function(obj, name, exports){
|
||||
if(exports == null){
|
||||
this.libs[name] = obj;
|
||||
}else{
|
||||
for(var i=0;i<exports.length;i++){
|
||||
this.libs[name + "." + exports[i]] = obj[exports[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publ.objToJson=function(obj){
|
||||
if(obj == null){
|
||||
return "null";
|
||||
}else{
|
||||
return mod.objToJson(obj);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
mod.parser = new mod.JSONParser();
|
||||
|
||||
/**
|
||||
Turns JSON code into JavaScript objects.
|
||||
@param src The source as a String.
|
||||
*/
|
||||
mod.jsonToObj=function(src){
|
||||
return mod.parser.jsonToObj(src);
|
||||
}
|
||||
|
||||
var json_types = new Object();
|
||||
|
||||
json_types['object'] = function(obj){
|
||||
var v=[];
|
||||
for(attr in obj){
|
||||
if(typeof obj[attr] != "function"){
|
||||
v.push('"' + attr + '": ' + mod.objToJson(obj[attr]));
|
||||
}
|
||||
}
|
||||
return "{" + v.join(", ") + "}";
|
||||
}
|
||||
|
||||
json_types['string'] = function(obj){
|
||||
var s = '"' + obj.replace(/(["\\])/g, '\\$1') + '"';
|
||||
s = s.replace(/(\n)/g,"\\n");
|
||||
return s;
|
||||
}
|
||||
|
||||
json_types['number'] = function(obj){
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
json_types['boolean'] = function(obj){
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
json_types['date'] = function(obj){
|
||||
var padd=function(s, p){
|
||||
s=p+s
|
||||
return s.substring(s.length - p.length)
|
||||
}
|
||||
var y = padd(obj.getUTCFullYear(), "0000");
|
||||
var m = padd(obj.getUTCMonth() + 1, "00");
|
||||
var d = padd(obj.getUTCDate(), "00");
|
||||
var h = padd(obj.getUTCHours(), "00");
|
||||
var min = padd(obj.getUTCMinutes(), "00");
|
||||
var s = padd(obj.getUTCSeconds(), "00");
|
||||
|
||||
var isodate = y + m + d + "T" + h + ":" + min + ":" + s
|
||||
|
||||
return '{"jsonclass":["sys.ISODate", ["' + isodate + '"]]}';
|
||||
}
|
||||
|
||||
json_types['array'] = function(obj){
|
||||
var v = [];
|
||||
for(var i=0;i<obj.length;i++){
|
||||
v.push(mod.objToJson(obj[i])) ;
|
||||
}
|
||||
return "[" + v.join(", ") + "]";
|
||||
}
|
||||
|
||||
|
||||
mod.objToJson=function(obj){
|
||||
if ( typeof(obj) == 'undefined')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
if ( typeof(json_types[typeof(obj)]) == 'undefined')
|
||||
{
|
||||
alert('class not defined for toJSON():'+typeof(obj));
|
||||
}
|
||||
return json_types[typeof(obj)](obj);
|
||||
}
|
||||
|
||||
|
||||
mod.test=function(){
|
||||
try{
|
||||
print(mod.objToJson(['sds', -12377,-1212.1212, 12, '-2312']));
|
||||
}catch(e){
|
||||
print(e.toTraceString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
312
jssource/src_files/include/jsolait/lib/urllib.js
Normal file
312
jssource/src_files/include/jsolait/lib/urllib.js
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
Copyright (c) 2003 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
Provides methods for making HTTP requests.
|
||||
*/
|
||||
Module("urllib","1.1.3", function(mod){
|
||||
/**
|
||||
Thrown if no request object could be instanciated.
|
||||
*/
|
||||
mod.NoHTTPRequestObject=Class("NoHTTPRequestObject", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param trace The error causing this exception.
|
||||
*/
|
||||
publ.init=function(trace){
|
||||
supr(this).init( "Could not create an HTTP request object", trace);
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
Thrown if an HTTP request could not be opened.
|
||||
*/
|
||||
mod.RequestOpenFailed = Class("RequestOpenFailed", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param trace The error causing this exception.
|
||||
*/
|
||||
publ.init=function(trace){
|
||||
supr(this).init( "Opening of HTTP request failed.", trace);
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
Thrown is arequest could not be sent to the server.
|
||||
*/
|
||||
mod.SendFailed=Class("SendFailed", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param trace The error causing this exception.
|
||||
*/
|
||||
publ.init = function(trace){
|
||||
supr(this).init( "Sending of HTTP request failed.", trace);
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
Mimics the HTTPRequest object using Adobe's SVG Viewer's postURL and getURL.
|
||||
It can only process asyncronous connection and the only header that's supported is 'Content-Type'.
|
||||
*/
|
||||
var ASVRequest=Class("ASVRequest", function(publ){
|
||||
/**
|
||||
Initializes the ASVRequest.
|
||||
*/
|
||||
publ.init = function(){
|
||||
if((getURL==null) || (postURL==null)){
|
||||
throw "getURL and postURL are not available!";
|
||||
}else{
|
||||
this.readyState=0;
|
||||
this.responseText="";
|
||||
this.__contType ="";
|
||||
this.status=200;
|
||||
}
|
||||
}
|
||||
/**
|
||||
Mimics the open method without actually opening a connection.
|
||||
@param type "GET" or "POST".
|
||||
@param url The url to open.
|
||||
@param async=true True for async. connection. Otherwhise an exception is thrown.
|
||||
*/
|
||||
publ.open=function(type,url,async){
|
||||
if (async == false){
|
||||
throw "Can only open asynchronous connections!";
|
||||
}
|
||||
this.__type = type;
|
||||
this.__url = url;
|
||||
this.readyState=0;
|
||||
}
|
||||
/**
|
||||
Sets a header.
|
||||
@param name The header name. All but "Content-Type" are ignored.
|
||||
@param value The value of the header.
|
||||
*/
|
||||
publ.setRequestHeader=function(name, value){
|
||||
if (name=="Content-Type"){
|
||||
this.__contType =value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
Sends the request.
|
||||
@param data The data to send when doing a post.
|
||||
*/
|
||||
publ.send=function(data){
|
||||
var self=this;
|
||||
var cbh=new Object();
|
||||
cbh.operationComplete = function(rsp){
|
||||
self.readyState=4;
|
||||
self.responseText=rsp.content;
|
||||
if(this.ignoreComplete == false){
|
||||
if(self.onreadystatechange){
|
||||
self.onreadystatechange();
|
||||
}
|
||||
}
|
||||
}
|
||||
cbh.ignoreComplete = false;
|
||||
try{
|
||||
if(this.__type =="GET"){
|
||||
getURL(this.__url,cbh);
|
||||
}else if (this.__type == "POST"){
|
||||
postURL(this.__url, data, cbh, this.__contType);
|
||||
}
|
||||
}catch(e){
|
||||
cbh.ignoreComplete=true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
Creates an HTTP request object for retreiving files.
|
||||
@return HTTP request object.
|
||||
*/
|
||||
var getHTTP=function() {
|
||||
var obj;
|
||||
try{ //to get the mozilla httprequest object
|
||||
obj = new XMLHttpRequest();
|
||||
}catch(e){
|
||||
try{ //to get MS HTTP request object
|
||||
obj=new ActiveXObject("Msxml2.XMLHTTP.4.0");
|
||||
}catch(e){
|
||||
try{ //to get MS HTTP request object
|
||||
obj=new ActiveXObject("Msxml2.XMLHTTP")
|
||||
}catch(e){
|
||||
try{// to get the old MS HTTP request object
|
||||
obj = new ActiveXObject("microsoft.XMLHTTP");
|
||||
}catch(e){
|
||||
try{//to create the ASV request object.
|
||||
obj = new ASVRequest();
|
||||
}catch(e){
|
||||
throw new mod.NoHTTPRequestObject("Neither Mozilla, IE nor ASV found. Can't do HTTP request without them.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
Sends a request to a server.
|
||||
To explain the way the optional arguments work I will give examples:
|
||||
simple:
|
||||
sendRequest("get", "url")
|
||||
sendRequest("post", "url", "data")
|
||||
|
||||
with headers:
|
||||
sendRequest("get", "url", [["headername","value"]])
|
||||
sendRequest("post", "url", "data", [["headername","value"]])
|
||||
|
||||
with user information:
|
||||
sendRequest("get", "url", "user", "pass")
|
||||
sendRequest("post", "url", "user", "pass", "data")
|
||||
|
||||
with headers and user information:
|
||||
sendRequest("get", "url", "user", "pass", [["headername","value"]])
|
||||
sendRequest("post", "url", "user", "pass", "data", [["headername","value"]])
|
||||
|
||||
To make the request asynchronous just add a callback function as the last argument to the calls above.
|
||||
|
||||
@param type Type of connection (GET, POST, ...).
|
||||
@param url The URL to retrieve.
|
||||
@param user=null The username for auth.
|
||||
@param pass=null The password. (must be set if user is set!)
|
||||
@param data="" The data to send with the request.
|
||||
@param headers=[] Array of headers. Each element in the array should be another array containing [headername,value].
|
||||
@param callback=null Callback for asynchronous connections. The callback is called after completion and is passed the request object as 1st Parameter.
|
||||
@return HTTP request object.
|
||||
*/
|
||||
mod.sendRequest=function(type, url, user, pass, data, headers, callback){
|
||||
var async=false;
|
||||
//check if the last argument is a function and treat it as callback;
|
||||
if(arguments[arguments.length-1] instanceof Function){
|
||||
var async=true;
|
||||
callback = arguments[arguments.length-1];
|
||||
}
|
||||
//treat sencond last(if callback)/last(if no callback) argument as headers
|
||||
var headindex=arguments.length-((async || arguments[arguments.length-1] == null) ?2:1);
|
||||
//is it an array then it's headers
|
||||
if(arguments[headindex] instanceof Array){
|
||||
headers=arguments[headindex];
|
||||
}else{
|
||||
headers=[];
|
||||
}
|
||||
//are user AND password not specified then assume data as 3rd argument.
|
||||
if(typeof user == "string" && typeof pass == "string"){
|
||||
if(typeof data != "string"){
|
||||
data="";
|
||||
}
|
||||
}else if (typeof user == "string"){
|
||||
data = user;
|
||||
user=null;
|
||||
pass=null;
|
||||
}else{
|
||||
user=null;
|
||||
pass=null;
|
||||
}
|
||||
var xmlhttp= getHTTP();
|
||||
try{
|
||||
if(user!=null){
|
||||
xmlhttp.open(type, url, async, user, pass);
|
||||
}else{
|
||||
xmlhttp.open(type, url, async);
|
||||
}
|
||||
}catch(e){
|
||||
throw new mod.RequestOpenFailed(e);
|
||||
}
|
||||
//set headers
|
||||
for(var i=0;i< headers.length;i++){
|
||||
xmlhttp.setRequestHeader(headers[i][0], headers[i][1]);
|
||||
}
|
||||
|
||||
if(async){//set up a callback
|
||||
xmlhttp.onreadystatechange=function(){
|
||||
if (xmlhttp.readyState==4) {
|
||||
callback(xmlhttp);
|
||||
xmlhttp = null; //help IE with garbage collection
|
||||
}else if (xmlhttp.readyState==2){
|
||||
//status property should be available (MS IXMLHTTPRequest documentation)
|
||||
//in Mozilla it is not if the request failed(server not reachable)
|
||||
//in IE it is not available at all ?!
|
||||
try{//see if it is mozilla otherwise don't care.
|
||||
var isNetscape = netscape;
|
||||
try{//if status is not available the request failed.
|
||||
var s=xmlhttp.status;
|
||||
}catch(e){//call the callback because Mozilla will not get to readystate 4
|
||||
callback(xmlhttp);
|
||||
xmlhttp = null;
|
||||
}
|
||||
}catch(e){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
xmlhttp.send(data);
|
||||
}catch(e){
|
||||
if(async){
|
||||
callback(xmlhttp, e);
|
||||
xmlhttp=null;
|
||||
}else{
|
||||
throw new mod.SendFailed(e);
|
||||
}
|
||||
}
|
||||
return xmlhttp;
|
||||
}
|
||||
/**
|
||||
Shorthand for a GET request.
|
||||
It calls sendRequest with "GET" as first argument.
|
||||
See the sendRequest method for more information.
|
||||
@param url The URL to retrieve.
|
||||
@param user=null The username for auth.
|
||||
@param pass=null The password. (must be set if user is set!)
|
||||
@param headers=[] Array of headers. Each element in the array should be another array containing [headername,value].
|
||||
@param callback=null Callback for asynchronous connections. The callback is called after completion and is passed the request object as 1st Parameter.
|
||||
@return HTTP request object.
|
||||
*/
|
||||
mod.getURL=function(url, user, pass, headers, callback) {
|
||||
var a= new Array("GET");
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
a.push(arguments[i]);
|
||||
}
|
||||
return mod.sendRequest.apply(this,a)
|
||||
}
|
||||
/**
|
||||
Shorthand for a POST request.
|
||||
It calls sendRequest with "POST" as first argument.
|
||||
See the sendRequest method for more information.
|
||||
@param url The URL to retrieve.
|
||||
@param user=null The username for auth.
|
||||
@param pass=null The password. (must be set if user is set!)
|
||||
@param data="" The data to send with the request.
|
||||
@param headers=[] Array of headers. Each element in the array should be another array containing [headername,value].
|
||||
@param callback=null Callback for asynchronous connections. The callback is called after completion and is passed the request object as 1st Parameter.
|
||||
@return HTTP request object.
|
||||
*/
|
||||
mod.postURL=function(url, user, pass, data, headers, callback) {
|
||||
var a= new Array("POST");
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
a.push(arguments[i]);
|
||||
}
|
||||
return mod.sendRequest.apply(this,a)
|
||||
}
|
||||
})
|
||||
|
||||
247
jssource/src_files/include/jsolait/lib/xml.js
Normal file
247
jssource/src_files/include/jsolait/lib/xml.js
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
Copyright (c) 2003 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Provides parseXML and an importNode implementation.
|
||||
*/
|
||||
Module("xml","1.1.2", function(mod){
|
||||
/**
|
||||
Thrown if no parser could be instanciated.
|
||||
*/
|
||||
mod.NoXMLParser=Class("NoXMLParser", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param trace The error causing the Exception.
|
||||
*/
|
||||
publ.init=function(trace){
|
||||
supr(this).init("Could not create an XML parser.", trace);
|
||||
}
|
||||
})
|
||||
/**
|
||||
Thrown if a document could not be parsed.
|
||||
*/
|
||||
mod.ParsingFailed=Class("ParsingFailed", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param xml The xml source which could not be parsed.
|
||||
@param trace The error causing this Exception.
|
||||
*/
|
||||
publ.init=function(xml,trace){
|
||||
supr(this).init("Failed parsing XML document.",trace);
|
||||
this.xml = xml;
|
||||
}
|
||||
///The xml source which could not be parsed.
|
||||
publ.xml;
|
||||
})
|
||||
/**
|
||||
Parses an xml document.
|
||||
@param xml The xml text.
|
||||
@return A DOM of the xml document.
|
||||
*/
|
||||
mod.parseXML=function(xml){
|
||||
var obj=null;
|
||||
var isMoz=false;
|
||||
var isIE=false;
|
||||
var isASV=false;
|
||||
|
||||
try{//to get Adobe's SVG parseXML
|
||||
var p=window.parseXML;
|
||||
if(p==null){
|
||||
throw "No ASV paseXML";
|
||||
}
|
||||
isASV=true;
|
||||
}catch(e){
|
||||
try{//to get the mozilla parser
|
||||
obj = new DOMParser();
|
||||
isMoz=true;
|
||||
}catch(e){
|
||||
try{//to get the MS XML parser
|
||||
obj = new ActiveXObject("Msxml2.DomDocument.4.0");
|
||||
isIE=true;
|
||||
}catch(e){
|
||||
try{//to get the MS XML parser
|
||||
obj = new ActiveXObject("Msxml2.DomDocument");
|
||||
isIE=true;
|
||||
}catch(e){
|
||||
try{//to get the old MS XML parser
|
||||
obj = new ActiveXObject("microsoft.XMLDOM");
|
||||
isIE=true;
|
||||
}catch(e){
|
||||
throw new mod.NoXMLParser(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try{
|
||||
if(isMoz){
|
||||
obj = obj.parseFromString(xml, "text/xml");
|
||||
return obj;
|
||||
}else if(isIE){
|
||||
obj.loadXML(xml);
|
||||
return obj;
|
||||
}else if(isASV){
|
||||
return window.parseXML(xml, null);
|
||||
}
|
||||
}catch(e){
|
||||
throw new mod.ParsingFailed(xml,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
DOM2 implimentation of document.importNode().
|
||||
This will import into the current document. In SVG it will create SVG nodes in HTML it will create HTML nodes....
|
||||
This might become customizable in the future.
|
||||
@param importedNode The node to import.
|
||||
@param deep=true Import all childNodes recursively.
|
||||
@return The imported Node.
|
||||
*/
|
||||
mod.importNode=function(importedNode, deep){
|
||||
deep = (deep==null) ? true : deep;
|
||||
//constants from doom2
|
||||
var ELEMENT_NODE = 1;
|
||||
var ATTRIBUTE_NODE = 2;
|
||||
var TEXT_NODE = 3;
|
||||
var CDATA_SECTION_NODE = 4;
|
||||
var ENTITY_REFERENCE_NODE = 5;
|
||||
var ENTITY_NODE = 6;
|
||||
var PROCESSING_INSTRUCTION_NODE = 7;
|
||||
var COMMENT_NODE = 8;
|
||||
var DOCUMENT_NODE = 9;
|
||||
var DOCUMENT_TYPE_NODE = 10;
|
||||
var DOCUMENT_FRAGMENT_NODE = 11;
|
||||
var NOTATION_NODE = 12;
|
||||
var importChildren=function(srcNode, parent){
|
||||
if(deep){
|
||||
for(var i=0; i<srcNode.childNodes.length; i++){
|
||||
var n=mod.importNode(srcNode.childNodes.item(i), true);
|
||||
parent.appendChild(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
var node=null;
|
||||
switch(importedNode.nodeType){
|
||||
case ATTRIBUTE_NODE:
|
||||
node=document.createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
|
||||
node.value=importedNode.value;
|
||||
break;
|
||||
case DOCUMENT_FRAGMENT_NODE:
|
||||
node=document.createDocumentFragment();
|
||||
importChildren(importedNode,node);
|
||||
break;
|
||||
case ELEMENT_NODE:
|
||||
node=document.createElementNS(importedNode.namespaceURI, importedNode.tagName);
|
||||
//import all attributes
|
||||
for(var i=0; i<importedNode.attributes.length; i++){
|
||||
var attr=this.importNode(importedNode.attributes.item(i), deep);
|
||||
node.setAttributeNodeNS(attr);
|
||||
}
|
||||
importChildren(importedNode,node);
|
||||
break;
|
||||
case ENTITY_REFERENCE_NODE:
|
||||
node=importedNode;
|
||||
break;
|
||||
case PROCESSING_INSTRUCTION_NODE:
|
||||
node=document.createProcessingInstruction(importedNode.target, importedNode.data);
|
||||
break;
|
||||
case TEXT_NODE:
|
||||
case CDATA_SECTION_NODE:
|
||||
case COMMENT_NODE:
|
||||
node=document.createTextNode(importedNode.nodeValue);
|
||||
break;
|
||||
case DOCUMENT_NODE:
|
||||
//Document nodes cannot be imported.
|
||||
case DOCUMENT_TYPE_NODE:
|
||||
//DocumentType nodes cannot be imported.
|
||||
case NOTATION_NODE:
|
||||
//readonly in DOM2
|
||||
case ENTITY_NODE:
|
||||
//readonly in DOM2
|
||||
throw "not supported in DOM2";
|
||||
break;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
Turns an XML document into a String.
|
||||
@param node The node to print.
|
||||
@return A string containing the text for the XML.
|
||||
*/
|
||||
mod.node2XML = function(node){
|
||||
var ELEMENT_NODE = 1;
|
||||
var ATTRIBUTE_NODE = 2;
|
||||
var TEXT_NODE = 3;
|
||||
var CDATA_SECTION_NODE = 4;
|
||||
var ENTITY_REFERENCE_NODE = 5;
|
||||
var ENTITY_NODE = 6;
|
||||
var PROCESSING_INSTRUCTION_NODE = 7;
|
||||
var COMMENT_NODE = 8;
|
||||
var DOCUMENT_NODE = 9;
|
||||
var DOCUMENT_TYPE_NODE = 10;
|
||||
var DOCUMENT_FRAGMENT_NODE = 11;
|
||||
var NOTATION_NODE = 12;
|
||||
var s="";
|
||||
switch(node.nodeType){
|
||||
case ATTRIBUTE_NODE:
|
||||
s+=node.nodeName+'="' + node.value + '"';
|
||||
break;
|
||||
case DOCUMENT_NODE:
|
||||
s+=this.node2XML(node.documentElement);
|
||||
break;
|
||||
case ELEMENT_NODE:
|
||||
s+="<" + node.tagName;
|
||||
//attributes
|
||||
for(var i=0; i<node.attributes.length; i++){
|
||||
s+=" " + this.node2XML(node.attributes.item(i));
|
||||
}
|
||||
//children
|
||||
if(node.childNodes.length==0){
|
||||
s+="/>\n";
|
||||
}else{
|
||||
s+=">";
|
||||
for(var i=0; i<node.childNodes.length; i++){
|
||||
s+=this.node2XML(node.childNodes.item(i));
|
||||
}
|
||||
s+="</" + node.tagName+ ">\n";
|
||||
}
|
||||
break;
|
||||
case PROCESSING_INSTRUCTION_NODE:
|
||||
s+="<?" + node.target + " " + node.data + " ?>";
|
||||
break;
|
||||
case TEXT_NODE:
|
||||
s+=node.nodeValue;
|
||||
break;
|
||||
case CDATA_SECTION_NODE:
|
||||
s+="<" +"![CDATA[" + node.nodeValue + "]" + "]>";
|
||||
break;
|
||||
case COMMENT_NODE:
|
||||
s+="<!--" + node.nodeValue + "-->";
|
||||
break;
|
||||
case ENTITY_REFERENCE_NODE:
|
||||
case DOCUMENT_FRAGMENT_NODE:
|
||||
case DOCUMENT_TYPE_NODE:
|
||||
case NOTATION_NODE:
|
||||
case ENTITY_NODE:
|
||||
throw new mod.Exception("Nodetype(%s) not supported.".format(node.nodeType));
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
})
|
||||
831
jssource/src_files/include/jsolait/lib/xmlrpc.js
Normal file
831
jssource/src_files/include/jsolait/lib/xmlrpc.js
Normal file
@@ -0,0 +1,831 @@
|
||||
/*
|
||||
Copyright (c) 2003-2004 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Provides an XML-RPC imlementation.
|
||||
It is similar to python's xmlrpclib module.
|
||||
*/
|
||||
Module("xmlrpc","1.3.3", function(mod){
|
||||
var xmlext = importModule("xml");
|
||||
var urllib = importModule("urllib");
|
||||
/**
|
||||
Thrown if a server did not respond with response status 200 (OK).
|
||||
*/
|
||||
mod.InvalidServerResponse = Class("InvalidServerResponse", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param status The status returned by the server.
|
||||
*/
|
||||
publ.init= function(status){
|
||||
supr(this).init("The server did not respond with a status 200 (OK) but with: " + status);
|
||||
this.status = status;
|
||||
}
|
||||
///The status returned by the server.
|
||||
publ.status;
|
||||
})
|
||||
|
||||
/**
|
||||
Thrown if an XML-RPC response is not well formed.
|
||||
*/
|
||||
mod.MalformedXmlRpc = Class("MalformedXmlRpc", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param msg The error message of the user.
|
||||
@param xml The xml document's source.
|
||||
@param trace=null The error causing this Exception
|
||||
*/
|
||||
publ.init= function(msg, xml, trace){
|
||||
supr(this).init(msg,trace);
|
||||
this.xml = xml;
|
||||
}
|
||||
///The xml source which was mal formed.
|
||||
publ.xml;
|
||||
})
|
||||
/**
|
||||
Thrown if the RPC response is a Fault.
|
||||
*/
|
||||
mod.Fault = Class("Fault", mod.Exception, function(publ, supr){
|
||||
/**
|
||||
Initializes the Exception.
|
||||
@param faultCode The fault code returned by the rpc call.
|
||||
@param faultString The fault string returned by the rpc call.
|
||||
*/
|
||||
publ.init= function(faultCode, faultString){
|
||||
supr(this).init("XML-RPC Fault: " + faultCode + "\n\n" + faultString);
|
||||
this.faultCode = faultCode;
|
||||
this.faultString = faultString;
|
||||
}
|
||||
///The fault code returned from the rpc call.
|
||||
publ.faultCode;
|
||||
///The fault string returned from the rpc call.
|
||||
publ.faultString;
|
||||
})
|
||||
|
||||
/**
|
||||
Marshalls an object to XML-RPC.(Converts an object into XML-RPC conforming xml.)
|
||||
It just calls the toXmlRpc function of the objcect.
|
||||
So, to customize serialization of objects one just needs to specify/override the toXmlRpc method
|
||||
which should return an xml string conforming with XML-RPC spec.
|
||||
@param obj The object to marshall
|
||||
@return An xml representation of the object.
|
||||
*/
|
||||
mod.marshall = function(obj){
|
||||
if(obj.toXmlRpc){
|
||||
return obj.toXmlRpc();
|
||||
}else{
|
||||
var s = "<struct>";
|
||||
for(var attr in obj){
|
||||
if(typeof obj[attr] != "function"){
|
||||
s += "<member><name>" + attr + "</name><value>" + mod.marshall(obj[attr]) + "</value></member>";
|
||||
}
|
||||
}
|
||||
s += "</struct>";
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Unmarshalls an XML document to a JavaScript object. (Converts xml to JavaScript object.)
|
||||
It parses the xml source and creates a JavaScript object.
|
||||
@param xml The xml document source to unmarshall.
|
||||
@return The JavaScript object created from the XML.
|
||||
*/
|
||||
mod.unmarshall = function(xml){
|
||||
try {//try to parse xml ... this will throw an Exception if failed
|
||||
var doc = xmlext.parseXML(xml);
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("The server's response could not be parsed.", xml, e);
|
||||
}
|
||||
var rslt = mod.unmarshallDoc(doc, xml);
|
||||
doc=null;
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/**
|
||||
Unmarshalls an XML document to a JavaScript object like unmarshall but expects a DOM document as parameter.
|
||||
It parses the xml source and creates a JavaScript object.
|
||||
@param doc The xml document(DOM compatible) to unmarshall.
|
||||
@return The JavaScript object created from the XML.
|
||||
*/
|
||||
mod.unmarshallDoc = function(doc, xml){
|
||||
try{
|
||||
var node = doc.documentElement;
|
||||
if(node==null){//just in case parse xml didn't throw an Exception but returned nothing usefull.
|
||||
throw new mod.MalformedXmlRpc("No documentElement found.", xml);
|
||||
}
|
||||
switch(node.tagName){
|
||||
case "methodResponse":
|
||||
return parseMethodResponse(node);
|
||||
case "methodCall":
|
||||
return parseMethodCall(node);
|
||||
default://nothing usefull returned by parseXML.
|
||||
throw new mod.MalformedXmlRpc("'methodCall' or 'methodResponse' element expected.\nFound: '" + node.tagName + "'", xml);
|
||||
}
|
||||
}catch(e){
|
||||
if(e instanceof mod.Fault){//just rethrow the fault.
|
||||
throw e;
|
||||
}else {
|
||||
throw new mod.MalformedXmlRpc("Unmarshalling of XML failed.", xml, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Parses a methodeResponse element.
|
||||
@param node The methodResponse element.
|
||||
@return The return value of the XML-RPC.
|
||||
*/
|
||||
var parseMethodResponse=function(node){
|
||||
try{
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "fault": //a fault is thrown as an Exception
|
||||
throw parseFault(child);
|
||||
case "params":
|
||||
var params = parseParams(child);
|
||||
if(params.length == 1){//params should only have one param
|
||||
return params[0];
|
||||
}else{
|
||||
throw new mod.MalformedXmlRpc("'params' element inside 'methodResponse' must have exactly ONE 'param' child element.\nFound: " + params.length);
|
||||
}
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'fault' or 'params' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
//no child elements found
|
||||
throw new mod.MalformedXmlRpc("No child elements found.");
|
||||
}catch(e){
|
||||
if(e instanceof mod.Fault){
|
||||
throw e;
|
||||
}else{
|
||||
throw new mod.MalformedXmlRpc("'methodResponse' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a methodCall element.
|
||||
@param node The methodCall element.
|
||||
@return Array [methodName,params].
|
||||
*/
|
||||
var parseMethodCall = function(node){
|
||||
try{
|
||||
var methodName = null;
|
||||
var params = new Array();//default is no parameters
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "methodName":
|
||||
methodName = new String(child.firstChild.nodeValue);
|
||||
break;
|
||||
case "params":
|
||||
params = parseParams(child);
|
||||
break;
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'methodName' or 'params' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(methodName==null){
|
||||
throw new mod.MalformedXmlRpc("'methodName' element expected.");
|
||||
}else{
|
||||
return new Array(methodName, params);
|
||||
}
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'methodCall' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a params element.
|
||||
@param node The params element.
|
||||
@return Array of params values.
|
||||
*/
|
||||
var parseParams = function(node){
|
||||
try{
|
||||
var params=new Array();
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "param":
|
||||
params.push(parseParam(child));
|
||||
break;
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'param' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
//the specs say a 'params' element can contain any number of 'param' elements. That includes 0 ?!
|
||||
return params;
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'params' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a param element.
|
||||
@param node The param node.
|
||||
@return The value of the param.
|
||||
*/
|
||||
var parseParam = function(node){
|
||||
try{
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "value":
|
||||
return parseValue(child);
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'value' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
//no child elements found, that's an error
|
||||
throw new mod.MalformedXmlRpc("'value' element expected.But none found.");
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'param' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a value element.
|
||||
@param node The value element.
|
||||
@return The value.
|
||||
*/
|
||||
var parseValue = function(node){
|
||||
try{
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "string":
|
||||
var s=""
|
||||
//Mozilla has many textnodes with a size of 4096 chars each instead of one large one.
|
||||
//They all need to be concatenated.
|
||||
for(var j=0;j<child.childNodes.length;j++){
|
||||
s+=new String(child.childNodes.item(j).nodeValue);
|
||||
}
|
||||
return s;
|
||||
case "int":
|
||||
case "i4":
|
||||
case "double":
|
||||
return (child.firstChild) ? new Number(child.firstChild.nodeValue) : 0;
|
||||
case "boolean":
|
||||
return Boolean(isNaN(parseInt(child.firstChild.nodeValue)) ? (child.firstChild.nodeValue == "true") : parseInt(child.firstChild.nodeValue));
|
||||
case "base64":
|
||||
return parseBase64(child);
|
||||
case "dateTime.iso8601":
|
||||
return parseDateTime(child);
|
||||
case "array":
|
||||
return parseArray(child);
|
||||
case "struct":
|
||||
return parseStruct(child);
|
||||
case "nil": //for python None todo: ??? is this valid XML-RPC
|
||||
return null;
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'string','int','i4','double','boolean','base64','dateTime.iso8601','array' or 'struct' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(node.firstChild){
|
||||
var s=""
|
||||
//Mozilla has many textnodes with a size of 4096 chars each instead of one large one.
|
||||
//They all need to be concatenated.
|
||||
for(var j=0;j<node.childNodes.length;j++){
|
||||
s+=new String(node.childNodes.item(j).nodeValue);
|
||||
}
|
||||
return s;
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'value' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a base64 element.
|
||||
@param node The base64 element.
|
||||
@return A string with the decoded base64.
|
||||
*/
|
||||
var parseBase64=function(node){
|
||||
try{
|
||||
var s = node.firstChild.nodeValue;
|
||||
return s.decode("base64");
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'base64' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a dateTime.iso8601 element.
|
||||
@param node The dateTime.iso8601 element.
|
||||
@return A JavaScript date.
|
||||
*/
|
||||
var parseDateTime=function(node){
|
||||
try{
|
||||
if(/^(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})/.test(node.firstChild.nodeValue)){
|
||||
return new Date(Date.UTC(RegExp.$1, RegExp.$2-1, RegExp.$3, RegExp.$4, RegExp.$5, RegExp.$6));
|
||||
}else{ //todo error message
|
||||
throw new mod.MalformedXmlRpc("Could not convert the given date.");
|
||||
}
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'dateTime.iso8601' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses an array element.
|
||||
@param node The array element.
|
||||
@return An Array.
|
||||
*/
|
||||
var parseArray=function(node){
|
||||
try{
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "data":
|
||||
return parseData(child);
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'data' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new mod.MalformedXmlRpc("'data' element expected. But not found.");
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'array' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a data element.
|
||||
@param node The data element.
|
||||
@return The value of a data element.
|
||||
*/
|
||||
var parseData=function(node){
|
||||
try{
|
||||
var rslt = new Array();
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "value":
|
||||
rslt.push(parseValue(child));
|
||||
break;
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'value' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return rslt;
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'data' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a struct element.
|
||||
@param node The struct element.
|
||||
@return A JavaScript object. Struct memembers are properties of the object.
|
||||
*/
|
||||
var parseStruct=function(node){
|
||||
try{
|
||||
var struct = new Object();
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "member":
|
||||
var member = parseMember(child); //returns [name, value]
|
||||
if(member[0] != ""){
|
||||
struct[member[0]] = member[1];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'data' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return struct;
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'struct' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a member element.
|
||||
@param node The member element.
|
||||
@return Array containing [memberName, value].
|
||||
*/
|
||||
var parseMember=function(node){
|
||||
try{
|
||||
var name="";
|
||||
var value=null;
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "value":
|
||||
value = parseValue(child);
|
||||
break;
|
||||
case "name":
|
||||
if(child.hasChildNodes()){
|
||||
name = new String(child.firstChild.nodeValue);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'value' or 'name' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if(name == ""){
|
||||
throw new mod.MalformedXmlRpc("Name for member not found/convertable.");
|
||||
}else{
|
||||
return new Array(name, value);
|
||||
}*/
|
||||
return [name, value];
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'member' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Parses a fault element.
|
||||
@param node The fault element.
|
||||
@return A Fault Exception object.
|
||||
*/
|
||||
var parseFault = function(node){
|
||||
try{
|
||||
for(var i=0;i<node.childNodes.length;i++){
|
||||
var child = node.childNodes.item(i);
|
||||
if (child.nodeType == 1){
|
||||
switch (child.tagName){
|
||||
case "value":
|
||||
var flt = parseValue(child);
|
||||
return new mod.Fault(flt.faultCode, flt.faultString);
|
||||
default:
|
||||
throw new mod.MalformedXmlRpc("'value' element expected.\nFound: '" + child.tagName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new mod.MalformedXmlRpc("'value' element expected. But not found.");
|
||||
}catch(e){
|
||||
throw new mod.MalformedXmlRpc("'fault' element could not be parsed.",null,e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Class for creating XML-RPC methods.
|
||||
Calling the created method will result in an XML-RPC call to the service.
|
||||
The return value of this call will be the return value of the RPC call.
|
||||
RPC-Faults will be raised as Exceptions.
|
||||
|
||||
Asynchronous operation:
|
||||
If the last parameter passed to the method is an XMLRPCAsyncCallback object,
|
||||
then the remote method will be called asynchronously.
|
||||
The results and errors are passed to the callback.
|
||||
*/
|
||||
mod.XMLRPCMethod =Class("XMLRPCMethod", function(publ){
|
||||
|
||||
var postData = function(url, user, pass, data, callback){
|
||||
if(callback == null){
|
||||
var rslt = urllib.postURL(url, user, pass, data, [["Content-Type", "text/xml"]]);
|
||||
return rslt;
|
||||
}else{
|
||||
urllib.postURL(url, user, pass, data, [["Content-Type", "text/xml"]], callback);
|
||||
}
|
||||
}
|
||||
|
||||
var handleResponse=function(resp){
|
||||
var status=null;
|
||||
try{//see if the server responded with a response code 200 OK.
|
||||
status = resp.status;
|
||||
}catch(e){
|
||||
}
|
||||
if(status == 200){
|
||||
var respDoc=null;
|
||||
try{
|
||||
respDoc = resp.responseXML;
|
||||
}catch(e){
|
||||
}
|
||||
var respTxt = "";
|
||||
try{
|
||||
respTxt=resp.responseText;
|
||||
}catch(e){
|
||||
}
|
||||
if(respDoc == null){
|
||||
if(respTxt == null || respTxt == ""){
|
||||
throw new mod.MalformedXmlRpc("The server responded with an empty document.", "");
|
||||
}else{
|
||||
return mod.unmarshall(respTxt);
|
||||
}
|
||||
}else{ //use the respDoc directly so the xml does not have to be parsed.
|
||||
return mod.unmarshallDoc(respDoc, respTxt);
|
||||
}
|
||||
}else{
|
||||
throw new mod.InvalidServerResponse(status);
|
||||
}
|
||||
}
|
||||
|
||||
var getXML = function(methodName, args){
|
||||
var data='<?xml version="1.0"?><methodCall><methodName>' + methodName + '</methodName>';
|
||||
if (args.length>0){
|
||||
data += "<params>";
|
||||
for(var i=0;i<args.length;i++){
|
||||
data += '<param><value>' + mod.marshall(args[i]) + '</value></param>';
|
||||
}
|
||||
data += '</params>';
|
||||
}
|
||||
data += '</methodCall>';
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
Initializes the XML-RPC method.
|
||||
@param url The URL of the service providing the method.
|
||||
@param methodName The name of the method to invoke.
|
||||
@param user=null The user name to use for HTTP authentication.
|
||||
@param pass=null The password to use for HTTP authentication.
|
||||
*/
|
||||
publ.init = function(url, methodName, user, pass){
|
||||
|
||||
//this is pretty much a hack.
|
||||
//we create a function which mimics this class and return it instead of really instanciating an object.
|
||||
var fn=function(){
|
||||
//sync or async call
|
||||
if(typeof arguments[arguments.length-1] != "function"){
|
||||
var data=getXML(fn.methodName,arguments);
|
||||
var resp = postData(fn.url, fn.user, fn.password, data);
|
||||
|
||||
return handleResponse(resp);
|
||||
}else{
|
||||
var args=new Array();
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
var cb = args.pop();
|
||||
var data=getXML(fn.methodName, args);
|
||||
postData(fn.url, fn.user, fn.password, data, function(resp){
|
||||
var rslt = null;
|
||||
var exc =null;
|
||||
try{
|
||||
rslt = handleResponse(resp);
|
||||
}catch(e){
|
||||
exc = e;
|
||||
}
|
||||
try{//call the callback for the async call.
|
||||
cb(rslt,exc);
|
||||
}catch(e){
|
||||
}
|
||||
args = null;
|
||||
resp = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
//make sure the function has the same property as an object created from this class.
|
||||
fn.methodName = methodName;
|
||||
fn.url = url;
|
||||
fn.user = user;
|
||||
fn.password=pass;
|
||||
fn.toMulticall = this.toMulticall;
|
||||
fn.toString = this.toString;
|
||||
fn.setAuthentication=this.setAuthentication;
|
||||
fn.constructor = this.constructor;
|
||||
return fn;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the method representation for system.multicall.
|
||||
@param All params will be passed to the remote method.
|
||||
@return An object containing a member methodName and a member params(As required by system.multicall).
|
||||
*/
|
||||
publ.toMulticall = function(){
|
||||
var multiCallable = new Object();
|
||||
multiCallable.methodName = this.methodName;
|
||||
var params = [];
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
params[i] = arguments[i];
|
||||
}
|
||||
multiCallable.params = params;
|
||||
return multiCallable;
|
||||
}
|
||||
/**
|
||||
Sets username and password for HTTP Authentication.
|
||||
@param user The user name.
|
||||
@param pass The password.
|
||||
*/
|
||||
publ.setAuthentication = function(user, pass){
|
||||
this.user = user;
|
||||
this.password = pass;
|
||||
}
|
||||
///The name of the remote method.
|
||||
publ.methodName;
|
||||
///The url of the remote service containing the method.
|
||||
publ.url;
|
||||
///The user name used for HTTP authorization.
|
||||
publ.user;
|
||||
///The password used for HTTP authorization.
|
||||
publ.password;
|
||||
})
|
||||
|
||||
/**
|
||||
Creates proxy objects which resemble the remote service.
|
||||
Method calls of this proxy will result in calls to the service.
|
||||
*/
|
||||
mod.ServiceProxy=Class("ServiceProxy", function(publ){
|
||||
/**
|
||||
Initializes a new ServerProxy.
|
||||
The arguments are interpreted as shown in the examples:
|
||||
ServerProxy("url")
|
||||
ServerProxy("url", ["methodName1",...])
|
||||
ServerProxy("url", ["methodName1",...], "user", "pass")
|
||||
ServerProxy("url", "user", "pass")
|
||||
|
||||
@param url The url of the service.
|
||||
@param methodNames=[] Array of names of methods that can be called on the server.
|
||||
If no methods are given then introspection is used to get the methodnames from the server.
|
||||
@param user=null The user name to use for HTTP authentication.
|
||||
@param pass=null The password to use for HTTP authentication.
|
||||
*/
|
||||
publ.init = function(url, methodNames, user, pass){
|
||||
if(methodNames instanceof Array){
|
||||
if(methodNames.length > 0){
|
||||
var tryIntrospection=false;
|
||||
}else{
|
||||
var tryIntrospection=true;
|
||||
}
|
||||
}else{
|
||||
pass=user;
|
||||
user=methodNames;
|
||||
methodNames=[];
|
||||
var tryIntrospection=true;
|
||||
}
|
||||
this._url = url;
|
||||
this._user = user;
|
||||
this._password = pass;
|
||||
this._addMethodNames(methodNames);
|
||||
if(tryIntrospection){
|
||||
try{//it's ok if it fails.
|
||||
this._introspect();
|
||||
}catch(e){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Adds new XMLRPCMethods to the proxy server which can then be invoked.
|
||||
@param methodNames Array of names of methods that can be called on the server.
|
||||
*/
|
||||
publ._addMethodNames = function(methodNames){
|
||||
for(var i=0;i<methodNames.length;i++){
|
||||
var obj = this;
|
||||
//setup obj.childobj...method
|
||||
var names = methodNames[i].split(".");
|
||||
for(var n=0;n<names.length-1;n++){
|
||||
var name = names[n];
|
||||
if(obj[name]){
|
||||
obj = obj[name];
|
||||
}else{
|
||||
obj[name] = new Object();
|
||||
obj = obj[name];
|
||||
}
|
||||
}
|
||||
var name = names[names.length-1];
|
||||
if(obj[name]){
|
||||
}else{
|
||||
var mth = new mod.XMLRPCMethod(this._url, methodNames[i], this._user, this._password);
|
||||
obj[name] = mth;
|
||||
this._methods.push(mth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Sets username and password for HTTP Authentication for all methods of this service.
|
||||
@param user The user name.
|
||||
@param pass The password.
|
||||
*/
|
||||
publ._setAuthentication = function(user, pass){
|
||||
this._user = user;
|
||||
this._password = pass;
|
||||
for(var i=0;i<this._methods.length;i++){
|
||||
this._methods[i].setAuthentication(user, pass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Initiate XML-RPC introspection to retrieve methodnames from the server
|
||||
and add them to the server proxy.
|
||||
*/
|
||||
publ._introspect = function(){
|
||||
this._addMethodNames(["system.listMethods","system.methodHelp", "system.methodSignature"]);
|
||||
var m = this.system.listMethods();
|
||||
this._addMethodNames(m);
|
||||
}
|
||||
///The url of the service to resemble.
|
||||
publ._url;
|
||||
///The user used for HTTP authentication.
|
||||
publ._user;
|
||||
///The password used for HTTP authentication.
|
||||
publ._password;
|
||||
///All methods.
|
||||
publ._methods=new Array();
|
||||
})
|
||||
|
||||
///@deprecated Use ServiceProxy instead.
|
||||
mod.ServerProxy= mod.ServiceProxy;
|
||||
|
||||
/**
|
||||
XML-RPC representation of a string.
|
||||
All '&' and '<' are replaced with the '&' and '<'.
|
||||
@return A string containing the String's representation in XML.
|
||||
*/
|
||||
String.prototype.toXmlRpc = function(){
|
||||
return "<string>" + this.replace(/&/g, "&").replace(/</g, "<") + "</string>";
|
||||
}
|
||||
/**
|
||||
XML-RPC representation of a number.
|
||||
@return A string containing the Number's representation in XML.
|
||||
*/
|
||||
Number.prototype.toXmlRpc = function(){
|
||||
if(this == parseInt(this)){
|
||||
return "<int>" + this + "</int>";
|
||||
}else if(this == parseFloat(this)){
|
||||
return "<double>" + this + "</double>";
|
||||
}else{
|
||||
return false.toXmlRpc();
|
||||
}
|
||||
}
|
||||
/**
|
||||
XML-RPC representation of a boolean.
|
||||
@return A string containing the Boolean's representation in XML.
|
||||
*/
|
||||
Boolean.prototype.toXmlRpc = function(){
|
||||
if(this == true) {
|
||||
return "<boolean>1</boolean>";
|
||||
}else{
|
||||
return "<boolean>0</boolean>";
|
||||
}
|
||||
}
|
||||
/**
|
||||
XML-RPC representation of a date(iso 8601).
|
||||
@return A string containing the Date's representation in XML.
|
||||
*/
|
||||
Date.prototype.toXmlRpc = function(){
|
||||
var padd=function(s, p){
|
||||
s=p+s
|
||||
return s.substring(s.length - p.length)
|
||||
}
|
||||
var y = padd(this.getUTCFullYear(), "0000");
|
||||
var m = padd(this.getUTCMonth() + 1, "00");
|
||||
var d = padd(this.getUTCDate(), "00");
|
||||
var h = padd(this.getUTCHours(), "00");
|
||||
var min = padd(this.getUTCMinutes(), "00");
|
||||
var s = padd(this.getUTCSeconds(), "00");
|
||||
|
||||
var isodate = y + m + d + "T" + h + ":" + min + ":" + s
|
||||
|
||||
return "<dateTime.iso8601>" + isodate + "</dateTime.iso8601>";
|
||||
}
|
||||
/**
|
||||
XML-RPC representation of an array.
|
||||
Each entry in the array is a value in the XML-RPC.
|
||||
@return A string containing the Array's representation in XML.
|
||||
*/
|
||||
Array.prototype.toXmlRpc = function(){
|
||||
var retstr = "<array><data>";
|
||||
for(var i=0;i<this.length;i++){
|
||||
retstr += "<value>" + mod.marshall(this[i]) + "</value>";
|
||||
}
|
||||
return retstr + "</data></array>";
|
||||
}
|
||||
|
||||
|
||||
mod.test = function(){
|
||||
print("creating ServiceProxy object using introspection for method construction...\n");
|
||||
var s = new mod.ServiceProxy("http://localhost/testx.py");
|
||||
print("%s created\n".format(s));
|
||||
print("creating and marshalling test data:\n");
|
||||
var o = [1.234, 5, {a:"Hello & < ", b:new Date()}];
|
||||
print(mod.marshall(o));
|
||||
print("\ncalling echo() on remote service...\n");
|
||||
var r = s.echo(o);
|
||||
print("service returned data(marshalled again):\n")
|
||||
print(mod.marshall(r));
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
151
jssource/src_files/include/jsolait/missingmixin.js
Normal file
151
jssource/src_files/include/jsolait/missingmixin.js
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
Copyright (c) 2003 Jan-Klaas Kollhof
|
||||
|
||||
This file is part of the JavaScript o lait library(jsolait).
|
||||
|
||||
jsolait is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this software; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
if(Function.prototype.apply == null){
|
||||
Function.prototype.apply = function(thisObj, args){
|
||||
var a =[];
|
||||
for(var i=0;i<args.length;i++){
|
||||
a[i] = "args[" + i + "]";
|
||||
}
|
||||
thisObj.__apply__ = this;
|
||||
a="thisObj.__apply__(" + a.join(",") +")";
|
||||
var r = eval(a);
|
||||
delete thisObj.__apply__;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if(Function.prototype.call==null){
|
||||
Function.prototype.call=function(thisObj){
|
||||
var args=[]; //copy all arguments but the first
|
||||
for(var i=1;i<arguments.length;i++){
|
||||
args[i-1] = arguments[i];
|
||||
}
|
||||
return this.apply(thisObj, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------Array functions----------------------------------
|
||||
if(Array.prototype.splice == null){
|
||||
Array.prototype.splice = function(index, howMany){
|
||||
var a = this.slice(0, index);
|
||||
var e = this.slice(index + howMany, this.length);
|
||||
var r = this.slice(index, index+howMany);
|
||||
this.length=0;
|
||||
for(var i=0;i<a.length;i++){
|
||||
this[this.length] = a[i];
|
||||
}
|
||||
for(var i=2;i<arguments.length;i++){
|
||||
this[this.length] = arguments[i];
|
||||
}
|
||||
for(var i=0;i<e.length;i++){
|
||||
this[this.length] = e[i];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if(Array.prototype.pop == null){
|
||||
Array.prototype.pop = function(){
|
||||
var e=this[this.length-1];
|
||||
this.length -= 1;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
if(Array.prototype.push == null){
|
||||
Array.prototype.push = function(){
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
this[this.length] = arguments[i];
|
||||
}
|
||||
return this.length;
|
||||
}
|
||||
}
|
||||
|
||||
if(Array.prototype.shift == null){
|
||||
Array.prototype.shift = function(){
|
||||
var e = this[0];
|
||||
for(var i=1;i<this.length;i++){
|
||||
this[i-1] = this[i];
|
||||
}
|
||||
this.length -= 1;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
if(Array.prototype.unshift == null){
|
||||
Array.prototype.unshift = function(){
|
||||
var a=[]
|
||||
for(var i=0;i<arguments.length;i++){
|
||||
a[i] = arguments[i];
|
||||
}
|
||||
for(var i=0;i<this.length;i++){
|
||||
a[a.length] = this[i];
|
||||
}
|
||||
this.length=a.length;
|
||||
for(var i=0;i<a.length;i++){
|
||||
this[i] = a[i];
|
||||
}
|
||||
return this.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Number functions.
|
||||
|
||||
Contributed by Wolfgang Dumhs.
|
||||
*/
|
||||
if(Number.prototype.toFixed == null){
|
||||
Number.prototype.toFixed = function(d){
|
||||
var n = this;
|
||||
d = d || 0;
|
||||
var f = Math.pow(10, d);
|
||||
n = Math.round (f * n) / f;
|
||||
n = (n >= 0) ? n+Math.pow(10, -(d+1)) : n-Math.pow(10, -(d+1));
|
||||
n += '';
|
||||
return d == 0 ? n.substring(0, n.indexOf('.')) : n.substring(0, n.indexOf('.') + d + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(Number.prototype.toExponential == null){
|
||||
Number.prototype.toExponential = function(d){
|
||||
var n = this;
|
||||
var e = 0;
|
||||
if (n != 0){
|
||||
e = Math.floor(Math.log(Math.abs(n)) / Math.LN10);
|
||||
}
|
||||
n /= Math.pow(10, e);
|
||||
if (isFinite(d)){
|
||||
if (Math.abs(n) + 5*Math.pow(10, -(d+1)) >= 10.0){
|
||||
n /= 10;
|
||||
e += 1;
|
||||
}
|
||||
n = n.toFixed(d);
|
||||
}
|
||||
n += "e";
|
||||
if (e >= 0){
|
||||
n += "+";
|
||||
}
|
||||
n += e;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user