Thursday, June 17, 2010

The Business Service Browser Script

Ok, here's the browser script from the Business Service. The purpose of the BS is to act as wrappers to the server side - allowing rich features on the browser side. I'll discuss in more detail in a future post - there are security concerns in particular here becuase of what we're exposing that are worth a mention.
ExtendJsObjects();
top.oFramework = new Class_Main();

function BuildBsFramework()
{
// empty method - real work done in declarations section
}

function Class_BusComp(theParent)
{
/*------------------------------------------------------------------------------------------
Created: 01/06/2010
Description: BusComp class
Encapsulate functionality relating to Business Components
-----------------------------------------------------------------------------------------*/

var oBusComp =
{
// member variables
name: "Class_BusComp",
parent: theParent,

// member methods - simple wrappers
methodWrapper: Method_Wrapper,
addRecord: function () { return this.methodWrapper("BusComp.addRecord", arguments); },
getRecord: function () { return this.methodWrapper("BusComp.getRecord", arguments); },
getRecords: function () { return this.methodWrapper("BusComp.getRecords", arguments); },
updateRecord: function () { return this.methodWrapper("BusComp.updateRecord", arguments); },
updateRecords: function () { return this.methodWrapper("BusComp.updateRecords", arguments); }
}

return oBusComp;
}

function Class_IHelp(theParent)
{
/*------------------------------------------------------------------------------------------
Created: 01/06/2010
Description: IHelp class
Encapsulate functionality relating to IHelp
------------------------------------------------------------------------------------------*/

var oIHelp =
{
// member variables
name: "Class_IHelp",
parent: theParent,

// member methods
setToPath: function (sHelpPathName)
{
// code removed for brevity - sets iHelp to a particular path
},

setToRoot: function ()
{
// code removed for brevity - returns iHelp to root menu
},

openPath: function (sHelpPathName)
{
// code removed for brevity - opens iHelp menu window + sets to a particular path
}
}

return oIHelp;
}

function Class_Lov(theParent)
{
/*------------------------------------------------------------------------------------------
Created: 16/06/2010
Description: Lov class
Encapsulate functionality relating to LOVs
------------------------------------------------------------------------------------------*/

var oLov =
{
// member variables
name: "Class_Lov",
parent: theParent,

// member methods - simple wrappers
methodWrapper: Method_Wrapper,
get: function () { return this.methodWrapper("Lov.get", arguments); },
getAzValue: function () { return this.methodWrapper("Lov.getAzValue", arguments); },
getDescription: function () { return this.methodWrapper("Lov.getDescription", arguments); },
getEuFlag: function () { return this.methodWrapper("Lov.getEuFlag", arguments); }
}

return oLov;
}

function Class_Main()
{
/*------------------------------------------------------------------------------------------
Created: 05/05/2010
Description: Class definition - can be accessed via top.oFramework
------------------------------------------------------------------------------------------*/

var oMain =
{
// members values
name: "Class_Main",
createdTime: new Date(),
UID: new Date().toTimeStamp(),
aStack: [],

// methods
addToStack: function (sValue)
{
this.aStack.push("[" + new Date().toTimeStamp() + "] " + sValue);
// limit the size of the stack to the last 50 entries
if (this.aStack.length>50)
this.aStack.shift();
},

clearStack: function ()
{
this.aStack = [];
},

getStack: function ()
{
return "[UID:" + this.UID + "]\n" + this.aStack.join("\n");
},

getCreatedTime: function ()
{
return this.createdTime;
},

resizeAppWindow: function ()
{
top.window.moveTo(0,0);
top.window.resizeTo(1280,960);
},

toObject: function (source)
{
/*------------------------------------------------------------------------------------------
Created: 12/05/2010
Description: Rebuild an object from its source representation.
The handling of the _length is to workaround the fact
that Siebel does not allow an object property called "length"
be enumerated using the "for in" construct.

------------------------------------------------------------------------------------------*/

var oT = eval('(' + source + ')');

if (oT._length)
{
oT.length = oT._length;
}
return oT;
},

toSource: function (obj)
{
/*------------------------------------------------------------------------------------------
Created: 11/05/2010
Description: Convert any Javascript object into its source (string) representation
This can be used to pass return objects from the server-side Framework
to the browser side, recursion is used to break down properties of objects
and elements of arrays.

Quirk of Siebel: Arrays seem to have a typeof "function" rather than "object"
as expected. To distinguish between an Array and a real function, check does
it have a method called "shift" - an array will

------------------------------------------------------------------------------------------*/
var sReturn = "";
if (typeof(obj)=="string") // strings - need to quote, also replace ' with \'
{
sReturn = "\"" + obj.replace(/\'/g,"\\\x27") + "\"";
}
else if (typeof(obj.shift)=="function") // arrays
{
sReturn += "[";
for (var i=0; i<obj.length; i++)
{
sReturn += this.toSource(obj[i]) + ", ";
}
sReturn = (sReturn.length==1) ? sReturn + ']' : sReturn.substr(0, sReturn.length-2) + ']';
}
else if (typeof(obj.getTime)=="function") // date
{
sReturn = "new Date(\"" + obj + "\")";
}
else if (typeof(obj)=="object") // objects - loop through properties
{
sReturn += "{";
for (var x in obj)
{
sReturn += (x.indexOf(" ")>-1) ? "\"" + x + "\":" : x + ":" ;
sReturn += this.toSource(obj[x]) + ", ";
}
sReturn = (sReturn.length==1) ? sReturn + '}' : sReturn.substr(0, sReturn.length-2) + '}';
}
else // number, boolen, function will be left
{
sReturn = "" + obj;
}
return sReturn;
},

callServerFramework: function ()
{
/*------------------------------------------------------------------------------------------
Created: 17/05/2010
Description: This method uses a business service to expose server-side Framework methods
to browser script.

------------------------------------------------------------------------------------------*/

var oArguments = arguments[0]; //This will be an array of arguments

//Objects required to call business service
var oBusServ = null;
var oInputs = null;
var oOutputs = null;


try
{
//Set up objects
oBusServ = theApplication().GetService("My Framework");
oInputs = theApplication().NewPropertySet();
oOutputs = theApplication().NewPropertySet();

//Place the first argument in the Method property
oInputs.SetProperty("Method", oArguments.shift());

//Convert the remaining arguments to a string and place in the Arguments property
oInputs.SetProperty("Arguments", this.toSource(oArguments));

//Call server-side Framework
oOutputs = oBusServ.InvokeMethod("RunFrameworkMethod", oInputs);

//Rebuild complex objects and return
if(oOutputs.GetProperty("Return Type") == "Object")
{
return this.toObject(oOutputs.GetProperty("Return Value"));
}
//Return simple objects
else
{
return oOutputs.GetProperty("Return Value");
}

}
catch(e)
{
}
finally
{
//Clear down objects
oArguments = null;
oBusServ = null;
oInputs = null;
oOutputs = null;
}
},

variantToArray: function(pV)
{
return (typeof(pV)=="object" || typeof(pV)=="function" ? pV : [pV]);
}
};

oMain.BusComp = new Class_BusComp(oMain);
oMain.iHelp = new Class_IHelp(oMain);
oMain.Lov = new Class_Lov(oMain);
oMain.Service = new Class_Service(oMain);
oMain.Utility = new Class_Utility(oMain);

return oMain;
}

function Class_Service(theParent)
{
/*------------------------------------------------------------------------------------------
Created: 16/06/2010
Description: Service class
Encapsulate functionality relating to Services
------------------------------------------------------------------------------------------*/

var oService =
{
// member variables
name: "Class_Service",
parent: theParent,

// member methods - simple wrappers
methodWrapper: Method_Wrapper,
run: function () { return this.methodWrapper("Service.run", arguments); },
runAsynch: function () { return this.methodWrapper("Service.runAsynch", arguments); }
}

return oService;
}

function Class_Utility(theParent)
{
/*------------------------------------------------------------------------------------------
Created: 16/06/2010
Description: Service class
Encapsulate functionality relating to Utility
------------------------------------------------------------------------------------------*/

var oUtility =
{
// member variables
name: "Class_Utility",
parent: theParent,

// member methods - simple wrappers
methodWrapper: Method_Wrapper,
getSystemPreference: function () { return this.methodWrapper("Utility.getSystemPreference", arguments); },
setSystemPreference: function () { return this.methodWrapper("Utility.setSystemPreference", arguments); },
logMessage: function () { return this.methodWrapper("Utility.logMessage", arguments); }
}

return oUtility;
}

function ExtendJsObjects()
{
// String methods
String.prototype.spaceToUnderscore = function() {
return this.replace(/\s/g,"_");
}
String.prototype.hasSpace = function() {
return this.match(/\s/);
}
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.trimLeft = function() {
return this.replace(/^\s+/g,"");
}
String.prototype.trimRight = function() {
return this.replace(/\s+$/g,"");
}
String.prototype.inList = function(vA) {
for (var i=0; i<vA.length; i++)
if (vA[i]==this.valueOf())
return true;

return false;
}
// Date methods
Date.prototype.compare = function() {
var op = (arguments.length == 2 ? arguments[0] : "==" );
var pV = (arguments.length == 2 ? arguments[1] : arguments[0] );
var bReturn = false;
var d = new Date();
d.setFromString(pV);

if (op=="!=")
bReturn = this.toString()!=d.toString();
else
{
if (op.indexOf("=")>-1)
bReturn = (this.toString() == d.toString());

if (op.indexOf("<")>-1)
bReturn = bReturn || (this < d);

if (op.indexOf(">")>-1)
bReturn = bReturn || (this > d);
}
return bReturn;
}
Date.prototype.toIso=function() {
// return date in the format YYYYMMDD
var YYYY, MM, DD, M, D; // variables to hold parts of date

YYYY=this.getFullYear()+""; // convert to string
MM = (M=this.getMonth()+1)<10?('0'+M):M; // add 0 if 1-9 to make MM format
DD = (D=this.getDate())<10?('0'+D):D; // add 0 if 1-9 to make DD format

return YYYY+MM+DD;
}
Date.prototype.toDb=function() {
// return date in the format DD/MM/YYYY
var YYYY, MM, DD, M, D; // variables to hold parts of date

YYYY=this.getFullYear()+""; // convert to string
MM = (M=this.getMonth()+1)<10?('0'+M):M; // add 0 if 1-9 to make MM format
DD = (D=this.getDate())<10?('0'+D):D; // add 0 if 1-9 to make DD format

return DD+"/"+MM+"/"+YYYY;
}
Date.prototype.toUs=function() {
// return date in the format MM/DD/YYYY
var YYYY, MM, DD, M, D; // variables to hold parts of date

YYYY=this.getFullYear()+""; // convert to string
MM = (M=this.getMonth()+1)<10?('0'+M):M; // add 0 if 1-9 to make MM format
DD = (D=this.getDate())<10?('0'+D):D; // add 0 if 1-9 to make DD format

return MM+"/"+DD+"/"+YYYY;
}
Date.prototype.toTimeStamp=function() {
var hh,mm,ss,mmm,h,m,s,ms;

var ms = this.getMilliseconds();
var s = this.getSeconds();
var m = this.getMinutes();
var h = this.getHours();

var mmm = (ms<10?('00'+ms):ms<100?('0'+ms):ms);

hh = h<10?('0'+h):h==24?'00':h;
mm=m<10?('0'+m):m;
ss=s<10?('0'+s):s;

return this.toIso() + hh+mm+ss+mmm;
}
Date.prototype.setFromString = function(pV) {
var aTs = pV.split(" ");
var aD = aTs[0].split("/");
var aT = (aTs.length > 1) ? aTs[1].split(":") : [0,0,0];

this.setFullYear(aD[2], aD[1]-1, aD[0]);
this.setHours(aT[0], aT[1], aT[2]);
}
}

function Method_Wrapper(sName, vArguments)
{
/*------------------------------------------------------------------------------------------
Created: 01/06/2010
Description: passes arguments + object.method name to server side
------------------------------------------------------------------------------------------*/
var oArguments =[];

oArguments[0] = sName;

for(var x=0;x<vArguments.length;x++)
{
oArguments[x+1] = vArguments[x];
}

return top.oFramework.callServerFramework(oArguments);
}

function Service_PreInvokeMethod (methodName, inputPropSet, outputPropSet)
{
sReturn = "ContinueOperation";

try
{
switch ( methodName )
{
case "BuildBsFramework":

BuildBsFramework();

sReturn = "CancelOperation";
break;

default:
break;
}
}
catch(e)
{
}
finally
{
}

return (sReturn);
}

1 comment:

  1. This is a very very Nice piece of code and is really really helpful in making future applications to be called new gen...
    Thanks Matt
    Do share some info like these

    ReplyDelete