o4glwsdl2js.js

Summary

This is a library used by o4glwsdl2js.html a wizard to generate javascript code from wsdl descriptors.

This library needs xmlhttp.js file to be included to work properly.

This file is part of the Open 4GL webservices project.



Version: 0.1

Author: Lic. Edgar Medrano Pérez edgarmedrano@gmail.com


Class Summary
CodeGen  
WSDL  

Method Summary
static String cleanName(<String> name)
           Removes the namespace.
static Array xpath(<Object> node,<String> path,<int> depth)
           Finds the nodes that match the specified path.

/*------------------------------------------------------------------------
  File:        o4glwsdl2js.js
  Description: This is a library used by o4glwsdl2js.html
  Author:      Lic. Edgar Medrano Pérez 
               edgarmedrano@gmail.com
  Created:     2006.03.04
  Company:     Open 4GL webservices project
               http://o4glws.sourceforge.net
  Notes:       
------------------------------------------------------------------------*/

/** 
 * @fileoverview This is a library used by 
 * {@link http://o4glws.sourceforge.net/o4glwsdl2js o4glwsdl2js.html} 
 * a wizard to generate javascript code from wsdl descriptors.
 * <p>This library needs xmlhttp.js file to be included to work properly.</p>
 * <p>This file is part of the 
 * {@link http://o4glws.sourceforge.net/ Open 4GL webservices project}.</p>
 * @author Lic. Edgar Medrano Pérez edgarmedrano@gmail.com
 * @version 0.1 
 */

/**
 * Removes the namespace.
 * @param {String} name The attribute/tag name.
 * @return {String} the clean name.
 */
function cleanName(name) {
	return (name.indexOf(":") >= 0) ? name.substr(name.indexOf(":") + 1) : name;
}	

/**
 * Finds the nodes that match the specified path.
 * @param {Object} node XML parent node.
 * @param {String} path Path to child node. Example: "service/port/address"
 * @param {int} depth This parameter is for internal use only; don´t include
                      it in your call.
 * @return {Array} An array containing the found nodes.
 */
function xpath(node,path,depth) {
	var arrpath;
	var result = new Array();
	
	if(node && path) {
		arrpath = path.split("/");
		if(!depth) { 
			depth = 0;
		}
		
		for(var i = 0; i < node.childNodes.length; i ++) {
			if(cleanName(node.childNodes[i].nodeName) == arrpath[depth]) {
			
				if(depth < arrpath.length - 1) {
					return xpath(node.childNodes[i],path,depth + 1);  
				} else {
					result[result.length] = node.childNodes[i];
				}
			}
		}
	}
	
	return result;
}

/**
 * Builds the code from the loaded WSDL.
 * @param {Object} xml XML document containing the WSDL.
 * @constructor
 */
function CodeGen(xml) {
	this.wsdl = new WSDL(xml)
	this.Adapter = CodeGen_Adapter;
	this.Sample = CodeGen_Sample;
	this.Html = CodeGen_Html;
}

/**
 * Represents the information contained in a WSDL. It's
 * used by {@link CodeGen}.
 * @param {Object} xml XML document containing the WSDL.
 * @constructor
 */
function WSDL(xml) {
	var defs; 
	var i;
	var j;

	this.complexTypes = new Array();
	this.messages = new Array();
	this.operations = new Array();
	
	defs = xpath(xml,"definitions");
	if(defs[0]) {
		defs = defs[0];
		var node;
		var child;
		var complexType;
		var element;
		var message;
		var part;
		var operation;

		node = xpath(defs,"service");
		if(node[0]) {
			this.name = node[0].getAttribute("name");
		}
		
		node = xpath(defs,"service/port/address");
		if(node[0]) {
			this.address = node[0].getAttribute("location");
		}
		
		node = xpath(defs,"types/schema/complexType");
		if(node[0]) {
			for(i = 0; i < node.length; i++) {
				child = xpath(node[i],"all/element");
				complexType = new Object();
				complexType.name = node[i].getAttribute("name");
				complexType.type = "complexType";
				if(child[0]) {
					complexType.element = new Array();
					for(j = 0; j < child.length; j++ ) {
					    element = new Object();
						element.name = child[j].getAttribute("name");
						element.type = cleanName(child[j].getAttribute("type"));
						complexType.element[complexType.element.length] = element;
					}
				} else {
					child = xpath(node[i],"complexContent/restriction/attribute");
					if(child[0]) {
						complexType.arrayType = cleanName(child[0].getAttribute("wsdl:arrayType")); 
						complexType.type = "Array";
						if(complexType.arrayType.indexOf("[")) {
							complexType.arrayType = complexType.arrayType.substr(0,complexType.arrayType.indexOf("["));
						}
					}
				}
				this.complexTypes[this.complexTypes.length] = complexType;
				this.complexTypes[complexType.name] = complexType;
			}
		}
		
		node = xpath(defs,"message");
		if(node[0]) {
			for(i = 0; i < node.length; i++) {
				message = new Array();
				message.name = cleanName(node[i].getAttribute("name"));
				for(j = 0; j < node[i].childNodes.length; j++) {
					part = new Object();
					part.name = node[i].childNodes[j].getAttribute("name");
					part.type = cleanName(node[i].childNodes[j].getAttribute("type"));
					/*
					while(this.complexTypes[part.type]) {
						part.type = this.complexTypes[part.type].type;
					}
					alert(part.name + "," + part.type);
					*/
					message[message.length] = part;
				}
				this.messages[this.messages.length] = message;
				this.messages[message.name] = message;
			}
		}
		
		node = xpath(defs,"portType/operation");
		for(i = 0; i < node.length; i++) {
			operation = new Object();
			operation.name = node[i].getAttribute("name");
			child = xpath(node[i],"input");
			if(child[0]) {
				operation.input = cleanName(child[0].getAttribute("message"));
				operation.input = this.messages[operation.input];
			}
			child = xpath(node[i],"output");
			if(child[0]) {
				operation.output = cleanName(child[0].getAttribute("message"));
				operation.output = this.messages[operation.output];
			}
			this.operations[this.operations.length] = operation;
		} 
	} /*if(defs[0])*/
}

/**
 * Generates the javascript code to be included in the .js file.
 * @return {String} The javascript code.
 */
function CodeGen_Adapter() {
	var i;
	var j;
	var result = "";
	var param;
	var paramType;
	
	result += 
		"/" + "*------------------------------------------------------------------------\n"
		+ "  " + this.wsdl.name + ".js\n"
		+ "  Description: This file was generated using o4glwsdl2js.html from \n"
		+ "               the Open 4GL webservices project (http://o4glws.sourceforge.net)\n"
 		+ "               a wizard to generate javascript code from wsdl descriptors.\n"
		+ "  Author:      Your name goes here\n"
		+ "  Created:     " + new Date() + "\n"
		+ "  Company:     Your company name goes here\n"
		+ "  Notes:       \n"
		+ "------------------------------------------------------------------------*/\n"
 		+ "\n"
		+ "*" + "/\n"
		+ "/" + "** \n"
 		+ "* @fileoverview This file was generated using \n"
 		+ "* {@link http://o4glws.sourceforge.net/o4glwsdl2js o4glwsdl2js.html} \n"
 		+ "* a wizard to generate javascript code from wsdl descriptors.\n"
 		+ "* <p>This library needs webservice.js file to work properly.</p>\n"
 		+ "* @author Your name goes here\n"
 		+ "*/\n"
 		+ "\n"
 		+ "/" + "**\n"
  		+ "* " + this.wsdl.name + " webservice adapter object.\n"
  		+ "* @extends __WebService\n"
  		+ "* @param {String} url Optional url pointing to the webservice deployment location.\n"
  		+ "*                     If you don´t specify it " + this.wsdl.address +  " will be used.\n"
  		+ "* @constructor\n"
  		+ "*/\n"
		+ "function " + this.wsdl.name + "(url) {\n"
		+ "  this.__WebService = __WebService;\n"
		+ "  this.__WebService(\"" + this.wsdl.name + "\",url?url:\"" + this.wsdl.address + "\");\n";
	
	for(i = 0; i < this.wsdl.operations.length; i++) {
		result += 
			"  this." + this.wsdl.operations[i].name + " = " + this.wsdl.name + "_" + this.wsdl.operations[i].name + ";\n"
			+ "  this." + this.wsdl.operations[i].name + "_callback = " + this.wsdl.name + "_" + this.wsdl.operations[i].name + "_callback;\n"
			+ "  this." + this.wsdl.operations[i].name + "_handle = function () {};\n"; 
	} 
	result += "}\n\n";
	
	for(i = 0; i < this.wsdl.operations.length; i++) {
		result += 
	 		  "/" + "**\n"
	  		+ "* Calls " + this.wsdl.operations[i].name " operation in the" 
			+ this.wsdl.name + " webservice.\n";
			
		for(j = 0; j < this.wsdl.operations[i].input.length; j++) {
			result += "* @param " + this.wsdl.operations[i].input[j].name + "\n" ;
		}
		
		result += 
	  		+ "*/\n"
			+ "function " + this.wsdl.name + "_" + this.wsdl.operations[i].name + "("; 
			
		for(j = 0; j < this.wsdl.operations[i].input.length; j++) {
			result += (j > 0 ? ",":"") + this.wsdl.operations[i].input[j].name;
		}
		result += 
			") {\n"
			+ "  var request = new __Request(this.urn,\"" + this.wsdl.operations[i].input.name + "\");\n"; 
		for(j = 0; j < this.wsdl.operations[i].input.length; j++) {
			result += "  request.addParam(\"" 
				+ this.wsdl.operations[i].input[j].name 
				+ "\"," 
				+ this.wsdl.operations[i].input[j].name 
				+ ");\n";
		}
		result += 
			"  this.invoke(request,\"" + this.wsdl.operations[i].output.name + "\",\"" + this.wsdl.operations[i].name + "_callback\");\n" 
			+ "}\n\n"
	 		+ "/" + "**\n"
	  		+ "* XMLHttp callback handler for " + this.wsdl.operations[i].name + " operation in the "
			+ this.wsdl.name + " webservice. This is the function assigned to XMLHttp.onreadystatechange\n"
			+ " in {link __WebService#invoke}. If there is a fault while calling the webservice, \n"
			+ " an alert message will be show reporting the fault. \n"
	  		+ "* @param {__Request} request Webservice request.\n"
	  		+ "* @param {__Response} response Webservice response.\n" __WebService_invoke
	  		+ "* @see __WebService#invoke.\n"
	  		+ "*/\n"
			+ "function " + this.wsdl.name + "_" + this.wsdl.operations[i].name + "_callback(request,response) {\n" 
			+ "  if(response.fault) {\n" 
			+ "     alert(\"Fault: \" + response.fault.faultstring" 
			+            " + \"\\nCode: \" + response.fault.faultcode" 
			+            " + \"\\nActor: \" + response.fault.faultactor);\n" 
			+ "  } else {\n" 
			+ "    this." + this.wsdl.operations[i].name + "_handle("; 
		for(j = 0; j < this.wsdl.operations[i].input.length; j++) {
			result += (j > 0 ? ",":"") 
				+ "request.getParam(\"" 
				+ this.wsdl.operations[i].input[j].name 
				+ "\",\"" 
				+ this.wsdl.operations[i].input[j].type 
				+ "\")";
		}
		for(j = 0; j < this.wsdl.operations[i].output.length; j++) {
			param = this.wsdl.operations[i].output[j].name;
			paramType = this.wsdl.operations[i].output[j].type;
		    if(this.wsdl.complexTypes[paramType]) {
				param = this.wsdl.complexTypes[paramType].name;
				paramType = this.wsdl.complexTypes[paramType].type;
			}
			result += (this.wsdl.operations[i].input.length > 0 || j > 0 ? ",":"") 
				+ "response.getParam(\"" + param + "\",\"" + paramType + "\")";
		}
		result += 
			");\n"
			+ "  }\n"
			+ "}\n\n"; 
	} 
	 
	result += 
		"/" + "* \n"
		+ this.Sample()
		+ "*" + "/ \n\n"; 
	
	return result;
}

/**
 * Generates the sample call handlers code. 
 * @return {String} The javascript code.
 */
function CodeGen_Sample() {
	var i;
	var j;
	var result = "";
	
	result += 
		"//" + "test code\n"
		+ "var test = new " + this.wsdl.name + "(); \n"; 
	for(i = 0; i < this.wsdl.operations.length; i++) {
		result += "test." + this.wsdl.operations[i].name + "_handle = function ("; 
		for(j = 0; j < this.wsdl.operations[i].input.length; j++) {
			result += (j > 0 ? ",":"") + this.wsdl.operations[i].input[j].name;
		}
		for(j = 0; j < this.wsdl.operations[i].output.length; j++) {
			result += (this.wsdl.operations[i].input.length > 0 || j > 0 ? ",":"") + this.wsdl.operations[i].output[j].name;
		}
		result += 
			") {\n"
			+ "//" + "Put your handler code here\n"
			+ "}\n"; 
	} 
	
	return result;
}

/**
 * Generates the sample html code.
 * @return {String} The html code.
 */
function CodeGen_Html() {
	var i;
	var j;
	var result = "";
	
	result += 
	    "<html>\n"
	    + "  <head>\n"
	    + "    <title" + ">Sample call for " + this.wsdl.name + " WebService<" + "/title" + ">\n"
	    + "  </head>\n"
	    + "  <body>\n"
	    + "    <" + "script language=\"JavaScript\" src=\"webservice.js\"><" + "/script" + ">\n"
	    + "    <" + "script language=\"JavaScript\" src=\"" + this.wsdl.name + ".js\"><" + "/script" + ">\n" 
	    + "    <" + "script language=\"JavaScript\"><" + "!--\n"
		+ this.Sample()
		+ "    //--" + "><" + "/script" + ">\n"
		+ "  </body>\n"
		+ "</html>"; 
	
	return result;
}


Documentation generated by JSDoc on Sun Apr 16 18:38:12 2006