This is really exciting, and I’m sure you guys/gals will think so too. The following article was written by Master Frolov, to explain the design of his program.
-----------------------------------------------
Brief Introduction
All of us, those who deal with Siebel customization in local machines, know that GenBScript generates browser scripts by parsing SRF fie and puts them into a special folder and this folder is names uniquely based on some not very obvious rules. The process itself takes (depending mostly on CPU) from 1 to 3 minutes.
If you have automatic SRF compilation during the night, you have to use GenBScript every morning when you replace the SRF.
Additionally if you have several environments (prod, prod copy for support, upcoming release test, integration test, load test etc. to name a few) and you have to switch from one environment to another throughout the day, time consumed by GenBScript may reach up to 1 – 1.5 hours.
Though incremental compilation of an applet with browser script puts browser scripts in the right directory (if you managed to set up the corresponding options in Tools), the are still a lot of cases when you need to run GenBScript by hand.
The proposed method allows quick and painless method of producing the same result as GenBScript but using slightly different approach to gain performance improvement.
Our tests show that in most cases it gives less than 10 seconds per run (mostly around 5).
Idea behind the proposal
My goal was to reproduce the result of GenBScript as close as possible so first of all I prepared the list of questions needed to be solved for that purpose:
1. How to determine the folder name to which GenBScript result is placed?
2. What’s the difference between the script sources in editor and the resulting scripts in *.js files?
The idea behind the method is to use script sources from database instead of SRF file to produce result as close as possible to original GenBScript and do it as quickly as possible.
To answer both of these questions we need to perform some analysis.
Firstly about the folder name. The folder name is constructed using two parts:
srfXXXXXXXX_YYY. For those of you who are familiar with unix or java, it should be familiar that the time is measured by counting seconds (or milliseconds) from 1st of Jan, 1970. So after some research I realized that XXXXXXXX – is the number of seconds passed from 1st of Jan 1970 when then last full or incremental compilation took place. The seconds part YYY seems to be dependent of whether the SRF is a full compile or an incremental compile.
The problem here is that XXXXXXXX not a creation or modification date of SRF file itself, but a part of an internal record in SRF file.
To approach this issue we need to remember that some time ago there was an article in one of Siebel-related forums stating that SRF file is no more than bare OLE document (which is also used by older versions of Microsoft office system) which is essentially a container format which has its own internal file system. By the way you can easily prove that opening SRF file in 7-zip archive manager which supports this format.
So after some effort I found out that the number of seconds from 1st of Jan 1970 is stored in one of two records which named… surprise-surprise… “Full Compile” and “Last Incr. Compile” respectively and are stored in the root of internal file system. Both of those records have 384 bytes in length and the seconds value is stored in bytes 4-5-6-7 (in reverse order).
So we need to parse SRF records to find one of the entries named “Full Compile” or “Last Incr. Compile”. If latter is found then we have an incremental SRF otherwise full-compiled. The second part YYY as I already mentioned depends solely on whether SRF in question is incremental or full compile. Respectively you need to use 612 for incremental and 599 for full compile.
The second question. How to organize script source code (which we have in repository database) into a bunch of script files. Well, I found out that there are quite a few changes between source code in repository and resulting script files.
1. Scripts are aggregated to parent object. This means that there is one script file per Applet/Business Service/Business Component/Application (with some minor exception for an Applet objects)
2. Names of pre-defined functions are prefixed with escaped name of a parent object
3. Applets have two script files one for controls and one for all the other functions.
I will omit all the details here, this is not really complex. You can look up source code if you wish to find them out yourself.
The implementation
The program is written in Java as single Java-file which contains numerous child subclasses.
To parse OLE file format I used apache POI library which has convenient methods to parse office documents (the funny thing is that file format is called HPSF which stands for Horrible Property Set Format :-) ).
To perform database operations I used jdbcType4 Oracle driver (jdbc6,jar from jdbc/lib folder of Oracle installation home).
Note about supported databases: in theory program should work in any database used in develpoment environment (I mean Sybase (through ODBC), MSSQL (through ODBC) and Oracle (native type 4 (thin), native type3 (TNS) or ODBC). I don’t have any idea about more exotic DB2 but I assume they are not used in development very frequently anyway. I tested only for Oracle but kept in mind other databases during development.
Testing method I used is standard text-compare. The only issue I ran into is that there is no specific order of methods in repository for browser script as they present for server scripts. This make impossible to make binary compare between GenBScript and QuickGenBScript. No other script text differences were identified.
The program was written in one working day, it is fairly small (around 700+ LoC). I and two of my colleagues use it permanently for several week already, no issues found so far.
Installation/Configuration
The program itself is run without any input parameters. This is done intentionally to promote ease of use. Based on my experience, it is easier to spend some time for initial set up than to enter some parameters each time you need to run it.
So the configuration is done through editing two text files (db.properties for database parameters and srf.properties for srf parameters). The program looks for these files in working directory (may not be the same as program directory). If you need to run QuickGenBScript for several environments it is worth doing several folder (each folder for single environment) and place both of db.properties and srf.properties in each of those folder. Then setup environment parameters for each environment and bat-files to run QuickGenBScript in those folders. Alternatively you can set up several installations of QuickGenBScript since it is quite small anyway.
What to configure.
db.properties
ConnectURL - url to database according to syntax for a given driver. Example: jdbc:odbc:
DriverClassName - fully-qualified database driver class name. For example, sub.jdbc.odbc.JdbcOdbcDriver for an ODBC driver and oracle.jdbc.OracleDriver for oracle database driver
Login - database user login
Password - database user password
UseSchema - valid values are “true” and “false”. Whether to prefix table names with schema name (required for oracle when user name is different from siebel system user name)
SchemaName - the prefix to use for database table names. Schemas and table names are separated by dot (“.”)
RepositoryName - the name of Siebel repository to use as a source of browser script data. Normally this should be “Siebel Repository”
ShowSQL - whether to show SQL generated and some more debug output. Normally should be “false”
srf.properties
PathToSRF - path to SRF for which you need to generate browser scripts. It is used to find out the folder name where resulting scripts will be stored.
IMPORTANT: in *.properties files back-slach (“\”) must be DOUBLED. For example c:\Siebel\Client\PUBLIC\ENU\Siebel_SIA.srf transforms to c:\\Siebel\\Client\\PUBLIC\\ENU\\Siebel_SIA.srf
FullCompileSuffix=599. You need to run original GenBScript againts a full-compile SRF file and find out which is the suffix for directory where it puts generated files. In version 8.0 this is 599.
IncrementCompileSuffix=612. The same for increment SRF.
TargetDir - the root public\enu directory where generated files should be stored.
IMPORTANT: IMPORTANT: in *.properties files back-slach (“\”) must be DOUBLED. c:\Siebel\Client\PUBLIC\ENU turns to c:\\Siebel\\Client\\PUBLIC\\ENU
TargetEncoding=utf-8. Target encoding for generated scripts. Leave it as it is.
How to run
Prerequisites: JRE or JDK version 1.6. I assume java.exe can be found in PATH, so no java path is present in run.bat
run.bat contains a single line code which essentially includes apache POI, database library (jdbc6.jar in distributive) and QuickGenBScript.jar which contains all the class.files from QuickGenBScripts (quite a few).
Unfortunately initial implementation requires quite a lot of RAM to run (300M is enough). This is due to the fact that SRF file contains > 70 000 entries (in our case) which need to be parsed.
Additionally I published Eclipse project containing all that is required to run and debug QuickGenBScript in Eclipse environment.
PS: Sorry guys. almost no comments in source code, I’m just really very busy nowadays with my full-time job. I’m a bit ashamed to produce code without comments, but... That’s life. Besides, I’m willing too much to share this interesting research project with you.
Screenshots
With option ShowSQL=true
With option ShowSQL=false
References:
SourceForge download page:
https://sourceforge.net/projects/quickgenbscript/files/
Source code can be obtained via SVN
svn co https://quickgenbscript.svn.sourceforge.net/svnroot/quickgenbscript quickgenbscript
Official notice: QuickGenBScript is purely for development tool, use it on your own risk. Though it’s working, it is experimental and completely unsupported by Oracle. NEVER USE IT IN PRODUCTION ENVIRONMENT!!! Nevertheless, I believe many of you will like it.
-----------------------------------------------
Thanks to Kirill, for providing the community with greater insight into the inner workings of Siebel, and improving the lives of all Developers.
I think there is one aspect that would really top this off. How do we automatically discover the suffix code for Full and Incremental compiles? I think the answer is in the SRF, consider it a challenge =).
Here is the db.properties for a local db
ReplyDeleteConnectURL=jdbc:odbc:SSD Local Db default instance
DriverClassName=sun.jdbc.odbc.JdbcOdbcDriver
Login=SADMIN
Password=SADMIN
UseSchema=true
SchemaName=SIEBEL
RepositoryName=Siebel Repository
ShowSQL=false
Много букаф
ReplyDelete