Bridging the gap to Fusion through our PeopleSoft Solutions Extenders
Grey Sparling PeopleSoft Expert's Corner
Oracle Blogs
 Subscribe Now!

Friday, June 23, 2006

Oracle-PeopleSoft Bloggers

I've known that Jesper Andersen has had a blog for awhile, but I just saw that Jim McGlothlin is blogging now. Getting sales executives blogging is pretty impressive. Jim's a good guy though. I can vouch for him :-)

You can find a complete list of Oracle blogs here. That includes executives and 3rd party blogs related to Oracle.

Although I don't see any submission form to get our blog listed. Hmm, maybe I'll have to ping Brian Duff (who started the whole Oracle blogging effort) about that.

Add a comment here to vote if we should be added to the 3rd party list of Oracle related weblogs (or if you think we shouldn't!).

Labels:

Tuesday, June 20, 2006

PeopleCode and C Integration

We've had blog posts on how integrating PeopleCode with various other languages before, but one of the things that I punted on previously was showing how to do really deep integration with C. Or more accurately, .DLLs/shared objects.

Strangely enough, I've actually had occasion recently to dig back into some of this for some work that we've been doing to integrate with another product. I'll spare you the details of that (for now - since the work isn't done yet :-), but I thought I'd share how the technical bits work. Most folks can feel safe to skip this entry - we're digging into the weeds here. But sometimes you have to really get your hands dirty to accomplish something (or so my wife says to me), so that's what we're going to do here.

In a nutshell, the problem that we're trying to solve is that when we want to access various functionality that is exposed in .DLL files (they're called shared objects on Linux/Unix, but I'm just going to refer to .DLL files here - the concepts translate well though) there are numerous occasions when the function that we're calling wants to deal with a structure (struct). The easiest way to think of a structure is that you have a single "thing" that has a bunch of fields in it.

Unfortunately, the integration that PeopleCode has for .DLLs does not support structures. What to do? Roll your own, of course!

To provide a concrete example that everyone can try on their own, I'm using the Windows API call for getting the local system time. The MSDN documentation (a great resource) shows that the GetLocalTime function returns a pointer to a SYSTEMTIME structure.

