//该函数通过创建 *.DomDocument 是否成功来判断 IE支持的 ActiveXObject 类型
function getDomDocumentPrefix() {
if (getDomDocumentPrefix.prefix)
return getDomDocumentPrefix.prefix;
//这里是定义了四种 ActiveXObject 对象前缀
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
var o;
for (var i = 0; i < prefixes.length; i++) {
try {
// try to create the objects
o = new ActiveXObject(prefixes[i] + ".DomDocument");
return getDomDocumentPrefix.prefix = prefixes[i];
}
catch (ex) {};
}
throw new Error("Could not find an installed XML parser");
}
//同上面的函数 通过创建 *.XmlHttp 是否成功来判断 IE支持的 ActiveXObject 类型,如果不成功就抛出错误信息 可以通过IE的左下角错误信息查看
function getXmlHttpPrefix() {
if (getXmlHttpPrefix.prefix)
return getXmlHttpPrefix.prefix;
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
var o;
for (var i = 0; i < prefixes.length; i++) {
try {
o = new ActiveXObject(prefixes[i] + ".XmlHttp");
return getXmlHttpPrefix.prefix = prefixes[i];
}
catch (ex) {};
}
throw new Error("Could not find an installed XMLHttp object");
}
function XmlHttp() {}
//该函数 创建了 XmlHttp 对象
XmlHttp.create = function () {
try {
if (window.XMLHttpRequest) {
var req = new XMLHttpRequest();
if (req.readyState == null) {
req.readyState = 1;
//添加 load事件的处理函数,
req.addEventListener("load", function () {
req.readyState = 4;
if (typeof req.onreadystatechange == "function")
req.onreadystatechange();
}, false);
}
return req;
}
if (window.ActiveXObject) {
return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
}
}
catch (ex) {}
//如果你的浏览器不支持 XmlHttp 对象 会在浏览器的左下角报一个错误
throw new Error("Your browser does not support XmlHttp objects");
};
//函数也可以一个对象 XmlDocument 对象主要作用是将字符串解释为XML的Document的对象,我们在用buffalo.js时候
//其实都是通过了buffalo.jar包转化为了XML的字符串形式,并且返回的已经被转化为对象了,这个可以稍微了解下
//我一般很少用到这个地方
function XmlDocument() {}
XmlDocument.create = function () {
try {
if (document.implementation && document.implementation.createDocument) {
var doc = document.implementation.createDocument("", "", null);
if (doc.readyState == null) {
doc.readyState = 1;
doc.addEventListener("load", function () {
doc.readyState = 4;
if (typeof doc.onreadystatechange == "function")
doc.onreadystatechange();
}, false);
}
return doc;
}
if (window.ActiveXObject)
return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
}
catch (ex) {}
throw new Error("Your browser does not support XmlDocument objects");
};
if (window.DOMParser &&
window.XMLSerializer &&
window.Node && Node.prototype && Node.prototype.__defineGetter__) {
Document.prototype.loadXML = function (s) {
var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
while (this.hasChildNodes())
this.removeChild(this.lastChild);
for (var i = 0; i < doc2.childNodes.length; i++) {
this.appendChild(this.importNode(doc2.childNodes[i], true));
}
};
Document.prototype.__defineGetter__("xml", function () {
return (new XMLSerializer()).serializeToString(this);
});
}
//使用 prototype.js的Class创建类 该对象的作用是将要传递到后台程序的参数组装成 XML字符串形式(包括参数的类型和值)
Buffalo.Call = Class.create();
//初始化相关方法
Buffalo.Call.prototype = {
initialize: function(methodname){
this.method = methodname;
this.params = [];
this._objects = [];
},
//添加需要传递到后台的参数信息
addParameter: function(data){
if (typeof(data) == 'undefined') return;
this.params[this.params.length] = data;
},
// 创建 XML字符串
xml: function(){
this._objects = [];
var xmlstr = "
xmlstr += "
for (var i = 0; i < this.params.length; i++) {
var data = this.params[i];
//该行是组装 XML字符串的重要的一条语句 描述:
//dataTypeOf 方法获取参数的类型,以便后续操作该对象,判断对象的类型不是100%准备 只能大概猜测参数所属的相关类型(Number(int,double),Object(Date,Array,map))
xmlstr += this.getParamXML(this.dataTypeOf(data),data) + "/n";
}
xmlstr += "
return xmlstr;
},
/* Guess the type of an javascript object */
// 猜测 javascript object对象的 类型
dataTypeOf: function (o){
if (o == null) {
return "null";
}
var type = typeof(o);
type = type.toLowerCase();
switch(type){
case "number":
type = this._getNumberType(o);
break;
case "object":
var con = o.constructor;
if (con == Date) type = "date";
else if (con == Array) type = "list";
else type = "map";
break;
}
return type;
},
// 使用 typeof()方法检测 o 所属的类型,如果为"number"类型 那么进一步判断该类型为 "int" 或 "double" 类型
_getNumberType: function(o) {
if (Math.round(o) == o)
return "int";
else
return "double";
},
//构造基本元素的XML字符串
doValueXML: function(type,data){
var xml, str = data;
//如果为字符串 对 "&" "<" ">" 进行替换
if (typeof(data) == "string") {
str = str.replace(/&/g,"&");
str = str.replace(/ str = str.replace(/>/g,">");
xml = "<" + type + ">" + str + "" + type + ">";
} else {
xml = "<" + type + ">" + data + "" + type + ">";
}
return xml;
},
// 设置布尔值 1 代表 TRUE 0 代表 FALSE
doBooleanXML:function(data){
var value = (data==true)?1:0;
var xml = "
return xml;
},
// 将日期的数据类型转化为 ISO8609 日期格式 就是将年份少于2000的加上1900
doDateXML: function(data){
var xml = "
xml += dateToISO8609(data);
xml += "
return xml;
},
doArrayXML : function(data){
//_checkRef方法判断 data 是否引用了同一个对象,如果引用了同一个对象那么就直接引用已经解析了的Array();
var ref = this._checkRef(data);
if (ref != -1) return "" + ref + "";
this._objects[this._objects.length] = data;
var xml = "/n";
/n";
// Buffalo.BOCLASS ="_BUFFALO_OBJECT_CLASS_"
var boClass = data[Buffalo.BOCLASS];
//获取数组的元素的类型 arrayType方法
var boType = boClass ? boClass : this.arrayType(data);
xml += "
xml += "
for (var i = 0; i < data.length; i++){
xml += this.getParamXML(this.dataTypeOf(data[i]),data[i]) + "/n";
}
xml += "
return xml;
},
//获取Array对象的元素的类型,这里包含三种类型的判断 object number 和string,如果数组的元素是混合类型,那么整个数组的类型设置为 空
arrayType: function(arr) {
if (arr.length == 0) return "";
var type = "";
var obj = arr;
//this.isArray(obj) 判断该对象是否为Array (judging the object obj is Array() )
while(this.isArray(obj)) {
var obj0 = obj[0];
var canBeArray = true;
for(var i = 0; i < obj.length; i++) {
var obji = obj[i];
if (typeof(obji) != typeof(obj0)) {
canBeArray = false;
break;
} else {
if (typeof(obji) == 'object') {
if (obj0[Buffalo.BOCLASS] != obji[Buffalo.BOCLASS]) {
canBeArray = false;
break;
}
}
if (typeof(obji) == 'number') {
if (this._getNumberType(obji) != this._getNumberType(obj0)) {
canBeArray = false;
break;
}
}
}
}
if (canBeArray) {
type+="[";
obj = obj[0];
} else {
break;
}
}
if (type.indexOf("[") == -1) return "";
var componentType = obj[Buffalo.BOCLASS] || typeof(obj);
if (componentType == 'object') return "";
if (componentType == 'number') componentType = this._getNumberType(obj);
return type+componentType;
},
//判断对象是是否为 Array对象
isArray: function(obj) {
return typeof(obj) == 'object' && obj.constructor == Array;
},
// 判断传递的参数是否引用了同一个对象
_checkRef: function(obj) {
var ref = -1;
for (var i = 0; i < this._objects.length; i++) {
//判断是否引用了同一个对象
if (obj === this._objects[i]) {
ref = i; break;
}
}
return ref;
},
doStructXML : function(data){
var ref = this._checkRef(data);
if (ref != -1) return "" + ref + "";
this._objects[this._objects.length] = data;
var boType = data[Buffalo.BOCLASS] || "java.util.HashMap";
var xml = "
for (var i in data){
if (data[i] != boType) {
if (typeof(data[i]) == "function") continue; /* the function shouldn't transfered. */
xml += this.getParamXML(this.dataTypeOf(i),i)+"/n";
xml += this.getParamXML(this.dataTypeOf(data[i]),data[i]) + "/n";
}
}
xml += "/n";
return xml;
},
doNullXML : function() {
return "
},
//根据不同类调用不同的函数进行解释
getParamXML: function(type,data){
var xml;
switch (type){
case "date": xml = this.doDateXML(data); break;
case "list": xml = this.doArrayXML(data); break;
case "map": xml = this.doStructXML(data); break;
case "boolean": xml = this.doBooleanXML(data); break;
case "null": xml = this.doNullXML(); break;
default: xml = this.doValueXML(type,data); break;
}
return xml;
}
}
// 将日期的数据类型转化为 ISO8609 日期格式 就是将年份少于2000的加上1900
function dateToISO8609(date){
var year = date.getYear();
/* Fix for Y2K */
if (year < 2000) {
year += 1900;
}
var month = leadingZero(new String(date.getMonth()+1));
var day = leadingZero(new String(date.getDate()));
var time = leadingZero(new String(date.getHours())) + leadingZero(new String(date.getMinutes())) + leadingZero(new String(date.getSeconds()));
var converted = year+month+day+"T"+time+"Z";
return converted;
}
//小于两位的在前面补零
function leadingZero(n){
if (n.length==1) n = "0" + n;
return n;
}