Featured Article


We are having a ABS Framework Marathon @ Impossible Siebel. Stick around to see what all the hype is about.

Checking for an empty string

Its interesting to look through a repository and see what different methods people use to test for an empty string. Some projects standardize on 1 method, while other projects arnt so consistent.

In this article i'll go through the different methods for testing an empty string in Siebel and look at its pros and cons.

Lets start with our empty string;

var sEmpty = "";


[Method 1]

if (sEmpty == "")
;


This method is used in the Prototype library, and is the most common way of testing for an empty string, and looks the most natural, but it has a flaw.

You may not see any immediate effects of using this method, but if sEmpty is accidentily set to 0, then the expression will evaluate to true. Why does this happen?

If string is compared to a number, the string will be converted to a number implicitly by the engine, before the comparison is made. So the "" will be converted to 0 and compared with 0, which returns true.

[Method 2]

if (sEmpty.length == 0)
;


This is another common way of testing for an empty string, its not as natural as method 1, but is still readable and works well in a strict circumstances.

Strict circumstances? If sEmpty is only declared and not initialized as a string eg. var sEmpty, or declared and not assigned a value, then this method will raise an error.

If people forget to initialize their variables, or the conditions were not met to assign a value to the variable, then this is another potential problem.

Have a look at the following example:

var sErrorMsg;
try{
//do something
} catch(e){
sErrorMsg = e.toString();
} finally {
if (sErrorMsg.length>0)
TheApplication().RaiseErrorText(sErrorMsg);
}


sErrorMsg will only get populated if there is an error, in normal circumstances this will raise an error, of course this would not pass unit testing, but there are times when this problem is less obvious.

To avoid this problem initialize your variables.

[Method 3]

if (sEmpty === "")
;


This method is an improvement on method 1 (note the triple equal sign), the === forces the engine to do a strict compare of the value as well as the type of the object. So if we try to compare "" with 0, the engine will see the mis-match in object types, and return a no match.
eg.

if("0"===0);//returns false;


In theory, this method is faster than the normal == compare, because the engine dosnt have to perform a type conversion.

If we forget to initialize our sEmpty variable again, or assign it a null, then it would also return false, which in a strict sense is correct. An empty string does not technically equal a null or undefined object, but logically it dosnt contain a value and should return empty.

[Method 4]

if (!sEmpty)
;


This last method is more relaxed. What this does is check if sEmpty has a value (or if the value is true) and performs a NOT. So wether your variable is declared like

var sEmpty = "" //or
var sEmpty //or
var sEmpty = null;


This will return false, meaning our variable is empty or has no value. The problem with this method is the same as Method 1, if our sEmpty string is set to the number 0, then it will return empty.

[So which method should you use?]

Method 1 - if (sEmpty == "")
Method 4 - if (!sEmpty)
These methods have a flaw but you can use it with a bit more work

Modified Method 1 a - if (sEmpty==""&&sEmpty!==0)
Kinda ugly, but it works. Method 2,3 are more elegant alternatives.

Modified Method 1 b - if (ToString(sEmpty)=="")
Another variation to get around the same problem. We apply the eScript ToString function to make sure what we have is a string, before doing the compare.

Modified Method 4 - if (!sEmpty&&sEmpty!==0)
This method is good for relaxed comparisons which caters for null and undefined (un-initialized) strings as well.

Methods 2 - if (sEmpty.length == 0)
Methods 3 - if (sEmpty === "")
These methods are good if you need strict comparisons and practice good variable initiation.

[How about creating a String prototype?]

This sounds like a good idea, because we can standardize the implementation and use it system wide. The only caveat with using this as a prototype is that it will only work on string objects! Try it on a number, null, undefined and you will will get an error, because our method is not defined on those object types.

Alternatively, we *could* attach this to the global object prototype, but this isnt a scalable solution. The better alternative is to make this as part of a script library and make use of dynamic typing, then call it like a function instead of a prototype method. (ala ABS Framework)

Who knew that checking for an empty string was so much hassle? If you dont have a script library, you can stick to checking the object length or the ===, but keep in the mind the limitations.

Xmas and the future

Impossible Siebel is taking a break, and is heading towards Surfers Paradise



After bumming around the beach, i might decide to come back, and if i do, there are a bunch of topics that i want to cover.

I've created a new widget called "Future Articles" which will provide readers with an idea of whats to come. Many of these topics, i'm currently drafting or testing, and not just a dream, so more likely than not, they'll materialize if i decide to come back.

I've started a new poll that gives readers a chance to dictate the direction of future articles.

1. ABS articles and tutorials
2. Standard Siebel scripting articles
3. Impossible Siebel Toolbar updates
4. Impossible Challenges & Solutions

You can have multiple choices, so if you are indecisive, choose them all.

On a related note, i'm also working on getting the ABS source code for you guys, dont believe it? Remember you heard it here first, you wont get the full commercial version, but a training version might be possible. This will certainly be a nice christmas present, but dont bet on this horse just yet.

And finally christmas wont be christmas without listening to Wham's Last Christmas. Does anyone else miss the 80s?...



Have fun...

Siebel 8 Tab Order defect on Popup applets

We seem to have lots of encounters with Popup applets here at Impossible Siebel

About Record Applet Challenge

Siebel 7 Dual Screen popup

Siebel 8 Dual Screen popup

Conditional Popup based on button click

MVG Popup Challenge

[Another popup challenge]

On the last day before code freeze, the following challenge came through as a critical defect.

The problem in Siebel 8, is that the tab order is ignored on all popup form applets using grid layout (CSSFramePopup).

The tab order still functions correctly in view applets, but on popup form applets, the tab always moves in a sideways fashion, from left to right, no matter how the sequence property is set on the controls.

This may not seem like a huge issue, but for a customer facing staff this can be mission critical. The tab order allows staff to efficiently key in data in a logical sequence, without using the mouse, and if the tab order changes all of a sudden, they have to un-train their old typing habits and adapt to the new behaviour.

This problem was escalated to the Siebel engineers and we were advised that there is no workaround for this behaviour.

This is bad news, especially for customers who have upgraded from 7.8 to find this functionality has been broken, however the good news is, i have a solution that restores this broken behaviour.

[Tab Behaviour]

To fix the root cause of this problem, we need to understand how the tab behaviour works.

Is it controlled by class/ActiveX code? or by HTML? or by Javascript/browser script? who knows?

The answer is HTML. The actual solution will lead us to a very obscure part of the application.

When we configure Tab order in Siebel, we need to set the HTML sequence for the control on the applet or use the format menu option. The latter option is disabled in Siebel 8.

When siebel generates the HTML for this control definition, it creates a tag called tabIndex which controls the tab sequence in the browser.

Take a look at the following example, and copy it into a plain text file and run it to see how it works.


<html>
<head>
<title>Controlling TAB Order</title>
</head>
<body>
<SPAN>
<form>
<table border=1><tr><td ><div class=GridBorder>
Field 1 (first tab selection):
<input type="text" name="field1" tabindex=1 /><br />

Field 2 (third tab selection):
<input type="text" name="field2" tabindex=3 /><br />

Field 3 (second tab selection):
<input type="text" name="field3" tabindex=2 /><br> </div></td>
</tr>
</table>
</form>
</SPAN>
</body>
</html>


The problem is, this particular tag, cannot be inspected by looking at the HTML source, or sniffing the HTML, because the HTML source is the pre rendered content, which contains all the HTML code and Javascript commands that your browser interprets on the fly to create the actual content that you see.

The only way to get at this information is to traverse the DOM tree, and spool out the post rendered structure (which is the true representation of what you seen on the screen).

When i spooled out the HTML that Siebel rendered, the controls were missing the tabIndex, and it was also malformed.

No wonder it didnt work!, this tag was correctly rendered for applets in the view frame, but was not for popup applets.

[The challenge]

Our particular requirement for this challenge, was to only fix one applet, there were a few others which were affected, but given where we were, the business accepted this compromise, because there was likely to be a lot of hard coding.

We need some mechanism to control the tabIndex, i could query the repository to get the control sequence, but it wouldn't be easy to grab this information from Browser script and was overkill in every sense of the word, the alternative, was to hard code the tabIndex references to correspond to the HTML sequence of the actual control on the applet. Not very nice, but it was an idea.

[The solution]

An unexpected treasure appeared, when the post rendered Siebel HTML source was analysed, the malformed tag actually contained the HTML sequence, but it was disguised by an empty identifier and was actually hacked to the back of another attribute. It seemed that Siebel did generate the sequence attribute, but chopped off the tabIndex indentifier required for this to work.



So now that we have the most important ingredient (the tab sequence of all the controls), we can modify the HTML to create the tabIndex property and inject our sequence.

Its easy to access a node, and grab its attribute, but its difficult if the attribute dosnt have a name, so how do you reference some thing that has no reference? It took me a while to figure out, but heres how i restored the Siebel Tab order.

Put the following code on applet load:

var oControl = this.FindActiveXControl("Any Control
Name");
var oObject =
oControl.document.body.getElementsByTagName("object");
for (var i=0; i < oObject.length; i++)
oObject[i].tabIndex = oObject[i][""];


What this does, is grab a hold of any arbitary control to gain access to the DOM. We then use this handle to go to the top of the DOM hierarchy, and grab all the tags for the applet controls, and insert a tabIndex attribute, and assign it the value of the un-named identifier.



The final solution involved no hard coding of the sequence or control arrays, nor did it require a server trip to retrieve this information from the respository. So we ended up fixing all the other applets that the business wanted.

This is only meant to be a stop gap solution, and hopefully Siebel will fix the bug soon. Dont hold your breath, but also dont go crazy and put this on every popup applet in the application. This solution is only designed for HI mode and was tested on 8.1.1.1, a SI fix wasnt applicable, and wasnt explored. (Thanks to KW for help on analysing this problem)

ImposSiebel Toolbar, About Label

I had a conversation with some Siebel architects not too long ago, and we were talking about Siebel 6. One of the best things about the interface (probably the only thing that was good), was the fact that, when you hovered over any label on the client, it would reveal the actual BC field name in the application status bar.



This was a golden nugget for developers, because instead of going to the applet, viewing the layout, inspecting the control, scrolling down the properties window to get the field name. Siebel 6 provided this information plainly to anyone who cared to look.

The person who designed this functionality was obviously an engineer, and the person who killed the feature in Siebel 7.0 was most likely a marketing person. Siebel professionals who came from the 10 year batch, will remember this feature, and will be happy to know that i've brought this feature back.

This feature is provided for pure nostalgia, but will not have any practical value anymore and I'll explain why soon.

[About Label]

Rather than borrow design cues from a 10 year old interface, i've come up with something a little more modern.

'About Label' provides the developer with detailed information about the label of any form applet inside a floating window, which can be interacted with to show low level BC information.

To invoke this feature, goto any form applet, and pay attention to the labels. When you hover over a suitable label, the background of the label will change color, indicating that this feature is enabled.



Double click on the desired label to call 'About Label'. A dialog will appear showing the following summary information about the field, if it is available.



Calculated fields will not have mapped columns, VBC fields will not have a Table, and System fields will have no definition.

So depending on the kind of field you are inspecting, the following information is displayed.

1. Field Name
2. Column
3. Calculated Value
4. MVL Name
5. Dest Field
6. Dest BC Name
7. Picklist Name
8. Picklist Type Value
9. Table Name

Click on the toggle icon, and the dialog will expand to show the entire list of configured properties for the field.



And finally the field name will be displayed in the status bar for those Siebel 6 hippies who want to do some reminiscing. Give me a Hi-5 in the comments, if you're a hippie.

[Limitations]

1. List applet support
This feature is sorely missing, but it is a tough one, and requires an overhaul of the current design to work, so dont expect it on your radar anytime soon.

2. Popup applet support
This also requires some new design to work, but consider it a weak bleep on your radar.

3. Home pages/SI mode support
SI support is possible with a little tweak and some further testing, but hasnt been enabled. Consider this one a phantom bleep that might appear anytime soon.

4. MVF Column/Table name
'About Label' doesnt show the mapped column/table name for MVF fields. This is a personal annoyance for me, but i dont have a quick solution, so this will be a future enhancement.

[Whats on the horizon?]

Theres still a few features of "Super About View" that i have yet to port over to the ImposSiebel toolbar. The most notable are listed below.

1. About Script

Displays all browser and server script related to the current BC and Applet in an explorer tree. This is useful to inspect the behaviour behind a button, or action on the UI, without going into Tools.

2. About Applet & About BC

Displays low level details about the user properties, and object properties of the Applet and BCs. This is useful to see why fields are read only, or what user properties could contribute to the UI behaviour.

3. 40 second Repository Search

As the feature title suggests, the Impossible Siebel toolbar can scan the repository in roughly 40 seconds, and display a detailed report on the repository reference to any string, field, applet or view definition. Try this with a standard Siebel full repository search, and you'll hang your tools for a few hours!

This will be the last major release for this year, and mostly likely the early part of next year. I must admit, i skipped some corners to get this release out in time, and also deliver the ABS articles. So i will focus on refactoring the code, and creating object wrappers, so its more scalable for future enhancements.

Although this is mostly under the hood enhancements, the foundations will make the above enhancements easier. But to keep you guys/gals happy, i'll provides some nice easter eggs along the way so you dont get bored with all this stability, and scalability nonsense.

ImposSiebel Toolbar, Version 0.54 Release Information

This is the anticipated version of the Impossible Siebel Toolbar, with the "About Label" feature, which was the winner of our last poll.



"About Label" should be fairly obvious to use (hint, its has something to do with Labels). If you can't figure it out, a follow up article will be posted soon to explain how "About Label" works.

Before you skim over this article, the new XML configuration file is mandatory for the "SQL Profiling", and "About Label" to work. This is required for new and existing users.

[Installation]

1. Existing Users


Managed Option
Under the ImposSiebel Toolbar options, just click on "Refresh
Toolbar"

Bookmark Option
If you are using the server copy, i've already uploaded the new
version.

2. New Users

Follow the instructions in the first article
http://www.impossiblesiebel.com/2009/09/impossiebel-toolbar-beta.html

[XML configuration file]


This new component is critical for "About Label" and other future
functionality to work.

Create a XML file called "ISConfig.xml" with the following contents and put it in the following directory.

C:\Program Files\Impossible_Siebel\

<IS>
<odbc>
<source>
<dsn>Your Local Siebel DSN</dsn>
<username>datasource username</username>
<password>datasource password</password>
</source>
</odbc>
<sqlspoolfile>c:\spool.sql</sqlspoolfile>
</IS>

This directory will already be there for users who have opted for the "Managed" version.

[New Features]

1. About Label
This feature provides the developer with detailed information about the label of any form applet.

Keep an eye out for the next article, and i'll provide a tutorial on how to use this functionality.

2. Current Applet and Id
Next to the [IS Menu], i've added dynamic information on the current active applet, and the current Row Id.

When you hover over this text, it will be copied to your clipboard automatically. This is useful, when you have a popup window and want to know its name.

3. Position sensitive "About View", "About Label"
The most annoying behaviour of the previous version, was "About View" only appears in a hard coded position near the top. So if you have a long screen, and try to invoke "About View", you wont see it until you scroll up.

"About View" is now position sensitive to where you double click. This enhancement also applys to "About Label", however other dialogs are still hardcoded.


[Changes]

1. Invoking "About View"

In the previous version, "About View" was invoked by double clicking on any free space in the main view. The term "main view" dosnt really mean anything to anyone except me.

So i've made it more user friendly, by allowing the user to double click on any free space in the application, and this will bring up "About View"

2. Active position/Login information
This information has been shifted from the right of the toolbar to the left

3. SQL Profiler Total Operations

SQL Profiler shows the top 10 operations ordered by SQL cost. There are some cases where you could get thousands of small transactions taking a large amount of resources. In this case the top 10 operations wont reveal the whole picture.

I've added the Total number of SQL operations, so if you have a nasty piece of rescursive SQL, this new information will reveal the proper context of the top 10.


[Fixes]


"About View" Smart Script Crash

Fixed an issue that caused the toolbar to die under a smart scripts
view.



[Known issues]


Cannot establish connection to local database
In Siebel 8, if you are connecting to an encrypted local database, you need to have Tools open at the same time.

You need to open Tools and re-start the client for the changes to take effect.

Server DSN issues
A server DSN can be configured, but it is not recommended because it can be slow. Also the toolbar has only been tested on DB2, and therefore is not guaranteed to work with any other DB vendor.

SI About Label
"About Label" has not been implemented in SI.

ABS Framework - Business Object Library

The ABS Business Object library is probably the most important feature of ABS, from a benefits realization point of view, and heres why.

ABS can make your project atleast 2x more efficient.

The ABS framework provides a global class of functions that allows developers to write code that is leaner, faster, use less memory and require less time and resources than traditional build methods.

That’s a really big promise, and we should be sceptical when someone makes a claim like that, but in this article I’ll look at how ABS achieves this, and how it can be quantified.

[Abstraction Layer]

The goal of the ABS Business Object library is to build on top of the existing Siebel BO functions, and provide the developer with tools to achieve complex functionality with just a few lines of code.

It’s difficult to talk about abstract concepts, without an example, so heres a scenario that all developers can relate to.

If you wanted to query an Account and get back the primary Address related to this account and return the state and city in an array, how many lines of code would it take?

Here’s the traditional way of writing this logic in standard Siebel eScript.

function GetAccountInfo() {
var aAddressInfo = [];

var oBO_Account = TheApplication().GetBusObject("Account");//1
var oBC_Account = oBO_Account.GetBusComp("Account");//2
var oBC_Address;//3

try {
oBC_Account.ClearToQuery();//4
oBC_Account.SetViewMode(AllView);//5
oBC_Account.ActivateField("City");//6
oBC_Account.ActivateField("State");//7
oBC_Account.SetSearchSpec("Id","1-ABC");//8
oBC_Account.ExecuteQuery(ForwardOnly);//9

if (oBC_Account.FirstRecord()) {//10
oBC_Address = oBO_Account.GetMVGBusComp("Address");//11

if (oBC_Address.FirstRecord()) {//12
aAddressInfo[0] = oBC_Address.GetFieldValue("City");//13
aAddressInfo[1] = oBC_Address.GetFieldValue("State");//14
} //15
}
else {
throw "No Address found in the Account";
}

}
}
catch(e) {
throw (e);
}
finally {
}

return aAddressInfo;
}


That’s over 15 lines of actual logic, not including line spacing, and error handling. So how many lines does it take using the ABS BO Library? Just one.

Here’s how we would write the same logic using ABS.

function GetAccountInfo() {
var bErrRaised=false,aAddressInfo;

try {

aAddressInfo = TheAccount.GetChildFieldValueWithId(“1-ABC”,TheAccount.oBCChild_Address,["City","State"],true))[0];//1

}
catch(e)
throw (e);
}
finally {
if (!bErrRaised) return aAddressInfo;
}
}

Let me explain what is happening here.



















 Legend
TheAccount  This is a predefined ABS BO object that is always available in the Application.

Take it for granted that this exists, and you can use it anywhere, and in the chapter on the ABS Universal Object, I’ll explain how this object comes into existence.
TheAccount.oBCChild_Address  This is another predefined ABS BO object.
GetChildFieldValueWithId  This is a method of the ABS BO Object, which is inherited by all BO instances such as TheAccount. It allows the developer to query a child BC using a row id as a search spec, and return a set of values as an array.


[Inputs]



sId = Row Id

hbChildHandler: Child BC instance

hbChildField: Fields to return

bRaiseErrIfNoRecChild: throw error if not found

sSortSpecChild: Child BC Sort Spec


[Re-Use]

The above example highlights one of the main principles around ABS: Re-use.

Why do we have to write

GetBusObject(), GetBusComp(), ClearToQuery(), ActivateFields(), SetViewMode(), SetSearchExpr(),ExecuteQuery(),FirstRecord()

in every function, in every business component, applet or business service in the application, hundreds of time, over and over again?

We can start to imagine how this kind of code writing can lead to application bloat, adding to application maintenance, reducing the upgradability of a project, and obscuring business logic with un-necessary repetition of technical artifacts.

ABS encapsulates the above logic in a single function, that can be used anywhere in the application.

Writing less code, will definitely add to your efficiency.

[Upgradability]

One of the main arguments for using declarative configuration methods is that it can be easily upgraded. The reasoning is that if all your logic is configured rather than scripted, then the upgrade would be painless and carefree.

Well, that is really not the case. In 7.5 you could have WFs that have steps that were free standing with no connecting lines, 7.5 also allowed WF designers to have multiple start points. This is illegal in 7.7 onwards, and during the upgrade you will have to fix all your WFs.

Experienced people will see that WFs are not foolproof in upgrades, they are just as likely to be obsolete as scripted solutions.

The argument against using traditional eScript, is when you perform an upgrade, Siebel does not touch your script, so every piece of code has to be retested.

How does ABS differ?

The highly modular design of ABS makes it more favourable to upgrades.

For example.

If Siebel decided to make ActivateFields deprecated, and forced developers to use ActivateMultipleFields instead.

You’ll only need to find that one place in the ABS framework, and replace it with the new method. Of course, the unit testing has to be thorough, but once it has been unit tested in this function, the entire application will benefit.

Upgrades can never done by the push of a button, but if you given the choice of upgrading an application with a hoarde of WFs with hundreds of individually defined steps, a massively scripted spaghetti system, or a highly modular but concise scripted system, which one would you choose?

[Improve Efficiency]

Let’s revisit that promise again.

“ABS can make your project atleast 2x more efficient.

…write code that is leaner, faster, use less memory and require less time and resources than traditional build methods. “


Write faster code

If we had two developers with EQUAL knowledge and experience, 1 is skilled in eScript and the other is skilled in ABS.

Which developer would have the advantage? I think the answer is obvious. The eScript developer would have to write 15 times more code than the ABS developer.

That is an unholy advantage. Not only would the ABS developer be faster, but would also have 15x less code to troubleshoot if there was something wrong.

Leaner code

15 lines vs 1 line, need I say more?

The code is not only leaner, but also more representative of the business logic and more readable at the same time.

Use less memory

Business Objects and Business Components are only ever instanciated once, and re-used throughout the lifetime of the user session. This will be explained in more detail in a section for the ABS Universal Object.

Less time/resources

The tangible benefit that the ABS BO library brings to projects is obvious. To run and maintain a large scale project will require less time and resources. This puts project managers in a better bargaining position.

Theoretically, you would have to hire 15 eScript developers to do the same amount of work of 1 master ABS developer.

But realistically, you do not need to hire master ABS developers, you only need to get Siebel developers who have a solid foundation in scripting (preferably ECMA), and who are open minded to the ABS philosophy.

While you cannot hire just anyone that walks in from the street, you’ll only need a few very good people, rather than a brigade of good people.

[Conclusion]

The use of ABS is not widespread, and part of the reason for this is that it needs to be implemented as a total solution, and not in bits and pieces. And the most suitable implementations are the green field projects, or projects which are still young.

Currently there is only one Systems Integrator that is implementing ABS solutions on a grand scale, and the benchmark hasn’t been made public.

A 2x improvement in efficiency sounds controversial, but if we base our conclusion of other ECMA script frameworks, such as jQuery, Scriptaculous and Prototype. We know that scripting frameworks do deliver on efficiency, as well as improving code readability, and application maintenance.

We saw that by using ABS, build and testing times were cut by a factor of 15. Saying that ABS delivers 2x more efficiency is quite conservative, but keeps it realistic.

Code bloat is detrimental to the long term maintenance of the application, and the main culprit is eScript, so its interestesting to see a framework like ABS tackle this problem head on with a very radical tactic:

Using ECMA Script to reduce eScript.

Implementing a concise, highly modular, Siebel framework, using ECMA script to lay the foundation, is not something that your average scripting expert can achieve.

People that can pull off this sort of feat, are your architect of architects.

ABS Framework - Prototype Library

[What is a Prototype?]

Using the prototype object is common in web development circles, but it is foreign to most experienced Siebel professionals.

This is the definition of “prototype” object according to Siebel Help
    An object prototype lets you specify a set of default values for an object. When an object property that has not been assigned a value is accessed, the prototype is consulted. If such a property exists in the prototype, its value is used for the object property.

    Object prototypes are useful to be sure that every instance of an object use the same default values and that these instances conserve the amount of memory needed to run a script. Then every instance of the object use the same function instead of each using its own copy of it.


That is quite an abstract description, and although it tries to explain the concept using a generic example, it still feels very disconnected.

In layman terms, using the prototype statement allows developers to add properties and methods to all instances of custom and pre-built objects in eScript/browser script (excluding Siebel Objects).

    So how do we use prototype to solve real world Siebel problems?

[ABS Prototypes]

The ABS framework includes prototypes to reduce the daily scripting chores for Siebel professionals. In this article we look at the some of the most interesting prototypes in ABS, and see how it can make our lives easier and more fun.

The ideas for these prototypes comes from years of experience and tideous hours of work to encapsulate the common routines that Siebel configurators and Integration people can share in one common library.

Array.IsIn

There are a lot of times when we want to compare the current active view, to a list of predetermined views, before performing some action.

Normally we have to write code like this to achieve it

var sViewName = TheApplication().ActiveViewName();

If (sViewName == “View1” || sViewName == “View2” || sViewName == “View3”) {

}

ABS provides us with IsIn() to achieve this same functionality in a more elegant manner.

var aViewName = [“View1”,“View2”,“View3”];
if (aViewName.IsIn(TheApplication().ActiveViewName()) {
}


This function returns a Boolean, indicating whether a value exists or not, but also returns an additional property that points to the index of the matched value.

Date.ToISO

ToISO() is useful for formatting dates to ISO format. This is commonly used to convert dates, so it can be easily sorted alphabetically.

var oDate = new Date(2000,1,1);
oDate.ToISO() = "20000101"


Date.ToDB

ToDB() allows the developer to get the current date and do a setfieldvalue without doing messy conversions.

Date.ToDB() //This returns the current date in MM/DD/YYYY format for setfieldvalue


Date.Compare
Compare() is a really powerful shorthand method of comparing dates or datetime.

A common business requirement is to ensure the currently selected date is greater than the created date, but less than a future date.

Heres how we would normally perform this operation.

//Convert to date object
oCreated = new Date("12/31/1999");
oFutureDate = new Date("1/1/2001");
oCurrentDate = new Date("1/1/2000");

If (oCurrentDate.GetTimeStamp() > oCreated.GetTimeStamp() && oCurrentDate.GetTimeStamp() < oFutureDate. GetTimeStamp ())


ABS does it in one line

Date.Compare("1/1/2000",">","12/31/1999","<","1/1/2001") = true


Heres a couple more examples of how it can be used to quickly compare dates.

//Created for date comparison of date1>date2 or date1>date2>date3
//Example 1:
Date.Compare("12/31/1999",">","1/1/2000") = false

//Example 2:
Date.Compare("12/31/1999","<","1/1/2000",">","") = true
//for the case of open date


Array.PSToStr

PSToStr () converts a Siebel PropertySet to a string for debugging. This is a very common situation for developers to find themselves in.

But it’s the implementation of this function as part of the Array object, which makes it unique. This allows it to be executed from Global scope, anywhere in the application, without using business service script libraries.


var oPS = TheApplication().NewPropertySet();

oPS.SetProperty(“A”,”1”);
[oPS].PSToStr(); //This returns a string representation of the PS


[Reducing code in your application]

Date.Compare() is a really good example of how prototypes can reduce code in your application. This prototype allows a developer to use date strings, to compare dates, without having to manually convert them to date objects.

Converting strings to dates is integral to comparing Dates correctly in Siebel, so instead of having these date conversion routines littered across the application in BCs, Applets and BSs, ABS prototypes this functionality to the Date Object.

ABS Prototypes is a feature purely for coders, but even if you don’t write a lot of script, whatever script you write will be very compact.

What if your project has massive amounts of scripting? We all know these projects exist.

Some projects start off with the noble principle of “exhausting” every declarative means of configuration, before turning to script, but this usually dosnt last, and there are a few common reasons for this.

    * Project cannot say “No” to funky ideas from business
    * Tight deadlines
    * In-experienced developers


Its likely to be a combination, if not all of the above. Its natural that people pick up scripting quicker than using WF, a junior can come in fresh from high school, know a little bit (or a lot) of Javascript, copy a bit of code from here and there, and with a small amount of effort, get a working solution.

Using prototype allows projects to build your own code library, these functions are bound to the standard ECMA objects, and can be re-used across the application without instantiation.

[Reduce memory usage]

I know you didn’t pay much attention to Siebel’s definition of prototype, but its interesting to revisit it (a part of it).

    Object prototypes are useful to be sure that every instance of an object use the same default values and that these instances conserve the amount of memory needed to run a script. Then every instance of the object use the same function instead of each using its own copy of it.


At this stage, we have a little more context of what prototype can do for our projects, and the Siebel definition seems to be more comprehensible.

But for the project managers, and executives out there, the prototype objects ensure that functions are instantiated once and shared across the application, and by taking advantage of prototypes, a project can reduce the memory usage in the application.

With a robust suite of prototypes at the core of your application, you have a more scalable and manageable solution at hand, or where ever you go in future.

[Conclusion]

The ABS Prototype feature, dosnt make people better scripters, but it does reduce the amount of scripting in the application, and provides a repository of common routines, that in-experienced (and experienced) developers can rely on, without re-inventing the wheel.

Benefits of using Prototypes


    1) Reduce the size and clutter in the repository
    2) Reduce redundant code writing
    3) Standardize implementation of common routines
    4) Easier code maintenance
    5) Speed and streamline up code development
    6) Reduce memory usage


Pre-requisites


Prototypes should be implemented by developers with a solid understanding of ECMA script (not eScript). Improper implementation of prototypes can lead to memory leaks and defective behaviour across your application.

This also applies to projects that currently have ABS, and want to enhance the prototype library.

Projects need to ensure that there is a clear owner for the prototype library, and this person or group, have exclusive controls to these library functions, and makes changes on behalf of everyone. This ensures a layer of quality control, and a consistent coding standard is maintained for the project.

ABS Framework - Logging & Tracing Module

Log files are the bread and butter of every developer, so every once in a while it is interesting to meet a developer who has never used Trace() before. So how do these people troubleshoot Siebel? Using debugger, amazing!

Although debugging is useful, it’s not always reliable. In complex scenarios, when you have logic across different objects, the debugger just dies, or jumps around erratically. In these cases it’s just more efficient to dump out all the information to a file and analyse what went wrong.

From the most mundane, to the most critical problem, having informative logs is crucial to solving problems quickly.

For this purpose Siebel provides us with a basic tool.

    TheApplication().Trace()

Good old Trace, what this does is allow us to route key information to a log file during script execution. This same log file is used by the Siebel application for its application logging. So the first frustration developers get is all the information they are trying to dump out, is being buried by all the Siebel internal object allocation and destruction information.

Trace() is used by developers during the build phase and is inserted when a problem is found or in key areas for unit testing, and it is removed before the code is migrated into the test environments and ultimately in production.

Trace()
does the job, and gives developers the basic means to troubleshoot problems. Its function is not flashy, and it’s a little better than popping up an alert box, but we all learn to live with it pretty quickly.

[Paradigm Shift]


With that perspective, anyone that looks at ABS business code, will notice one major contrast to the above logging paradigm.

The ABS tracing module is used as part of the program design, rather than to troubleshoot problems as they arise.

In standard code, we normally trace the start, end and catch of each function, and put lots of comments to explain the code.

In ABS code, tracing is done at the start, end, catch, and is put at key decision points in the program, and this is left in the code, even when it is migrated into production.

The advantage of doing this is two fold.

1. The code is self documenting
    By including descriptions of the program logic in business speak, anyone can turn on tracing, perform the function, and the system will spool the program logic to a log for analysis.

2. On demand function execution information
    Since the tracing code is part of the program design, a developer can go into any environment, look at the ABS logs, or re-run the function, and have access to the details of the function execution details.

Similar to the way Workflow provides a debug mode for developers to see step and variable information of the runtime action. This ABS design feature closes the gap on the advantage that declarative configurations once had.

This is quite powerful, because it allows the developer to debug the problem live in an environment with real data, which can’t always be created on a local environment.

[Logging Levels]

Conforming to the Siebel logging standard, the ABS logging module has 5 levels of logging detail. Setting this value controls the amount of detail that is spooled to the log file. By default it is set to 3, but this can be overridden by the developer in the system preference or in the code.



[ABS Logging & Tracing components ]

    1. MSG object
    2. LOG object
    3. EXCEP object


[MSG Object]

One of the key design principles around the ABS System is re-use. Messages can be categorised and parameterised and re-used across the application.

To display errors or log error messages, we need to create our own message category in the Application, ABS encourages this over hard coding custom errors on the fly.

The ABS System creates a category called ABS Defined Messages.

Instead of using numbers and defined ranges for their use, the ABS Logging module uses identifiers with the following naming standard.



The ABS Defined Messages is only used for the ABS framework for standard error messages, to display more specific error messages, we need to create our own custom message category, and follow the above standard to define our messages.

Although it is not enforced, it is encouraged to follow this standard, because it makes managing error messages, and looking up their relationship to the functional areas easier.

[LOG Object]

This object defines how a function is logged, and does the actual job of tracing the messages to a file.

ABS Log files are generated in the following format, but can be changed according to individual user preferences.































 LOG object Methods
 Begin  Tell the logging module that a new function has begun
 Step  Used to record key milestones in the script and document the process
 StepResult  Used to document the result of a milestone
 End  Tell the the logging module that the function ended without any errors
 Error  Logs the error object



The basic construct must be built like this, for the proper logging and log format indenting to happen.



[EXCEP Object]


In a standard application, when an error is raised, the developer can choose to override this error, to provide a different message that is more suited to the context, or bubble it up the the parent function, but local variables are lost when the function loses scope.

In ABS, when an error occurs, the EXCEP object is thrown, the relevant parameters are captured and stored in the EXCEP object, and the original message is discarded after it is logged, the EXCEP object is then bubbled up in the function chain.

When the error bubbles back to the base function, the parameters are written out along with the error message.

This is very interesting, because it allows us to display a meaningful error message with full context of the parameters at the point when the error occurred.

[Example Error Log]



This is the function calling path from the above example.
    BO_Service -> LOV_Service -> LOV_GetValue -> LOV_GetAnyField -> BO_Query -> SYS_Assert

The error is raised at SYS_Assert, but it has no useful information at this point, so the error is thrown up the chain to BO_Query.

BO_Query is the real reason why the exception was raised, the arguments captured by this function are important, and will not be available once the function finishes, so it is bubbled up further along the function chain, with arguments captured from previous functions, until it reaches BO_Service

BO_Service is where the message is finally displayed. The cause of the error is due to a BC query that returned no results, but you want to override this, and display something more meaningful to the end user, but still log the actual technical reason for the developer.

The result is an informative message that contains details gathered from various parts of the function calling chain.

[Consolidated Server Logs]

The ABS Logging module solves a very fundamental problem with Siebel server logs. If you are in a multi-server environment and have 10 Siebel application servers, each will have its own set of application logs. So what happens when there is an error? We need to find out which server we were logged onto!

Why do we have to hunt for our logs?

ABS allows us to save logs from all our application servers in one central location.


Developers and environment guys a like, will really appreciate this feature. The design of ABS is an evolution of the way Siebel manages its logs.

[Self Documentation]

Traditional documentation and diagrams can be quickly outdated, especially if the rules are complex, and change every release. Script should be easy to read and understandable, the ABS system takes this idea further, and uses the logging objects to document the system.

With the correct usage of these functions, the ABS logging module will allow anyone to go into the system, and generate 100% accurate documentation of the system in business speak.

[Pro-active Error handling]

During the build and test phase, a developer builds a piece of functionality, does the unit testing, and migrates the code for testing. The tester will look at the build and raise defects that will event get re-assigned back to the developer. This process can take days.

The ABS system takes a more proactive approach, when ever an error is raised, it uses a SR style ticketing system, and assigns the error, based on its category to the correct position, in real time. This way a developer can get all the details of an exception, even before the tester has even realised there was an error.

[Conclusion]

The ABS logging & Tracing module provides the following features

    1. Detailed contextual error messages
    2. Step execution and function parameter information
    3. Self documentation mechanism
    4. Problem ticket assignment
    5. Consolidated server logs
    6. Works in WF and Script


Developers will appreciate the level of detail provided by the ABS system.

    1. Point of error
    2. Function calling path
    3. Function inputs and outputs
    4. Name, Value, and Type of arguments used in function

ABS can generate a lot of logs, so its important to keep your eye on disk space. The good news is the design of ABS allows all logs to be saved to one central place, so you only have to monitor one location, unfortunately, we cannot do the same for Siebel logs.

The developer shouldn't have to hunt around the logs for an error, then wonder where it exactly originated, and what were the conditions that caused it to error. All this information should be captured at the point of error.

If we reflect for a moment and compare the ABS logging module to the standard Siebel solution, the TheApplication().Trace() feels somehow inadequate, its like trying to fight fire with a water pistol.

The ABS logging and Tracing modules provides advanced tools for projects to quickly identify problems, turn around a solution and focus on the delivery.

What is the scope of a variable in eScript/Browser Script?

It is considered best practice, that we should always declare our variables outside the try/catch block. It is also one of the main recommendations of the following Siebel support document.

Assigning Null to Variables [ID 508828.1]

This was the question that was asked by the customer in the above article:

"In order for a variable to be referenced inside of a finally block, is it required for the variable to be declared before the try block, or can it be declared within the try block without any risk of not having all of the null statements work properly."


And Siebel provided this answer:

"If a variable is declared in the try block, there is no way to use them in the catch or even in the finally blocks, so using them in
these other blocks will lead to have an execution error."


This is the example that was provided to support this claim.

function foo()
{
var var1;

try
{
var var2;
if(true)
{
var var3;

for(var index = 0; index < 2; index++)
{
// Accessible variables are var1, var2, var3 and index
}
// Accessible variables are var1, var2 and var3
}
// Accessible variables are var1 and var2
}
catch(e)
{
var var4;
// Accessible variables are var1 and var4
}
finally
{
// Accessible variable is var1
}
}

This article was written by a very knowlegable person. The quality of his answers on Support web, shows that he has quite an extraordinary understanding of scripting, so one does not naturally question this sort of authority, but something didnt add up.

eScript which is based on ECMA script, does not have block level scoping. This is very important, because it means that the above test case will never prove true. Dont take it from me, take it from the ECMA standard itself, here is the reference.

http://www.ecma-international.org/publications/standards/ecma-262.htm

"A Block does not define a new execution scope. Only Program and Function Declaration produce a new scope"


There are two exceptions to this rule.

"the scope chain of the execution context is affected only by with statements and catch clauses."

But lets put standards and theory aside, because Siebel can add its own flavour into to the mix, so lets actually test the damn thing.

Take the above script, and trace out variable var2 in the finally block, this should not work according to the Siebel recommendation, but it does.

function foo()
{
try {
var var2=2;
}
catch(e){
}
finally {
// Accessible variable is var1
TheApplication().Trace(var2);
}
}

The explanation for this is, is eScript like ECMA Script has function scope. Any variable declared inside the function is a local variable, and is available throughout the lifetime of the function.

The test was done with primitive and complex objects, and has been tested in IE 6 Javascript, Siebel 8.1.1.1 eScript ST Engine, and Siebel 7.8 T Engine.

This illustration does not invalidate the Siebel recommendation, but it does highlight the importance of understanding why we have to do things in a particular way, and what effect it has.

Declaring variables outside the try/catch blocks comes from solid tradition, behind programming languages such Java and C. And if you are starting out in ECMA Script and want to learn Java in future, then this is one less scripting habit you have to change.

The only caution i would give, is dont add complex initialization routines for your variables outside the try catch, because you do not have the safety if it fails. Initialize it before the try, and use it in the try/catch/finally body.

Results of ImposSiebel Toolbar poll



The results are surprising, and shows that readers are heavily divided on two features.

The winner of course is the field/column/table information, users who voted for this option are practical, they want fast access to their configuration without messing about in Tools.

What is surprising to me, is the number of people who voted on Browser Script tracing. It might just be my reader demographics, because on most projects, Browser Script is avoided, and given in for Server script solutions.

Although its use should be minimized, its fair to say that Browser Script functionality offers really cool functionality for end users, that cannot be achieved using Server script. People who voted for this, are likely to be flashy, and sacrifice practicality for a little luxury.

I have prototyped both features, but can only focus on one, because both require a lot of work (my spare time).

But as a consolation prize for the code junkies out there, i'll dedicate a couple of articles on some obscure Browser Script behaviour and tips for rapid development.

The new feature will be available in a few weeks (maybe less), so keep an eye on ImposSiebel twitter for updates on the next IS Toolbar version.