PeopleCode will support getting back the return pointer to the struct (it just ends up as a Number in PeopleCode), but we need to do some extra work to dig out the specific data values that we want. The trick is realizing that a struct is really all sequential in memory. So, since we know where the beginning of the struct is (from the return value) and we know the definition of the struct (from the doc), we can calculate how far away from the beginning of the struct the data that we want is. We can then use the Windows RtlMoveMemory function to grab the data from the appropriate place (we can also use this same function to write data into a struct, but here we're just reading data).

Let's take a look at some sample code.



We start off by declaring the actual Windows API functions that we're going to use to get our work done. This is all standard stuff and documented in PeopleBooks. The only wrinkle here is that we declare the RtlMoveMemory function with the name CopyPtrToInt so that we can leverage the existing PeopleCode infrastructure for passing data back and forth. In the other code that I'm working on, there are multiple "Declare Function" statements that all reference RtlMoveMemory with different names (CopyPtrToLong, CopyLongToPtr, etc).

Next we have a little function that just maps a word that describes a struct datatype (e.g. "long", "integer", "word", etc) with how many bytes that datatype will occupy. We need this so that if we want to, say, grab the 5th field from a struct, we know how many bytes in it starts.

We follow that with a function that exists purely for sanity checking our structure definitions in PeopleCode. When you call into .DLLs, there is practically no error handling, so if you pass it bad data, then you'll quickly get to meet Doctor Watson.

Next up is a function that will tell us how large our strucuture is. We need to know this for when we actually allocate memory for the structure. Speaking of which, allocation and deallocation of memory are what the next two function handle. Very important to always deallocate any memory that you allocate (which is why we have all of these wrapper functions), but you can only deallocate it once.

OK, we're in the home stretch in now. Only two more infrastructure functions define and then we can actually do something. The first one is used to know where inside a struct a "field" is. We need this so that we can access data in the struct by fieldname, while under the covers it gets mapped to a specific memory offset in the structure.

The last infrastructure function we need is something that will return an actual PeopleCode value to us from the structure. Whew! The demo code just has something to return an Integer. If the structure had other field types in it (Longs, Strings, etc. ), then you'd want to mimic this function for those data types.

Now we're finally down to the meat of it. Or the main course of it if you're a vegetarian. We're ready to define what our SYSTEMTIME structure is, allocate the memory for it, call the GetLocalTime API function, and display our results.

Our function creates two array definitions. One is the list of field names that are in the struct. These can actually be anything that you want to refer to the fields as, but it's always good to keep them somewhat in sync with whatever "C level" documentation that you have regarding the struct. The second array has the same number of values as the first array, but it is a list of all of the data types for each field in the first array. We combine these into a single array for passing around to all of our infrastructure functions, and then we're good to go.

When we run this program, we get output similar to "2006-6-20 14:36:16". A lot of work just to get the time, eh? True enough that there are better ways of getting the time, but there are lots of other uses for this type of strategy that it makes a nice example.

Ok, now it's time for Ketan or Chili Joe to catch any of my typos :-)

Labels:

Sunday, June 18, 2006

Fixing PeopleSoft Copy-URL for Firefox

We've been spending a lot of time on drilling features in our products. The nVision Drilling Snap-on is all about drilling, and we're working on a new product that will add drilling all over the online PeopleSoft pages. So we're constantly needing to dig up a complete URL to a PeopleSoft page (including the keys).



Like a lot of early web applications PeopleSoft 8 didn't do a very good job in letting you know what URL you needed to supply to get a user directly to a specific page. In between frames and a heavy reliance on using POST (which is a topic for some other day) it was pretty tricky to figure out.



So when PeopleSoft 8.4 came out in 2002 one of the things that was added automatically to the top right corner of each page was a link that would copy the URL for the current page to the clipboard.





You can see the same sort of thing done now on sites like Google Maps where they provide a "link to this page" link in top right corner of each page. Sof if you drag the map around or zoom in/out, you can get the direct URL to where you are I'm sure that there are other examples as well.



One minor problem with the way that the PeopleSoft link works is that it pulls in not just the keys needed to identify a single row in the component search, but it also pulls in alternate search keys as well.



For example, if you pull up VP1 on the User Profiles component and click on that link, then paste the URL from the clipboard somewhere where you can look at it, you'll see that the generated URL includes the DESCR field in it, along with OPRID. If the description of this user account ever changes (like someone getting married and changing their name), then the URL doesn't work anymore. Which is a real headache if you've mailed that URL to a bunch of people.



That's easy enough to work around by changing the generated URL before you do something like emailing it (pain that is), but if you're using Firefox and just tried to click that link and then paste the URL somewhere, you probably noticed that it didn't work.



The reason is that Internet Explorer allows JavaScript to access the clipboard by default and Firefox does not.



To turn on access temporarily in Firefox enter the URL about:config and hit Enter. This will bring up a huge list of settings. The one we want is called signed.applets.codebase_principal_support. Thankfully the settings dialog does type ahead searching so you only have to type a few characters to get to it. Once you find it, double click the entry to change it from it's default setting of False to True.



Now when you go back to the PeopleSoft page and try it again you'll find it works. Actually it prompts you about the current site trying to access the clipboard and ask you to grant access, which you'll want to allow. Security is always a good thing, even if it means an extra step in the process.



If you want to make this setting last between restarts of Firefox, then you'll need to update the Firefox prefs.js file, which stores your Firefox settings. This file lives in your Firefox profile directory.



An alternative to getting the full URL is to enable Notification support for the component. I'll write more about what Notifications (aka Ad-hoc Workflow) are in a future post. For now, the easiest way for you to test this out is to go to PeopleTools -> Workflow -> Notifications -> Generic Templates and pull up the system default template. You'll notice a Notify button down near the Save button. If you click this and take a look at the generated email, you'll see that the direct link to the component (with the proper key structure) is correctly generated.

The big drawback to this approach is that Notifications were not defaulted on in the 8.4 upgrade, so you have to update each component definition where you want this turned on (Component properties, Internet tab).

Labels: