Saturday, September 20, 2008

printf for Peoplesoft

Many languages include a printf function for formatting strings. The main point of printf is to provide programmers with a way to insert dates, times, numbers, and other strings into a final string. This final string is sometimes referred to as a format string or pattern because it contains the formatting characters required by printf to convert numbers and dates into strings. For example, should that floating point decimal have 2 or 3 digits after the decimal place? printf has its roots in C++, where string construction requires memory buffer allocation, etc. Simply put, printf simplifies formatting strings in languages that don't treat strings as native objects. Many languages support printf. As of Java 1.5, the Java runtime environment included with PeopleTools 8.49, supports printf. Since Java supports it, we can use it from PeopleCode. If you are new to printf, then take a look at the printf Wikipedia entry. If you are familiar with printf and just want to know how to use it, then take a look at the Format String Syntax of the java.util.Formatter class. The code below actually uses the format(Locale l, String format, Object... args) method of the java.lang.String class. If you are interested in using printf with PeopleCode, here is an example to get you started:

Function printf(&language As string, &country As string, &message As string, &parms As array of any) Returns string
Local JavaObject &jLocale = CreateJavaObject("java.util.Locale", &language, &country);
Local JavaObject &jParms = CreateJavaArray("java.lang.Object[]", &parms.Len);

CopyToJavaArray(&parms, &jParms);
Return GetJavaClass("java.lang.String").format(&jLocale, &message, &jParms);

Function IScript_TestPrintf()
Local string &message = "Amount gained or lost since last statement dated %1$tc: $ %2$(,.2f";
Local array of any &parms = CreateArrayAny();

%Response.WriteLine(printf("en", "us", &message, &parms));
%Response.WriteLine(printf("es", "es", &message, &parms));

Notice that my printf function takes a language code and a country code. These are the ISO language and country codes defined in ISO-639 and ISO-3166 respectively. One of the places Java's formatting functions shine is in creating locale specific strings. If you don't need to format strings for different Locales, then you can delete these parameters and use the 2 argument version of the format method.

One thing that is interesting to note is that the format method of the java.lang.String class takes a variable length list of arguments. PeopleCode functions don't have this concept. In fact, Java objects called from PeopleCode don't have this concept either. As I was trying to figure out how to call this function from PeopleCode, I did a little research on Java's variable length parameter lists. It appears that this convention is a design time convention and that the compiler actually converts variable length lists into arrays. At runtime, these lists actually appear as arrays. Therefore, we can call a method that takes variable length parameters by passing that method an array. In this case, since the parameters are of type java.lang.Object, we can use the CopyToJavaArray PeopleCode function to copy an array of type Any into a Java Array of type java.lang.Object.


Luis Marion said...

I need to rewrite a Java program in SQR. It generates a flat file with a very long record with lots of fields.

I have a buffer in Java
private char record[] = new char[750];
which I load with the desired fields
output(146, rs.getString("STREET_2"));
output(176, rs.getString("CITY"));
The output() method simply loads a field into the buffer
private void output(int start, String field)
{if (field != null)
field.getChars(0, field.length(), record, start - 1);

Once a record is filled in, I write the entire buffer to the file.

I would like to do the same in SQR. If I list all fields on the SQR write statement then they would become positional relative to the prior. It would work, but it is not exactly what the Java code does. Plus it makes it harder to debug and maintain.

I appreciate your help!


Jim Marion said...

Sorry Luis, I don't have much experience with SQR.

HH said...

This may be an Off Topic for this post.
I am having issues with JQuery.

I this in an HTML area enveloped in a script tag:

alert("I am there");

alert("I am here");

alert("I am again");

The alert "I am there" is firing.

But nothing is firing in $(document).ready. Also the "I am again" does not fire as well.

How do I find out what the cause is ?

Jim Marion said...

@HH, you are right, that is off topic. No matter.

The code you have shown looks correct for jQuery. The "I am again" code should fire before the "I am here" code. It looks like your browser is failing on $(document).ready.

Do you have Firefox with Firebug installed? If so, then navigate to your page, change the URL from psp to psc, and then execute the $(document).ready(...) code in the firebug console. It will run immediately if the document is already loaded.

Are you sure that you have jQuery included in your page? Are you getting any errors? Firefox is very good at showing all errors. I can't say the same for other browsers.