<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-34020393</id><updated>2012-02-01T08:08:04.393-08:00</updated><category term='Cryptography'/><category term='proxy'/><category term='SQL'/><category term='PeopleBooks'/><category term='XP'/><category term='Encoding'/><category term='Calendar'/><category term='Regular Expressions'/><category term='Disgraceful conduct'/><category term='WorkCenters'/><category term='PL/SQL'/><category term='AppEngine'/><category term='Communities'/><category term='Bookmarklets'/><category term='Security'/><category term='Integration'/><category term='Oracle'/><category term='Meta-SQL'/><category term='iCalendar'/><category term='Ajax'/><category term='Strings'/><category term='Reporting'/><category term='Enterprise Portal'/><category term='Scripting'/><category term='XQuery'/><category term='Web server'/><category term='PSUnit'/><category term='AWE'/><category term='TDD'/><category term='Meta-HTML'/><category term='PeopleSoft'/><category term='IScripts'/><category term='e-mail'/><category term='book signing'/><category term='JSON'/><category term='Facebook'/><category term='Design Patterns'/><category term='PeopleTools'/><category term='File Attachment API'/><category term='Mobile'/><category term='jQuery'/><category term='CSS'/><category term='ServletFilters'/><category term='Test Driven Development'/><category term='REST'/><category term='Portal'/><category term='Application Classes'/><category term='formatting'/><category term='Logging'/><category term='XMPP'/><category term='XML'/><category term='Java'/><category term='Presentations'/><category term='Best Practices'/><category term='Google'/><category term='Dates'/><category term='Extreme Programming'/><category term='JDBC'/><category term='Templates'/><category term='Java Reflection'/><category term='Book Revisions'/><category term='log4j'/><category term='Pagelet Wizard'/><category term='Chat'/><category term='Conferences'/><category term='XPath'/><category term='Mix'/><category term='Meta-Data'/><category term='Tools'/><category term='PeopleCode'/><category term='Branding'/><category term='Monkeygrease'/><category term='DHTML'/><category term='JavaScript'/><category term='Books'/><title type='text'>Jim's PeopleSoft Journal</title><subtitle type='html'>A blog containing development tips I have learned through the years as a PeopleSoft developer.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default?start-index=101&amp;max-results=100'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>119</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-34020393.post-5871006180745879324</id><published>2011-10-23T21:49:00.000-07:00</published><updated>2011-10-23T22:00:48.347-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>REST-like PeopleSoft Services</title><content type='html'>&lt;p&gt;As you survey the consumer web service landscape, you will notice a shift: fewer SOAP based services and more REST based services. I will refrain from sharing my true feelings about WSDL and SOAP to share with you the important stuff: how you can make REST-like calls into PeopleSoft. If you are not familiar with REST, then I suggest you read the Wikipedia &lt;a href="http://en.wikipedia.org/wiki/Representational_state_transfer"&gt;&lt;u&gt;RE&lt;/u&gt;presentational &lt;u&gt;S&lt;/u&gt;tate &lt;u&gt;T&lt;/u&gt;ranfer&lt;/a&gt; summary and then follow some of the external links for additional details.&lt;p&gt;&lt;p&gt;While there are implementation differences, at its core, the difference between REST and SOAP is the focus. The focus of SOAP is the operation, not the data. The focus of REST is the data. I find this difference most evident when working with a Component Interface (CI). With a CI, you set key values, call Get (or Create), change values, and then call Save. The entire time you are working with that CI, you are working with a single transaction instance. The focus of the CI is the state of the data. The operations (get, create, save) are secondary. Service Operations are exactly opposite. Service Operations focus on method execution. The data (the transaction in this case) is just a parameter. OK, maybe this isn't the "core" of the REST specification, but as one who has tried working with a CI in a Web Service Data Control, it is enough for me to want to throw out web services. Don't misunderstand me at this point. I'm not blaming web services, the CI WSDL, or the Web Service Data Control. I'm sure they all have their place in development projects. It is my experience, however, that they mix together like chlorine bleach and ammonia (&lt;a href="http://answers.yahoo.com/question/index?qid=20061023171105AAMBfma"&gt;please, oh please don't mix these two chemicals!&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;There are several implementation details that differ between REST and SOAP. As a user interface (think Ajax) developer, my preferred implementation detail is the ability to call services with a URL as an HTTP GET or POST. Yes, you can make SOAP calls with JavaScript, but I find it a lot more difficult to package up a SOAP envelope with JavaScript than to just make an HTTP GET or POST with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;As noted by the Cedar Hills Group &lt;a href="http://www.cedarhillsgroup.com/knowledge-base/kbarticles/will-peoplesoft-support-rest-web-services"&gt;PeopleSoft REST Wiki&lt;/a&gt;, there is a lot more to REST than just URL's, and a true REST URL doesn't use Query Strings for parameters. If you want more REST, then you will have to wait for &lt;a href="https://support.oracle.com/CSP/main/article?cmd=show&amp;type=NOT&amp;doctype=REFERENCE&amp;id=1327656.1"&gt;PeopleTools 8.52&lt;/a&gt; or build something yourself (stand-alone REST gateway, MyRestListeningConnector, etc). If, like me, your greatest interest is executing Service Operation Handlers from URL's, then review the &lt;a href="http://download.oracle.com/docs/cd/E18083_01/pt851pbr0/eng/psbooks/tiba/htm/tiba14.htm#g37cff77f5a85d1f8_ef90c_113e48db06c__7e0f"&gt;PeopleBooks HTTP Listening Connector&lt;/a&gt;. It contains the URL call specification for PeopleSoft service operations. With an "Any to Local" routing, the basic form looks like this: http(s)://my.peoplesoft.server/PSIGW/HttpListeningConnector?Operation=EXECTHISOPERATION. If you prefer, you can pass transaction keys, etc as query string parameters, and then read those parameters in PeopleCode. Here is how (assuming &amp;MSG is the message parameter to your OnRequest handler):&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &amp;amp;connectorInfo &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;MSG.IBInfo.IBConnectorInfo;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;number&lt;/span&gt; &amp;amp;qsIndex &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;qsValue;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;For&lt;/span&gt; &amp;amp;qsIndex &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;1&lt;/span&gt; To &amp;amp;connectorInfo.GetNumberOfQueryStringArgs()&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&amp;amp;connectorInfo.GetQueryStringArgName(&amp;amp;qsIndex) &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;THE_QS_PARM_NAME&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;         &amp;amp;qsValue &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;connectorInfo.GetQueryStringArgValue(&amp;amp;qsIndex);&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-For&lt;/span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;No, I'm not fond of having to iterate over each query string argument either, but that is what the API requires. I packaged this up in a Query String helper class and create an instance of it for each request that uses query string arguments. Here is my Helper class:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;class&lt;/span&gt; IBQueryStringHelper&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; IBQueryStringHelper(&amp;amp;connectorInfo As IBConnectorInfo);&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; getParameterValue(&amp;amp;parameterName As &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt;) &lt;span class="syntax-KEYWORD2"&gt;Returns&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;private&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;instance&lt;/span&gt; IBConnectorInfo &amp;amp;m_connectorInfo;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-class&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; IBQueryStringHelper&lt;br /&gt;   &lt;span class="syntax-COMMENT3"&gt;/+&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;&amp;amp;connectorInfo&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;as&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;IBConnectorInfo&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;+/&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD4"&gt;%This&lt;/span&gt;.m_connectorInfo &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;connectorInfo;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-method&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; getParameterValue&lt;br /&gt;   &lt;span class="syntax-COMMENT3"&gt;/+&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;&amp;amp;parameterName&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;as&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;String&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;+/&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-COMMENT3"&gt;/+&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;Returns&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;String&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;+/&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;number&lt;/span&gt; &amp;amp;qsIndex &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;For&lt;/span&gt; &amp;amp;qsIndex &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;1&lt;/span&gt; To &amp;amp;m_connectorInfo.GetNumberOfQueryStringArgs()&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&amp;amp;m_connectorInfo.GetQueryStringArgName(&amp;amp;qsIndex) &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;parameterName) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;         &lt;span class="syntax-KEYWORD2"&gt;Return&lt;/span&gt; &amp;amp;m_connectorInfo.GetQueryStringArgValue(&amp;amp;qsIndex);&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-For&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD2"&gt;Return&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-method&lt;/span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;What about the result? Does it have to be XML? No. I have used two ways to create non-XML results from Integration Broker. The first is by creating a JSON response directly in PeopleCode. It is this use case that prompted me to write the &lt;a href="http://jjmpsj.blogspot.com/2010/04/json-encoding-in-peoplecode.html"&gt;PeopleCode JSONEncoder&lt;/a&gt;. A service operation handler can return non-XML by wrapping the result in a psnonxml attribute like this:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; Message &amp;amp;result_msg &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateMessage&lt;/span&gt;(Operation.MY_SERVICE_OPERATION, %IntBroker_Response);&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;json;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Do&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;some&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;processing&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;generate&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;json&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;response&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;nonXmlData &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;lt;?xml&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;version=&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;1.0&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;?&amp;gt;&amp;lt;data&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;psnonxml=&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;yes&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &amp;amp;json &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;]]&amp;gt;&amp;lt;/data&amp;gt;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; XmlDoc &amp;amp;doc &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateXmlDoc&lt;/span&gt;(&amp;amp;nonXmlData);&lt;br /&gt;   &lt;br /&gt;   &amp;amp;result_msg.SetXmlDoc(&amp;amp;doc);&lt;br /&gt;   &lt;span class="syntax-KEYWORD2"&gt;Return&lt;/span&gt; &amp;amp;result_msg;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The second method I use to create non-XML results is through a transformation. Using XSL, it is possible to transform an XML document into JSON -- although JSON-safe encoding might be more difficult.&lt;/p&gt;&lt;p&gt;If you use a debugging proxy (such as Fiddler) to inspect the results of an Integration Broker response, you will notice Integration Broker always returns the Content-Type header value &lt;code&gt;text/xml&lt;/code&gt;. Unfortunately, this means you have to help jQuery understand the results because it won't be able to determine the response type based on the Content-Type header. When PeopleTools 8.52 arrives at your office, you will be able to specify different MIME types. For now, I find it satisfactory to just set the $.ajax dataType parameter to "json." If you absolutely need to set the Content-Type header and don't have PeopleTools 8.52, then I suggest looking into a reverse proxy with header rewrite capabilities (Apache, for example).&lt;/p&gt;&lt;p&gt;No, unfortunately, this post didn't show you true REST. If you are choosing REST for Ajax because it is easier to make a URL based request to a REST service than to build a SOAP header to send to a Web Service (like me), then this post hopefully offers you enough information to get started. If you require more of the REST specification than I've shown here, then you will probably have to wait for PeopleTools 8.52.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5871006180745879324?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5871006180745879324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5871006180745879324' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5871006180745879324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5871006180745879324'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/10/rest-like-peoplesoft-services.html' title='REST-like PeopleSoft Services'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1095038380071108417</id><published>2011-10-20T23:22:00.000-07:00</published><updated>2011-10-24T09:06:50.166-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pagelet Wizard'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='Enterprise Portal'/><title type='text'>Slideshow News Publications</title><content type='html'>&lt;p&gt;This post follows my &lt;a href="http://jjmpsj.blogspot.com/2011/10/accordion-navigation-collections.html"&gt;Accordion Navigation Collections&lt;/a&gt; post and contains the XSL I used at OpenWorld to convert an Applications (formerly Enterprise) Portal news publication into a slideshow. The XSL assumes you have images associated with your news content. Even though the XSL and JavaScript will operate fine with images of different sizes, I recommend that each of the images used with this XSL be of the same size. Here is the XSL: &lt;a href="http://www.box.net/shared/4hcjoq89jbmfuxfztcmn"&gt;slideshow-hosted.xsl&lt;/a&gt;&lt;/p&gt;&lt;p&gt;All of the usual disclaimers apply. Don't trust anyone else's code -- Understand what it is doing before you use it. You take full responsibility for the code once you download it. Don't delegate your responsibility, especially to someone that offers you code for free.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I make no warranty regarding the use of this XSL.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Security Warning:&lt;/strong&gt; To make sure the XSL will work "out of the box," I pointed the JavaScript at &lt;a href="http://code.google.com/apis/libraries/"&gt;Google's hosted JavaScript API's&lt;/a&gt; and the &lt;a href="http://jquery.malsup.com/cycle/download.html"&gt;jQuery Cycle download site&lt;/a&gt;. Since this code is used on your enterprise home pages, I suggest you replace these references with references to your own site's versions of these libraries. The thought of allowing some external service to run code on my pages makes me a bit nervous.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1095038380071108417?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1095038380071108417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1095038380071108417' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1095038380071108417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1095038380071108417'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/10/slideshow-news-publications.html' title='Slideshow News Publications'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5752405218176279914</id><published>2011-10-05T00:03:00.000-07:00</published><updated>2011-10-05T00:03:13.067-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Book Revisions'/><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Changing the Search Page Operator</title><content type='html'>&lt;p&gt;I just posted about &lt;a href="http://jjmpsj.blogspot.com/2011/10/monkey-patching-peoplesoft.html"&gt;Monkey Patching&lt;/a&gt;, a technique used in chapter 7 of my book &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939/"&gt;PeopleTools Tips and Techniques&lt;/a&gt; to set the default search page operator on advanced search pages (Note: only 8.50 and later required Monkey Patching). As I was looking over the "Changing Search Operators" section of chapter 7, I noticed the code was missing a few lines (pages 293 - 296). Here is my revision:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-MARKUP"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt; &lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;type&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;=&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;text&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;/&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;javascript&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;C&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;style&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;include&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;protection&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;!&lt;/span&gt;window&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;apt&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;setSearchOp&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;    window&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;apt&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;setSearchOp &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL2"&gt;true&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;window&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;net&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;pt&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;8.50&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;$&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; originalContentLoader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; net&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;ContentLoader&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;        net&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;ContentLoader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;url&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;form&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;method&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onload&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onerror&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;params&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;contentType&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bAjax&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bPrompt&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;          &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; originalOnLoad &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; onload&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;          &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;name &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;#ICAdvSearch&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;            onload &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;typeof&lt;/span&gt; originalOnLoad &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;undefined&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;!&lt;/span&gt;originalOnLoad&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;                &lt;span class="syntax-LITERAL2"&gt;this&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;processXML&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;else&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;                originalOnLoad&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;call&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL2"&gt;this&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;br /&gt;              &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;The&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;value&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;for&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;&amp;quot;between&amp;quot;&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;is&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;9.&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Change&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;this&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;your&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;desired&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;search&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;operator&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;value.&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; newValue &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;9&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;              &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;The&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;name&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;of&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;search&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;key&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;field&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;is&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;APT_UI_SCRIPTS_MENUNAME.&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Generally&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;speaking,&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;PeopleSoft&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;creates&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;HTML&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;element&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;names&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;by&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;combining&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;record&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;and&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;field&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;names&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;with&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;an&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;underscore&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;as&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;in&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;RECORD_FIELD.&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Change&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;following&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;value&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;name&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;of&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;your&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;search&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;key&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;record_field&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; coll &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; $&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;select[name='APT_UI_SCRIPTS_MENUNAME$op']&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;coll&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;val&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;!&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; newValue&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;                coll&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;val&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;newValue&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;change&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;              &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;          &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;          &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;new&lt;/span&gt; originalContentLoader &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;url&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;form&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;method&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onload&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onerror&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;params&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;contentType&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bAjax&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bPrompt&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;window&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;jQuery&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;else&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;pt&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;8.4x,&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;$(document).ready&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;below&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;will&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;handle&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;pt&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;8.4x&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;span class="syntax-COMMENT2"&gt;//&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;just&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;in&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;case&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;advanced&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;is&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;initial&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;view&lt;/span&gt;&lt;br /&gt;    $&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;document&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;ready&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; newValue &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;9&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; coll &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; $&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;select[name='APT_UI_SCRIPTS_MENUNAME$op']&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;coll&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;val&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;!&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; newValue&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;        coll&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;val&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;newValue&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;change&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-MARKUP"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5752405218176279914?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5752405218176279914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5752405218176279914' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5752405218176279914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5752405218176279914'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/10/changing-search-page-operator.html' title='Changing the Search Page Operator'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total><georss:featurename>1800 Old Bayshore Hwy, Burlingame, CA, USA</georss:featurename><georss:point>37.6023496 -122.3706759</georss:point><georss:box>37.600777099999995 -122.37314339999999 37.6039221 -122.3682084</georss:box></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-637425766231312570</id><published>2011-10-04T23:49:00.000-07:00</published><updated>2011-10-04T23:49:47.676-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Monkey Patching PeopleSoft</title><content type='html'>&lt;p&gt;As a PeopleSoft developer responsible for upgrades and maintenance, I work extra hard up front to avoid changing delivered code. My potential reward is less work at patch, bundle, or upgrade time. One way I deliver new user interface features without modifying delivered code is by writing &lt;a href="http://en.wikipedia.org/wiki/Monkey_patch"&gt;Monkey Patches&lt;/a&gt;. &lt;a href="http://en.wikipedia.org/wiki/Monkey_patch"&gt;Monkey Patching&lt;/a&gt; is a term used with dynamic languages for modifying runtime behavior without changing design time code. Dynamic languages, such as JavaScript support this by allowing developers to override, extend, or even redefine objects and methods at runtime. Let me set up a scenario:&lt;/p&gt;&lt;p&gt;In PeopleTools 8.49 and earlier, I could tell when an action happened in a component (FieldChange, Save, Prompt, etc) by listening for the window load and unload and document ready events. PeopleTools 8.50, however, triggers these events through Ajax requests, which means the page state doesn't change. With 8.50, I had to find an alternative JavaScript mechanism for identifying these same actions, and the PeopleTools &lt;code&gt;net.ContentLoader&lt;/code&gt; JavaScript object seemed just the ticket. By wrapping this JavaScript object with my own implementation, I can hook into the PeopleTools Ajax request/response processing cycle. If you have &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; and PeopleTools 8.50 (or higher), then load up your User Profile component (/psc/ URL only) and run this JavaScript:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; originalContentLoader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; net&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;ContentLoader&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;  net&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;ContentLoader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;url&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;form&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;method&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onload&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onerror&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;params&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;contentType&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bAjax&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bPrompt&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;    console&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;log&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;new&lt;/span&gt; originalContentLoader &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;url&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;form&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;method&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onload&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onerror&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;params&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;contentType&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bAjax&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bPrompt&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Next, click on one of the prompt buttons on the user profile &lt;em&gt;General&lt;/em&gt; tab. You should see the name of the button you clicked appear in the Firebug console. Notice that the button name appears in the Firebug console before the Ajax HTTP Post. If you wanted to take action after the Ajax response, then you would implement your own onload handler like this:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; originalContentLoader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; net&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;ContentLoader&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;  net&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;ContentLoader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;url&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;form&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;method&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onload&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onerror&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;params&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;contentType&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bAjax&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bPrompt&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;    console&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;log&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; originalOnLoad &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; onload&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    onload &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;typeof&lt;/span&gt; originalOnLoad &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;undefined&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;!&lt;/span&gt;originalOnLoad&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax-LITERAL2"&gt;this&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;processXML&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;else&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;        originalOnLoad&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;call&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL2"&gt;this&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;      console&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;log&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;Ajax&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;response&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;received&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;new&lt;/span&gt; originalContentLoader &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;url&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;form&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;name&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;method&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onload&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;onerror&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;params&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;contentType&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bAjax&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;bPrompt&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Notice that the text "Ajax response received" appears after the HTTP post, meaning it executed after the page received the Ajax response.&lt;/p&gt;&lt;p&gt;When creating Monkey Patches, it is critical that you consider the original purpose of the overridden code. In this example we redefined the &lt;code&gt;net.ContentLoader&lt;/code&gt;, but maintained a pointer to the prior definition. It is possible that another developer may come after me and create another patch on net.ContentLoader. By maintaining a pointer to the &lt;code&gt;net.ContentLoader&lt;/code&gt;, as it was defined when my code ran, I ensure that each patch continues to function. In essence, I'm developing a chain of patches.&lt;/p&gt;&lt;p&gt;Monkey Patching has a somewhat less than desirable reputation, and for good reason. If allowed to grow, patches on patches can make a system very difficult to troubleshoot and maintain. Furthermore, if one patch is not aware of another patch, then it is entirely possible that a patch could be inserted in the wrong place in the execution chain, upsetting the desired order of patches.&lt;/p&gt;&lt;p&gt;"With great power comes great responsibility" (Voltaire, Thomas Francis Gilroy, Spiderman's Uncle Ben? Hard to say who deserves credit for this phrase). Use this Monkey Patching technique sparingly, and be careful.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-637425766231312570?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/637425766231312570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=637425766231312570' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/637425766231312570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/637425766231312570'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/10/monkey-patching-peoplesoft.html' title='Monkey Patching PeopleSoft'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>3</thr:total><georss:featurename>1800 Old Bayshore Hwy, Burlingame, CA, USA</georss:featurename><georss:point>37.6023496 -122.3706759</georss:point><georss:box>37.600777099999995 -122.37314339999999 37.6039221 -122.3682084</georss:box></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2155070796793666988</id><published>2011-10-03T23:20:00.000-07:00</published><updated>2011-10-24T09:07:04.638-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pagelet Wizard'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Accordion Navigation Collections</title><content type='html'>&lt;p&gt;A few months ago we released a White paper about &lt;a href="http://jjmpsj.blogspot.com/2011/04/pagelets-workcenters-etc-in-white-paper.html"&gt;PeopleSoft Applications Portal and WorkCenter Pages&lt;/a&gt; that showed screen shots of an accordion menu. A lot of you asked how we created these pagelets. Tomorrow in our OOW session &lt;a href="https://oracleus.wingateweb.com/scheduler/modifySession.do?SESSION_ID=14020"&gt;PeopleSoft Answers: How to Create a Great PeopleSoft UI&lt;/a&gt;, I will demonstrate creating the pagelet, but we won't have time to walk through the XSL -- the critical piece. For those of you that will be there (and those that won't but know how to use Pagelet Wizard), here is the XSL: &lt;a href="http://www.box.net/shared/fch5sixkv95ova3crsyb"&gt;accordion-nav-hosted.xsl&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I make no warranty regarding the use of this XSL.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Security Warning:&lt;/strong&gt; To make sure the XSL will work "out of the box," I pointed the JavaScript at &lt;a href="http://code.google.com/apis/libraries/"&gt;Google's hosted JavaScript API's&lt;/a&gt;. Since this code is used on your enterprise home pages, I suggest you replace these references with references to your own site's versions of these libraries. The thought of allowing some external service to run code on my pages makes me a bit nervous.&lt;/p&gt;&lt;p&gt;I have to point out a minor difference between the output of this XSL and the output shown in the white paper: This XSL opens links in the current window or a new window. It does not use modal dialogs. Navigation Collection XML contains absolute PSP URL's, which don't display well in a modal dialog. The version shown in the White paper actually uses a custom transformer and some PeopleCode to convert psp URL's into psc URL's for dialogs.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2155070796793666988?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2155070796793666988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2155070796793666988' title='33 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2155070796793666988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2155070796793666988'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/10/accordion-navigation-collections.html' title='Accordion Navigation Collections'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>33</thr:total><georss:featurename>1800 Old Bayshore Hwy, Burlingame, CA, USA</georss:featurename><georss:point>37.6023496 -122.3706759</georss:point><georss:box>37.600777099999995 -122.37314339999999 37.6039221 -122.3682084</georss:box></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3748722346860631039</id><published>2011-09-22T10:33:00.000-07:00</published><updated>2011-09-22T10:34:31.863-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Creating Binary Arrays</title><content type='html'>&lt;p&gt;Lately I have been using PeopleCode to manipulate binary files: moving files, copying files, and even creating zip files. A prerequisite for reading from and writing to binary files is the basic binary array -- the buffer.  My blog post &lt;a href="http://jjmpsj.blogspot.com/2009/05/base64-encoding-for-peoplesoft.html"&gt;Base64 Encoding for PeopleSoft&lt;/a&gt; demonstrated a very complicated method for creating binary files that worked with PeopleTools 8.49 and earlier, but does not work on my PeopleTools 8.51 systems. While studying PeopleBooks I found a much easier, well documented method for creating binary arrays:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;bytes &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;&lt;a href="http://download.oracle.com/docs/cd/E18083_01/pt851pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#4aa6e529_12cf5dc4902__62d8"&gt;CreateJavaArray&lt;/a&gt;&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;byte[]&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;1024&lt;/span&gt; &lt;span class="syntax-COMMENT1"&gt;/*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;length&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;of&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;array&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*/&lt;/span&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;For arrays with known values at construction time, you can use the &lt;a href="http://download.oracle.com/docs/cd/E18083_01/pt851pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#4aa6e529_12cf5dc4902__62aa"&gt;CreateJavaObject&lt;/a&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;bytes &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;byte[]&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;5&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;10&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;15&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;20&lt;/span&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Note: Since this is documented, I suspect these functions will work with PeopleTools 8.49 and earlier, but I haven't tested them on earlier PeopleTools versions. If this method won't work in PeopleTools 8.49 or earlier, then you are welcome to use the alternative:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;get&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;reference&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Java&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;class&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;instance&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;for&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;primitive&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;byte&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;array&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;arrayClass &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.reflect.Array&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;bytes &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;arrayClass.newInstance(&lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.Byte&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;).TYPE, &lt;span class="syntax-DIGIT"&gt;5&lt;/span&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;I would like to call out &lt;a href="http://www.blogger.com/profile/15566694434761468200"&gt;Kris&lt;/a&gt; who posted a comment on &lt;a href="http://jjmpsj.blogspot.com/2009/05/base64-encoding-for-peoplesoft.html"&gt;Base64 Encoding for PeopleSoft&lt;/a&gt; stating that the older method no longer worked. I happened to be working on zipping files with PeopleCode the week before Kris's comment and discovered the same issue and resolution. Very timely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3748722346860631039?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3748722346860631039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3748722346860631039' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3748722346860631039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3748722346860631039'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/09/creating-binary-files.html' title='Creating Binary Arrays'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-7098054172515020825</id><published>2011-09-21T22:43:00.000-07:00</published><updated>2011-09-21T22:47:17.587-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='book signing'/><title type='text'>OpenWorld Schedule 2011</title><content type='html'>I can hardly believe it. One more week at home and then I'm off to San Francisco for the biggest Oracle show of the year. I will be in San Francisco pretty much all week and would love to meet any of you that are attending. Here is where you will find me:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Monday 9:45 AM to 1:30 PM -- Integration Broker demo pod &lt;/li&gt;&lt;li&gt;Tuesday 9:45 AM to 12:00 PM -- Integration Broker demo pod&lt;/li&gt;&lt;li&gt;Tuesday 1:15 PM to 2:15 PM -- Session 14020 PeopleSoft Answers: How to Create a Great PeopleSoft UI (Moscone West 2024)&lt;/li&gt;&lt;li&gt;Tuesday 3:30 PM to 4:30 PM -- Session 14003 PeopleSoft PeopleTools Tips and Techniques (Moscone West 2022)&lt;/li&gt;&lt;li&gt;Wednesday 10:00 AM to 10:30 AM -- Meet the Authors @ the Moscone West bookstore (bring your book so I can sign it)&lt;/li&gt;&lt;li&gt;Wednesday 12:30 PM to 4:00 PM -- Integration Broker demo pod&lt;/li&gt;&lt;li&gt;Thursday 10:00 AM to 10:30 AM -- Meet the Authors @ the Moscone West bookstore (bring your book so I can sign it)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-7098054172515020825?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/7098054172515020825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=7098054172515020825' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/7098054172515020825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/7098054172515020825'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/09/openworld-schedule-2011.html' title='OpenWorld Schedule 2011'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>2</thr:total><georss:featurename>Moscone Center, 747 Howard St, San Francisco, CA 94103-3118, USA</georss:featurename><georss:point>37.783986 -122.40131</georss:point><georss:box>37.7714365 -122.42105099999999 37.7965355 -122.381569</georss:box></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1013107540596200066</id><published>2011-04-06T09:33:00.000-07:00</published><updated>2011-04-06T09:33:49.731-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='book signing'/><title type='text'>Collaborate 2011 Schedule and Book Signing</title><content type='html'>&lt;p&gt;Collaborate is only a couple of days away. If you are a reader, I'd love to meet you. Here are some times and places we can connect:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Monday, 5/11 6:00 PM - 8:00 PM -- Exhibition Hall PeopleTools demo pod.&lt;/li&gt;&lt;li&gt;Tuesday, 5/12 10:15 AM - 2:00 PM -- Exhibition Hall PeopleTools demo pod.&lt;/li&gt;&lt;li&gt;Tuesday, 5/12 3:15 PM - 4:15 PM -- Session 85680 PeopleTools 8.51 Highlights - PeopleTools in Action room 203B (Quest)&lt;/li&gt;&lt;li&gt;Tuesday, 5/12 4:30 PM - 5:00 PM -- Book signing at the Collaborate book store&lt;/li&gt;&lt;li&gt;Tuesday, 5/12 5:30 PM - 7:00 PM -- Exhibition Hall PeopleTools demo pod&lt;/li&gt;&lt;li&gt;Wednesday, 5/13 8:00 AM - 9:00 AM -- Session 85670 PeopleTools Tips and Techniques room 203A (Quest)&lt;/li&gt;&lt;li&gt;Wednesday, 5/13 10:15 AM - 4:00 PM -- Exhibition Hall PeopleTools demo pod&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;McGraw Hill was also able to schedule a special book signing event for Tuesday between 4:30 PM and 5:00 PM. Follow me down to the book store after my PeopleTools in Action session, buy a book, and I'll sign it for you. If I lose you, I've been told the bookstore is next to registration. See you there!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1013107540596200066?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1013107540596200066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1013107540596200066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1013107540596200066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1013107540596200066'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/04/collaborate-2011-schedule-and-book.html' title='Collaborate 2011 Schedule and Book Signing'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2706040594613720173</id><published>2011-04-05T15:08:00.000-07:00</published><updated>2011-04-06T15:09:21.077-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WorkCenters'/><category scheme='http://www.blogger.com/atom/ns#' term='Portal'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Pagelets, WorkCenters, etc in White Paper</title><content type='html'>Some of my friends from sales and product strategy just put together a very nice white paper on some of the new features in PeopleTools and Applications Portal (formerly known as Enterprise Portal). I created some of the content in the screen shots (home page layout, accordion navigation collections, slide show news publications, etc) and they did all the writing. Download a copy and see what you can do with your PeopleSoft application. The paper is titled &lt;a href="https://support.oracle.com/CSP/main/article?cmd=show&amp;type=NOT&amp;doctype=WHITE%20PAPER&amp;id=1311009.1"&gt;PeopleSoft Applications Portal and WorkCenter Pages&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2706040594613720173?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2706040594613720173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2706040594613720173' title='44 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2706040594613720173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2706040594613720173'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/04/pagelets-workcenters-etc-in-white-paper.html' title='Pagelets, WorkCenters, etc in White Paper'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>44</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-8457271392649457122</id><published>2011-04-04T22:36:00.000-07:00</published><updated>2011-04-04T22:39:13.260-07:00</updated><title type='text'>blogger.com's Views</title><content type='html'>&lt;p&gt;Have you seen blogger.com's new &lt;a href="http://buzz.blogger.com/2011/03/fresh-new-perspectives-for-your-blog.html"&gt;dynamic views&lt;/a&gt;? For my site, most aren't that exciting, but the &lt;a href="http://jjmpsj.blogspot.com/view/flipcard"&gt;flip card&lt;/a&gt; view for labels is pretty interesting. Rather than just seeing the usual label (count), you can see the actual titles under each label.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-8457271392649457122?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/8457271392649457122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=8457271392649457122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8457271392649457122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8457271392649457122'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/04/bloggercoms-views.html' title='blogger.com&apos;s Views'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-234105243047122208</id><published>2011-02-16T08:48:00.000-08:00</published><updated>2011-03-23T22:41:14.834-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>Alliance 2011</title><content type='html'>&lt;p&gt;I'm just finishing my demos for this year's &lt;a href="http://www.heug.org/p/cm/ld/fid=255"&gt;Alliance&lt;/a&gt; conference. I will present session 29321, PeopleTools Tips and Tricks, on Monday morning from 9:30 to 10:30 in Korbel 4A-C. In this session I will present some mobile, mashup, and ajax solutions as well as tips for debugging these client/server HTTP interactions. On Tuesday, I will show you some of the new PT 8.50/51 features during the session 29332 "PeopleTools 8.51 in Action" at 12:45 in Korbel 4A-C.&lt;/p&gt;&lt;p&gt;If you are not able to attend these sessions, then please feel free to chat with me in the Exhibition Hall or at Meet the Experts. I will be in the Exhibition Hall Sunday from 5:30 to 8:30, Monday from 12:45 to 2:15, and again on Tuesday from 12:30 to 2:15. I will be at the Meet the Experts PeopleTools table on Monday from 4:30 to 5:30 and on Tuesday from 9:30 to 10:30.&lt;/p&gt;&lt;p&gt;I can't wait to see you there!!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-234105243047122208?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/234105243047122208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=234105243047122208' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/234105243047122208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/234105243047122208'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/02/alliance-2011.html' title='Alliance 2011'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5798618804251773387</id><published>2011-02-10T12:21:00.000-08:00</published><updated>2011-02-10T12:22:22.109-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Meta blog</title><content type='html'>&lt;p&gt;JavaScript is a critical component of PeopleSoft applications. With the web browser pretty much taking over as the rendering engine for enterprise applications, I see JavaScript as a critical language for computer professionals. Of course, technologies like PeopleTools and ADF contain abstraction layers so application developers do not have to write JavaScript, but, in the end, someone has to write the JavaScript generated by those abstraction layers. And, if something goes wrong, odds are very good you will have to dig through the generated JavaScript to see what went wrong (where, when, why, etc).&lt;/p&gt;&lt;p&gt;Anyway, I think JavaScript is one of the most important modern languages a programmer can learn, and I know I'm not alone in this opinion. Of late, I've found some very interesting online resources for people interested in learning JavaScript, so I wrote this post to pass those resources along to PeopleSoft developers.&lt;/p&gt;&lt;p&gt;I will maintain this as a "Meta-blog" post and update it as I find more resources. I will attempt to keep the list short, so you don't have to sift through thousands of irrelevant tutorials. Restated: this is not a complete list. It is just a short list of tutorials that I think stand above the rest.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://eloquentjavascript.net/"&gt;Eloquent JavaScript&lt;/a&gt; &lt;em&gt;Beginner&lt;/em&gt; This is a very well done, hands on JavaScript tutorial. It is released under the Creative Commons license so you can download it and run the tutorials from your laptop while traveling, etc.&lt;/li&gt;&lt;li&gt;&lt;a href="http://bonsaiden.github.com/JavaScript-Garden/"&gt;JavaScript Garden&lt;/a&gt; The &lt;em&gt;Quirky&lt;/em&gt; parts of JavaScript&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth"&gt;The JavaScript Module Pattern&lt;/a&gt; &lt;em&gt;Advanced&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://phrogz.net/js/classes/OOPinJS.html"&gt;OOP in JS, Part 1 : Public/Private Variables and Methods&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://phrogz.net/js/classes/OOPinJS2.html"&gt;OOP in JS, Part 2 : Inheritance&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5798618804251773387?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5798618804251773387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5798618804251773387' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5798618804251773387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5798618804251773387'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2011/02/javascript-meta-blog.html' title='JavaScript Meta blog'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-7088796906896311438</id><published>2010-09-29T10:41:00.000-07:00</published><updated>2010-09-29T10:53:33.182-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Presentations'/><title type='text'>OOW 2010 Presentations Available</title><content type='html'>&lt;p&gt;Oracle OpenWorld OnDemand is now available and includes slides and audio for each of the sessions in which I presented. Here are the OnDemand links:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://openworld.vportal.net/?cid=8491"&gt;PeopleTools Tips and Tricks&lt;/a&gt; &lt;em&gt;Slides and Audio&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://openworld.vportal.net/?cid=9108"&gt;PeopleSoft PeopleTools Developer Series: Building a Custom Mobile Application&lt;/a&gt; &lt;em&gt;Slides&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://openworld.vportal.net/?cid=9137"&gt;Monster Mashups: Related Content in PeopleSoft Applications&lt;/a&gt; &lt;em&gt;Audio&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you were not able to attend OpenWorld 2010, you can &lt;a href="http://www.eventreg.com/oracle/openworld2010/sanfrancisco/ondemand_nonattendee/"&gt;purchase OnDemand here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-7088796906896311438?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/7088796906896311438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=7088796906896311438' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/7088796906896311438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/7088796906896311438'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/09/oow-2010-presentations-available.html' title='OOW 2010 Presentations Available'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2796556383762827347</id><published>2010-09-23T21:23:00.000-07:00</published><updated>2010-09-23T21:23:30.536-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Integration'/><title type='text'>Going Mobile with PeopleSoft</title><content type='html'>&lt;p&gt;Chapter 14 of my &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939"&gt;PeopleTools Tips &amp;amp; Techniques&lt;/a&gt; book walks you step-by-step through creating a mobile application. That chapter uses a CI based web service and Oracle ADF to demonstrate some of the &lt;em&gt;simple&lt;/em&gt; drag-and-drop tools provided by Oracle. Even though the technique demonstrated appears simple, if you start to dig into the generated code and try to work directly with the Web Service Data Control, you will quickly see that JDeveloper does a very, very good job of hiding the real complexities behind web services. For this year's OpenWorld, I wanted to show just how simple it could be to create a mobile app for PeopleSoft. For my prototype, I chose to build a mobile worklist out of plain HTML, JavaScript, and CSS (it seems to me that plain HTML, JavaScript, and CSS is about as simple as web development gets). Without a server side technology like JDeveloper's ADF and JSF, I knew my mobile app would have to communicate with PeopleSoft using &lt;a href="http://en.wikipedia.org/wiki/Ajax_(programming)"&gt;Ajax&lt;/a&gt;. As it turns out, most modern mobile browsers support &lt;a href="http://en.wikipedia.org/wiki/XMLHttpRequest"&gt;XHR&lt;/a&gt; (as of BlackBerry 6, &lt;a href="http://www.engadget.com/2010/08/04/blackberry-torch-review/"&gt;Torch&lt;/a&gt;, the BlackBerry browser is now WebKit - YEAH!!!), but I knew having a good mobile JavaScript library like &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt; would certainly help. A quick google search turned up &lt;a href="http://xuijs.com/"&gt;xuijs&lt;/a&gt;, which happens to be modeled after jQuery. Using &lt;a href="http://www.jedit.org"&gt;jEdit&lt;/a&gt;, my favorite syntax highlighting text editor, I prototyped the user interface, substituting Ajax URL's for local text files. After ironing out the server side requirements, I set about creating the Integration Broker App Class synchronous request handlers that my app would require. To make my HTML and JavaScript as simple as possible, I wrote my handlers to return data in &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt; and &lt;a href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/"&gt;JSONP&lt;/a&gt; format. While my JavaScript and PeopleCode may prove to be of some interest to you, I believe the most important concept from this exercise is the mechanism for calling Integration Broker from Ajax. To execute a web service from an HTTP GET (basic Ajax in &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt;-like fashion), you use a URL similar to:&lt;/p&gt;&lt;pre&gt;http://your.peoplesoft.server/PSIGW/HttpListeningConnector?Operation=YOUR_OPERATION_NAME.v1&amp;OperationType=Sync&lt;/pre&gt;&lt;p&gt;Calling any service operation implies, of course, that you have a message, service, service operation, handler, and an any-to-local routing.&lt;/p&gt;&lt;p&gt;My point for sharing this is that we easily forget how simple an application can be. PeopleTools provides the integration architecture. It is up to us to pick a language we are comfortable developing with. If your organization prefers .Net over Java, then write your web based mobile app in .Net. The language doesn't matter. Pretty much any language can make an HTTP request to the Integration Broker and then process the response. The keys are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Knowing how to call Integration Broker&lt;/li&gt;&lt;li&gt;Remembering that the mobile device has a much smaller screen&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That is about all there is to building mobile applications. Pretty simple... right?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2796556383762827347?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2796556383762827347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2796556383762827347' title='51 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2796556383762827347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2796556383762827347'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/09/going-mobile-with-peoplesoft.html' title='Going Mobile with PeopleSoft'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>51</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1851448988138045099</id><published>2010-09-23T20:05:00.000-07:00</published><updated>2010-09-23T20:20:05.373-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='IScripts'/><title type='text'>Posting Data to IScripts</title><content type='html'>&lt;p&gt;If you are a regular reader, you already know that I am a big fan of &lt;a href="http://en.wikipedia.org/wiki/Ajax_(programming)"&gt;Ajax&lt;/a&gt;. Most of my PeopleSoft Ajax requests use HTTP GET operations to send query string parameters to &lt;a href="http://jjmpsj.blogspot.com/2008/02/what-is-iscript.html"&gt;iScripts&lt;/a&gt;. I have considered using POST to send structured data to iScripts (XML, JSON, etc), but have not found reason to do so. Considering my background in other web based languages, I just assumed the &lt;code&gt;%Request&lt;/code&gt; object provided direct access to posted content. I didn't really look until I saw an IT Toolbox forum question from &lt;a href="http://it.toolbox.com/people/kcweaver/"&gt;KCWeaver&lt;/a&gt; asking how to post data to an iScript. The &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcr/htm/tpcr21.htm#4806ce6b_12acea27531_2397"&gt;Request&lt;/a&gt; object does have a &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcr/htm/tpcr21.htm#4806ce6b_12acea27531_2413"&gt;&lt;code&gt;GetContentBody()&lt;/code&gt;&lt;/a&gt; method that will return POST'd data. What PeopleBooks doesn't tell you is how to activate the &lt;code&gt;GetContentBody&lt;/code&gt; method (Note: I don't think this is an oversight. I think it is because GetContentBody is designed for Business Interlinks, not for iScripts). Special thanks to Kevin for digging through the documentation and figuring out how to POST to an iScript. The trick is to add &lt;code&gt;postDataBin=y&lt;/code&gt; to the end of your query string.&lt;/p&gt;&lt;p&gt;View the full IT Toolbox thread here: &lt;a href="http://peoplesoft.ittoolbox.com/groups/technical-functional/peopletools-l/ajax-to-iscript-3230064"&gt;AJAX to iScript&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1851448988138045099?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1851448988138045099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1851448988138045099' title='28 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1851448988138045099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1851448988138045099'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/09/posting-data-to-iscripts.html' title='Posting Data to IScripts'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>28</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-6279421378405009063</id><published>2010-09-23T11:39:00.000-07:00</published><updated>2010-09-23T19:18:25.689-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='AWE'/><title type='text'>PeopleTools Tips Sample Chapter Available</title><content type='html'>&lt;p&gt;Are you still trying to decide whether or not to buy my new PeopleTools book? Would a sample chapter help? The &lt;a href="http://www.mhprofessional.com/product.php?cat=7&amp;isbn=0071664939"&gt;McGraw Hill page for this book&lt;/a&gt; allows you to download &lt;a href="http://www.mhprofessional.com/downloads/products/0071664939/0071664939_chap03.pdf"&gt;chapter 3&lt;/a&gt; for free. Chapter 3 contains step by step instructions for workflow enabling a transaction using the relatively new Approval Workflow Engine (new in PeopleTools 8.48). If you have ever had trouble configuring AWE and wondered if it was possible to trace the stage, step, path, approver selection information, you will want to take a look at the &lt;strong&gt;Tracing AWE&lt;/strong&gt; sidebar on page 125 (page 35 of the PDF).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-6279421378405009063?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/6279421378405009063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=6279421378405009063' title='43 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6279421378405009063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6279421378405009063'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/09/peopletools-tips-sample-chapter.html' title='PeopleTools Tips Sample Chapter Available'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>43</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3701412443151027352</id><published>2010-09-18T09:19:00.000-07:00</published><updated>2010-09-18T09:46:26.832-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>PeopleTools Tips at OpenWorld</title><content type='html'>&lt;p&gt;I have checked in at my local airport and am en route to OpenWorld, the largest tech conference of the year. I'm pretty well finished preparing my demos for this year's session, and am using this time to finish my slides. I am very pleased with my demos this year as I think they demonstrate some very powerful ways to enhance PeopleSoft applications. Two of my primary topics for this year are Mashups and Mobile. I see Mashups as an alternative to Integration. Of course, you still need integrations, but whenever possible, I look for a Mashup alternative because Mashups general don't require modifications. In this session I will present some Mashup ideas and ways to ensure security.&lt;/p&gt;&lt;p&gt;Mobile... I find mobile to be one of the most fascinating ideas. I work remote (no office), and, therefore, am 100% mobile (at least in theory). PeopleTools has been relatively silent in regards to mobile. PeopleSoft Applications have built some very exciting mobile apps (see Theresa's &lt;a href="http://blogs.oracle.com/FinancialsMkting/2010/08/oracle_ireceipts_you_tube_vide.html"&gt;blog post and video&lt;/a&gt;), but PeopleTools is silent. After reviewing a handful of mobile development strategies, I am actually quite pleased with the mobile development solutions available to PeopleSoft customers. I'm finding that even though PeopleTools is silent in regards to mobile, the PeopleTools architecture lends itself very well to mobile development. In my PeopleTools Tips session on Monday I will demonstrate two separate mobile applications. The first is a mobile employee directory built using ADF and the web service data control. The second application uses plain old JavaScript and HTML to display a mobile worklist. This second application excites me the most because it shows that mobile development can be simple - No SOAP, no WSDL, no frameworks, no data bindings... just plain JavaScript, CSS, HTML, and PeopleCode.&lt;/p&gt;&lt;p&gt;Besides mobile and mashups, I also included:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Monkey_patch"&gt;Monkeypatching&lt;/a&gt; - what is it and how can I/why would I use it?&lt;/li&gt;&lt;li&gt;Debugging integrations - tools that facilitate debugging.&lt;/li&gt;&lt;li&gt;Pagelet Wizard - what is it, how can I use it, how can I extend it?&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;See you Monday at 5:00 PM in the Marriott, Golden Gate A (session id S317016). You won't be disappointed!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3701412443151027352?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3701412443151027352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3701412443151027352' title='42 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3701412443151027352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3701412443151027352'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/09/peopletools-tips-at-openworld.html' title='PeopleTools Tips at OpenWorld'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>42</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3957606246768846599</id><published>2010-09-10T14:16:00.000-07:00</published><updated>2010-09-10T14:31:43.327-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleTools'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleBooks'/><title type='text'>PeopleTools 8.51 Now Generally Available</title><content type='html'>&lt;p&gt;PeopleTools 8.51 is now Generally Available (meaning, you can download it from &lt;a href="http://edelivery.oracle.com"&gt;eDelivery&lt;/a&gt;). You can find the hosted PeopleBooks for 8.51 &lt;a href="http://download.oracle.com/docs/cd/E18083_01/pt851pbr0/eng/index.htm"&gt;here&lt;/a&gt;. The PeopleTools 8.51 documentation home is &lt;a href="https://support.oracle.com/CSP/main/article?cmd=show&amp;type=NOT&amp;id=1127534.1"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3957606246768846599?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3957606246768846599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3957606246768846599' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3957606246768846599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3957606246768846599'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/09/peopletools-851-now-generally-available.html' title='PeopleTools 8.51 Now Generally Available'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1266946758304304112</id><published>2010-09-07T13:16:00.000-07:00</published><updated>2010-09-07T14:50:56.753-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Best Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>URL Administration (Nodes and URL Definitions)</title><content type='html'>&lt;p&gt;I use URL's quite extensively for Ajax and other non-Integration Broker integrations (NEVER HARD CODE URL'S!). PeopleTools provides a couple of ways to store URL information. The most well-known of these features is the URL definition (PeopleTools &amp;gt; Utilities &amp;gt; Administration &amp;gt; URLs). URL Definitions are great for relative URL's, but I'm not fond of storing fully qualified URL's in this manner. Here is why...&lt;/p&gt;&lt;blockquote&gt;Imagine having 5 URL's that point to different resources on the same server and then one day the server's host name changes. Because of this change I have to modify 5 URL definitions. What if I forget one?&lt;/blockquote&gt;&lt;p&gt;An alternative is to store the base URL in a node definition and then the relative portion of the URL in a URL definition. Creating a fully qualified URL in this manner requires concatenating two definitions: the node URI and the URL definition. Next Question: How do I access these Meta-data objects from PeopleCode? Most of us are familiar with the &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#_4fb753ec_12575645bf8__330a"&gt;&lt;code&gt;GetURL&lt;/code&gt;&lt;/a&gt; PeopleCode function, but what mechanism does PeopleCode offer for retrieving a node's Content and Portal URI?&lt;/p&gt;&lt;p&gt;A PeopleSoft instance's node definitions are accessible through the &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#_4fb753ec_12575645bf8_1742"&gt;&lt;code&gt;%Session&lt;/code&gt;&lt;/a&gt; object. The &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcr/htm/tpcr39.htm#_5b517acc_1257564101a__f18"&gt;&lt;code&gt;Session&lt;/code&gt;&lt;/a&gt; object contains a method named &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcr/htm/tpcr30.htm#_5b517acc_1257563c1ac_7b30"&gt;&lt;code&gt;GetNodes&lt;/code&gt;&lt;/a&gt; which returns a collection of the instance's node definitions. A call to the collections &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcr/htm/tpcr30.htm#_5b517acc_1257564101a__7d43"&gt;&lt;code&gt;FindItemByName&lt;/code&gt;&lt;/a&gt; method returns a reference to a single node, which, of course, has properties of its own. Putting this all together, returning the Portal URI of a node named UCM would require PeopleCode that looks something like:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;serverUrl &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD4"&gt;%Session&lt;/span&gt;.GetNodes().ItemByName(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;UCM&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;).PortalURI;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;By centralizing the base portion of the URL in a node definition, we save some administration overhead.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1266946758304304112?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1266946758304304112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1266946758304304112' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1266946758304304112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1266946758304304112'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/09/url-administration-nodes-and-url.html' title='URL Administration (Nodes and URL Definitions)'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3702698440470442198</id><published>2010-08-31T14:23:00.002-07:00</published><updated>2010-08-31T14:55:37.432-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>OpenWorld in Two Weeks!</title><content type='html'>&lt;p&gt;OpenWorld is almost here! In less than 3 weeks, we will all be together again for the biggest Oracle apps and technology reunion of the year... and possibly, the biggest ever, with JavaOne and Oracle Develop co-located with OpenWorld.&lt;/p&gt;&lt;p&gt;This year I am teaming up with my good friend &lt;a href="http://i-like-trains.blogspot.com/"&gt;Graham Smith&lt;/a&gt; to deliver the "best of" PeopleTools Tips for 2010. Expect to see more PeopleTools 8.50 content in our presentation this year. Graham and I will be on stage Monday evening from 5:00 PM to 6:00 PM at the Marriott Golden Gate A (session id S317016). You will NOT want to miss this session!&lt;/p&gt;&lt;p&gt;On Thursday you can see Matthew, Pramod, and myself present &lt;i&gt;Monster Mashups&lt;/i&gt;, a session about creating mashups using the PeopleTools 8.50 related content framework. That session will be held at Moscone West room 2014 from 12:00 PM to 1:00 PM (session ID S317448).&lt;/p&gt;&lt;p&gt;Besides these sessions, I'll be working the PeopleTools Integration Tools demo pod Monday morning and all of Tuesday. Later during the week, however, I hope to spend some time in the Fusion Apps UI demo pod.&lt;/p&gt;&lt;p&gt;On Wednesday I plan to spend a half hour at the Oracle Bookstore signing copies of my new book. I will be there from 10:00 AM to 10:30 AM during the &lt;i&gt;Meet the Authors&lt;/i&gt; time slot. If you have a copy of my &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939"&gt;book&lt;/a&gt;, bring it with you so I can sign it! If you don't have a copy, I'm sure the Oracle bookstore will be more than happy to sell you a copy. &lt;i&gt;Meet the Authors&lt;/i&gt; actually runs Monday, Tuesday, and Wednesday from 10:00 AM to 10:30 AM, but I have demo grounds responsibilities Monday and Tuesday, so I won't be able to attend the first two days.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3702698440470442198?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3702698440470442198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3702698440470442198' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3702698440470442198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3702698440470442198'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/08/openworld-in-two-weeks.html' title='OpenWorld in Two Weeks!'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5306871578924447303</id><published>2010-08-20T10:29:00.000-07:00</published><updated>2010-08-20T10:33:53.822-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Get Your Kindle Copy</title><content type='html'>&lt;p&gt;The Kindle edition of my PeopleTools Tips and Techniques book is now available. Download a copy from Amazon's site &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Tips-Techniques-ebook/dp/B003XVYE8M/"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5306871578924447303?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5306871578924447303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5306871578924447303' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5306871578924447303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5306871578924447303'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/08/get-your-kindle-copy.html' title='Get Your Kindle Copy'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-332374703951480379</id><published>2010-07-22T11:34:00.000-07:00</published><updated>2010-07-22T11:38:13.154-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>The Code is now Available!</title><content type='html'>&lt;p&gt;The code for my new book &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939"&gt;PeopleSoft PeopleTools Tips &amp;amp; Techniques&lt;/a&gt; is now available. There is a download link on the book's &lt;a href="http://www.mhprofessional.com/product.php?cat=7&amp;isbn=0071664939"&gt;McGraw Hill page&lt;/a&gt;. Look for the &lt;a href="http://www.mhprofessional.com/downloads/products/0071664939/0071664939_code.zip"&gt;Downloads&lt;/a&gt; section. Enjoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-332374703951480379?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/332374703951480379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=332374703951480379' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/332374703951480379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/332374703951480379'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/07/code-is-now-available.html' title='The Code is now Available!'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-911953167895474059</id><published>2010-07-19T09:19:00.001-07:00</published><updated>2010-07-19T09:37:25.289-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Disgraceful conduct'/><title type='text'>Comment Moderation is now On</title><content type='html'>&lt;p&gt;Sigh... I really didn't want to enable comment moderation. When I post to a blog with comment moderation, I always wonder if my comment will appear. I also like to see my comments appear immediately. What if the moderator is on vacation? Unfortunately, I find myself in a position where I HAVE to enable comment moderation. Some organization has been posting pornographic links as comments on my blog and has been doing this for about six months. I have been diligent in deleting those comments, but then it occurred to me that each subscriber to a post was receiving these links as unsolicited e-mail. I WILL NOT ALLOW ANYONE TO MOLEST MY READERS IN THIS MANNER! I find it utterly distasteful and disgraceful. If someone wants to view pornography, that is their business, but I will not allow my blog to be used to tempt/lure people into pornography. The temptation is too much for some to handle. Just as alcoholism, gambling addiction, or many other social ills start as harmless entertainment, pornography can get way out of hand.&lt;/p&gt;&lt;p&gt;If you have been trapped by one of the e-mail comments sent from my blog and need help, I want to provide you with some resources. I think it is the least I can do. I have no experience in this issue, so I'm just listing what I googled on the topic: &lt;a href="http://www.troubledwith.com/AbuseandAddiction/PornographyCybersex.cfm"&gt;Abuse and Addiction: Pornography and Cybersex&lt;/a&gt; and &lt;a href="http://www.dads.org/strugglewithporn.asp"&gt;Dads.org&lt;/a&gt;.&lt;p&gt;Yes, you can still post comments on my blog. I really, really enjoy reading and responding to comments. I learn a lot from my readers. The unfortunate side affect of this parasite is that you will have to wait for me to read and approve your comments before they appear on this site. I really apologize for this. I wish there was something else I could do.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-911953167895474059?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/911953167895474059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=911953167895474059' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/911953167895474059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/911953167895474059'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/07/comment-moderation-is-now-on.html' title='Comment Moderation is now On'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-7727481348405558384</id><published>2010-07-14T13:17:00.000-07:00</published><updated>2010-09-15T10:16:09.101-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>The Book is Shipping, but Where is the Code?</title><content type='html'>&lt;p&gt;Amazon has been shipping my new &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939"&gt;PeopleTools&lt;/a&gt; book for about a week now... but where is the source code? The honest truth? It is on my laptop. I am in the process of exporting the code from my test PeopleSoft instance. I am up to chapter 9. I am averaging about 2 chapters a night, so I expect to finish this week. Once I finish, I'll send it to Oracle Press and they will post it on their web site at &lt;a href="http://www.oraclepressbooks.com/"&gt;http://www.oraclepressbooks.com/&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update 15-July-2010:&lt;/b&gt; I sent the code to the publisher last night. It is now in their production department awaiting posting. I will update again when it is available.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; The code is now available. You can find information in &lt;a href="http://jjmpsj.blogspot.com/2010/07/code-is-now-available.html"&gt;this blog post&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-7727481348405558384?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/7727481348405558384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=7727481348405558384' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/7727481348405558384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/7727481348405558384'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/07/book-is-shipping-but-where-is-code.html' title='The Book is Shipping, but Where is the Code?'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5240372956992886710</id><published>2010-06-21T04:55:00.000-07:00</published><updated>2010-06-21T05:04:25.219-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>At UKOUG With a Copy of My New Book</title><content type='html'>&lt;p&gt;I am presenting at the &lt;a href="http://peoplesoft.ukoug.org/"&gt;PeopleSoft UKOUG&lt;/a&gt; conference this week. It is always a pleasure to catch up with my English and European colleagues. I was able to acquire an advanced copy of my new book &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939"&gt;PeopleSoft PeopleTools Tips &amp;amp; Techniques&lt;/a&gt;. I will have the book with me during the conference, and will gladly show it to anyone who asks.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5240372956992886710?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5240372956992886710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5240372956992886710' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5240372956992886710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5240372956992886710'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/06/at-ukoug-with-copy-of-my-new-book.html' title='At UKOUG With a Copy of My New Book'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-733139154592787170</id><published>2010-06-08T10:42:00.000-07:00</published><updated>2010-06-08T10:43:48.969-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Marketing Flyer for PeopleTools Tips Book</title><content type='html'>&lt;p&gt;The marketing flyer for my &lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939"&gt;PeopleSoft PeopleTools Tips and Techniques&lt;/a&gt; book is now available. If you are unable to see the embedded flyer below, you can download a copy from my box.net account: &lt;a href="http://www.box.net/jimjmarion/1/30443306/446867924"&gt;PeopleTools Tips and Techniques flyer&lt;/a&gt;.&lt;/p&gt;&lt;embed src="http://www.box.net/embed/rl5kkocrv3sva44.swf" width="466" height="400" wmode="opaque" type="application/x-shockwave-flash" allowFullScreen="true" allowScriptAccess="always"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-733139154592787170?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/733139154592787170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=733139154592787170' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/733139154592787170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/733139154592787170'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/06/marketing-flyer-for-peopletools-tips.html' title='Marketing Flyer for PeopleTools Tips Book'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-4987799284050323574</id><published>2010-05-22T14:27:00.000-07:00</published><updated>2010-05-22T14:27:10.871-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleTools'/><category scheme='http://www.blogger.com/atom/ns#' term='Enterprise Portal'/><title type='text'>Enable View Source in Online HTML Editor</title><content type='html'>&lt;p&gt;If you use the Pagelet Wizard or Enterprise Portal's Managed Content features, then you have likely seen the PeopleTools online rich text editor. With PeopleTools 8.50, PeopleSoft switched to the &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt; and added rich text editor configuration options to App Designer. This allows you to turn any long text field into a rich text field (although I don't recommend doing so, as it can have a negative impact on reporting).&lt;/p&gt;&lt;p&gt;The former rich text editor had a &lt;em&gt;view source&lt;/em&gt; button. For security reasons, the PeopleTools team removed the view source button from this release. If you trust the users that have access to rich text editor pages (like the pagelet wizard) and would like to re-enable the view source button, then add &lt;code&gt;'Source','-',&lt;/code&gt; to the &lt;code&gt;config.toolbar&lt;/code&gt; array in your rich text editor configuration. Here is a fragment of the configuration file:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;        config&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;toolbar &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;'&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;Source&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;'&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;'&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;-&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;'&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;'&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;Maximize&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;'&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Where do you find your rich text editor's configuration? The PeopleBooks appendix &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tapd/book.htm?File=tapd/htm/tapd32.htm"&gt;Creating Custom Plug-in Files for the Rich Text Editor&lt;/a&gt; describes how to configure rich text editors on a per-page, per-editor basis. To change the default configuration, open the ckeditor/config.js file in your webserver's domain directory. For example, if your web server domain is named portal, open $PS_HOME/webserv/portal/applications/peoplesoft/PORTAL.war/portal/ckeditor/config.js.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-4987799284050323574?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/4987799284050323574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=4987799284050323574' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4987799284050323574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4987799284050323574'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/05/enable-view-source-in-online-html.html' title='Enable View Source in Online HTML Editor'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-4425416771175378922</id><published>2010-05-22T13:49:00.001-07:00</published><updated>2010-05-22T14:05:45.483-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Accessing PeopleCode Rowsets from Java</title><content type='html'>&lt;p&gt;A reader recently asked how to create instances of the &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr34.htm#d0e128760"&gt;Rowset&lt;/a&gt; class from Java. I believe the question was more about IDE and classpath setup than it was about actual Java code. But, since it can be difficult to figure out how to use PeopleCode objects in Java, I thought I would post an example:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD2"&gt;package&lt;/span&gt; test.peoplecode;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD2"&gt;import&lt;/span&gt; PeopleSoft.PeopleCode.Func;&lt;br /&gt;&lt;span class="syntax-KEYWORD2"&gt;import&lt;/span&gt; PeopleSoft.PeopleCode.Name;&lt;br /&gt;&lt;span class="syntax-KEYWORD2"&gt;import&lt;/span&gt; PeopleSoft.PeopleCode.Rowset;&lt;br /&gt;&lt;br /&gt;  &lt;span class="syntax-KEYWORD1"&gt;public&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;static&lt;/span&gt; String &lt;span class="syntax-FUNCTION"&gt;getOprDescr&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;String oprid&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;    Name recName &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;new&lt;/span&gt; &lt;span class="syntax-FUNCTION"&gt;Name&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;RECORD&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;PSOPRDEFN&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;;&lt;br /&gt;    Name fieldName &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;new&lt;/span&gt; &lt;span class="syntax-FUNCTION"&gt;Name&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;FIELD&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;OPRDEFNDESC&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;;&lt;br /&gt;    Rowset r &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; Func.&lt;span class="syntax-FUNCTION"&gt;CreateRowset&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;recName, &lt;span class="syntax-KEYWORD1"&gt;new&lt;/span&gt; Object[] &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    r.&lt;span class="syntax-FUNCTION"&gt;Fill&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;new&lt;/span&gt; Object[] &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;WHERE&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;OPRID&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;=&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;:1&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;, oprid &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;String&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;r.&lt;span class="syntax-FUNCTION"&gt;GetRow&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-DIGIT"&gt;1&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;.&lt;span class="syntax-FUNCTION"&gt;GetRecord&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;recName&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;.&lt;span class="syntax-FUNCTION"&gt;GetField&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;fieldName&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;.&lt;span class="syntax-FUNCTION"&gt;getValue&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;;&lt;br /&gt;  &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Notice that the first parameter to &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e12066"&gt;CreateRowset&lt;/a&gt; is a &lt;code&gt;Name&lt;/code&gt; object and the second is an empty array. If I were creating a hierarchical Rowset (similar to a component buffer), then I would fill the array with additional Rowset objects, as described by the &lt;code&gt;CreateRowset&lt;/code&gt; PeopleBooks entry. Another important difference between PeopleCode and Java is that the &lt;code&gt;"RECORD"&lt;/code&gt; and &lt;code&gt;"FIELD"&lt;/code&gt; parameters to the &lt;code&gt;Name&lt;/code&gt; constructor must be upper case.&lt;/p&gt;&lt;p&gt;Here is some PeopleCode to test this example:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD2"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;test.peoplecode.RowsetTest&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;).getOprDescr(&lt;span class="syntax-KEYWORD4"&gt;%OperatorId&lt;/span&gt;));&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;What about the IDE's Java project classpath? If your IDE supports library definitions (like &lt;a href="http://www.oracle.com/technology/products/jdev/index.html"&gt;JDeveloper&lt;/a&gt;), then add the JAR &lt;code&gt;%PS_HOME%\class\peoplecode.jar&lt;/code&gt; as a new library and then add the library to your project.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-4425416771175378922?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/4425416771175378922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=4425416771175378922' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4425416771175378922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4425416771175378922'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/05/accessing-peoplecode-rowsets-from-java.html' title='Accessing PeopleCode Rowsets from Java'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2742272876908672983</id><published>2010-04-20T06:54:00.000-07:00</published><updated>2010-04-20T06:54:10.943-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='PSUnit'/><title type='text'>FUNCLIB's and Event Scoped Variables</title><content type='html'>&lt;p&gt;While writing code for my post &lt;a href="http://jjmpsj.blogspot.com/2010/04/json-encoding-in-peoplecode.html"&gt;JSON Encoding in PeopleCode&lt;/a&gt;, I discovered a need for transient variable persistence (acknowledged in that post). Since I originally wrote that code in a FUNCLIB, I thought I could reuse/persist my &lt;code&gt;JavaObject&lt;/code&gt; variables by moving those two variable declarations above the function declaration. What I found was that this had no impact on the behavior of my code. The FUNCLIB function continued to initialize a new instance of my &lt;code&gt;JavaObject&lt;/code&gt; variables on each call. Now, PeopleBooks says that &lt;code&gt;JavaObject&lt;/code&gt; variables are treated a little differently than other variables so we should test to see if this behavior exists for regular variables, like &lt;code&gt;String&lt;/code&gt; variables. To test this, create a FUNCLIB that contains this code:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;test;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Function&lt;/span&gt; testval() &lt;span class="syntax-KEYWORD2"&gt;Returns&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&lt;span class="syntax-KEYWORD2"&gt;None&lt;/span&gt;(&amp;amp;test)) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;      &amp;amp;test &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;new&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;value&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;;&lt;br /&gt;      &lt;span class="syntax-KEYWORD2"&gt;Return&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;Not&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;initialized&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Else&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD2"&gt;Return&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;Initialized&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;End-Function&lt;/span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;You can then test this code with a &lt;a href="http://jjmpsj.blogspot.com/search/label/PSUnit"&gt;PSUnit&lt;/a&gt; test case defined as follows:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;import&lt;/span&gt; TTS_UNITTEST:TestBase;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;class&lt;/span&gt; Test extends TTS_UNITTEST:TestBase&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; Test();&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; Run();&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-class&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Declare&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;Function&lt;/span&gt; testval &lt;span class="syntax-KEYWORD1"&gt;PeopleCode&lt;/span&gt; JJM_SCOPE_FUNC.FUNCLIB FieldFormula;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; Test&lt;br /&gt;   &lt;span class="syntax-KEYWORD4"&gt;%Super&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;create&lt;/span&gt; TTS_UNITTEST:TestBase(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;Test&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-method&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; Run&lt;br /&gt;   &lt;span class="syntax-COMMENT3"&gt;/+&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;Extends/implements&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;TTS_UNITTEST:TestBase.Run&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;+/&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;number&lt;/span&gt; &amp;amp;idx;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;For&lt;/span&gt; &amp;amp;idx &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;1&lt;/span&gt; To &lt;span class="syntax-DIGIT"&gt;10&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD4"&gt;%This&lt;/span&gt;.Msg(&amp;amp;idx &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;:&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; testval());&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-For&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-method&lt;/span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;What does PeopleBooks say about this? What should I expect to see? Summarized, any variable declared within an event is available to all functions within that event (&lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcd/htm/tpcd03.htm#784eade9_125756438df__7a13"&gt;take me to the PeopleBooks reference for this&lt;/a&gt;). Given this information, the code does work... as described. The variable is accessible by the FUNCLIB function. PeopleBooks does not say the value will persist after a FUNCLIB function returns. It is important to make this distinction. Event scoped variables are accessible by all functions within an event, but they do not persist after leaving the scope of an event. In other words, once a FUNCLIB returns, the event scoped variables are discarded. Of course, if you call a FUNCLIB function from the same event that defines the FUNCLIB function, then the variable value will persist for the duration of the calling function. But if you did that, then the FUNCLIB function wouldn't really be a FUNCLIB function. It would just be a function. By definition, a FUNCLIB function is a function defined in a different event.&lt;/p&gt;&lt;p&gt;My conclusion: Locally scoped variables are really locally scoped. They don't maintain state when a FUNCLIB function returns. For a FUNCLIB, locally scoped variables are only relevant if you plan to call other functions within the FUNCLIB function's event from the FUNCLIB function.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2742272876908672983?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2742272876908672983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2742272876908672983' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2742272876908672983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2742272876908672983'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/04/funclibs-and-event-scoped-variables.html' title='FUNCLIB&apos;s and Event Scoped Variables'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1287833910928958239</id><published>2010-04-14T11:21:00.000-07:00</published><updated>2010-04-14T11:21:30.059-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Regular Expressions'/><title type='text'>JSON Encoding in PeopleCode</title><content type='html'>&lt;p&gt;I am a big fan of the &lt;a href="http://code.google.com/p/json-simple/"&gt;JSON.simple&lt;/a&gt; Java library. JSON.simple integrates well with PeopleCode. It produces flawless JSON without ugly PeopleCode &lt;a href="http://jjmpsj.blogspot.com/search/label/Java%20Reflection"&gt;Java Reflection&lt;/a&gt; and is compatible with Java 1.2 (for older tools versions). Yes, the object/array to JSON conversion in JSON.simple is nice, but my real reason for using a JSON library is JSON encoding. I can mock up and string together variable values to produce JSON, but my main problem is escaping strings so that they represent safe JSON data (quotes, etc). I thought the PeopleCode &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#_4fb753ec_12575645bf8__50d8"&gt;EscapeJavascriptString&lt;/a&gt; function would handle this for me, but I discovered that JSON != JavaScript. Certain character sequences, such as \' are valid for JavaScript, but invalid for JSON. After my latest tools and app upgrade, I decided to see what it would take to encode strings for JSON from PeopleCode. Here is what I created:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;class&lt;/span&gt; JSONEncoder&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; encode(&amp;amp;input As &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt;) &lt;span class="syntax-KEYWORD2"&gt;Returns&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;private&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;instance&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;meta_chars_;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;instance&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;unsafe_chars_pattern_;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;instance&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;int_;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; init();&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-class&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; encode&lt;br /&gt;   &lt;span class="syntax-COMMENT3"&gt;/+&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;&amp;amp;input&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;as&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;String&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;+/&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-COMMENT3"&gt;/+&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;Returns&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;String&lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT3"&gt;+/&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;matcher;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;output &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;input;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;replacement;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;match;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;number&lt;/span&gt; &amp;amp;offset &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;1&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Run&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;lazy&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;init&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;if&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;needed&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Protects&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;against&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;stateless&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;PeopleCode/Stateful&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;JVM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD4"&gt;%This&lt;/span&gt;.init();&lt;br /&gt;   &lt;br /&gt;   &amp;amp;matcher &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;unsafe_chars_pattern_.matcher(&lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.String&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;, &amp;amp;input));&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;While&lt;/span&gt; &amp;amp;matcher.&lt;span class="syntax-KEYWORD2"&gt;find&lt;/span&gt;()&lt;br /&gt;      &amp;amp;match &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;matcher.group();&lt;br /&gt;      &lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&amp;amp;meta_chars_.containsKey(&amp;amp;match)) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;         &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;replace&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;meta&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;characters&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;first&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;         &amp;amp;replacement &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;meta_chars_.get(&amp;amp;match).toString();&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;Else&lt;/span&gt;&lt;br /&gt;         &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;not&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;meta,&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;so&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;convert&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;unicode&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;escape&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;sequence&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;         &amp;amp;replacement &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\u&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;Right&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;0000&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &amp;amp;int_.toHexString(&lt;span class="syntax-KEYWORD2"&gt;Code&lt;/span&gt;(&amp;amp;match)), &lt;span class="syntax-DIGIT"&gt;4&lt;/span&gt;);&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;      &amp;amp;output &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;Replace&lt;/span&gt;(&amp;amp;output, &amp;amp;matcher.start() &lt;span class="syntax-OPERATOR"&gt;+&lt;/span&gt; &amp;amp;offset, (&amp;amp;matcher.end() - &amp;amp;matcher.start()), &amp;amp;replacement);&lt;br /&gt;      &lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;move&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;starting&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;position&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;based&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;on&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;size&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;of&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;string&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;after&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;replacement&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;      &amp;amp;offset &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;offset &lt;span class="syntax-OPERATOR"&gt;+&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;Len&lt;/span&gt;(&amp;amp;replacement) - (&amp;amp;matcher.end() - &amp;amp;matcher.start());&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-While&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-KEYWORD2"&gt;Return&lt;/span&gt; &amp;amp;output;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-method&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;method&lt;/span&gt; init&lt;br /&gt;   &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;None&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;only&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;works&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;on&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;local&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;vars,&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;so&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;get&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;pointer&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;&lt;span class="syntax-KEYWORD2"&gt;int&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;int_;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;if&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;&amp;amp;int&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;has&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;no&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;value,&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;then&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;initialize&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;all&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;JavaObject&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;vars&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-COMMENT1"&gt;/*&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;JavaObject&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;vars&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;will&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;have&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;no&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;value&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;in&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;two&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;scenarios:&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;1.&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;First&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;use,&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;never&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;initialized&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;2.&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Think&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;time&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;function,&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;global&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;variable,&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;anything&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;that&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;causes&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;state&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;serialization.&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;The&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;first&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;case&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;is&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;obvious.&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;The&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;second&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;case,&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;however,&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;is&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;not.&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;PeopleSoft&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;allows&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;you&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;make&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;App&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Classes&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Global&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;and&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Component&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;scoped&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;objects,&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;but&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;not&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;JavaObject&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;variables.&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;By&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;using&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;JavaObject&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;variables&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;in&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Component&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;and&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Global&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;scope,&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;you&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;can&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;get&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;into&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;bit&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;of&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;trouble.&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Retesting&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;these&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;values&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;on&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;each&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;use&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;ensures&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;they&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;are&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;always&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;initialized.&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;The&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;same&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;will&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;happen&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;if&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;you&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;use&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;think-time&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;function&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;like&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Prompt&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;or&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;a&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;Yes/No/Cancel&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;MessageBox.&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;*/&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&lt;span class="syntax-KEYWORD2"&gt;None&lt;/span&gt;(&amp;amp;&lt;span class="syntax-KEYWORD2"&gt;int&lt;/span&gt;)) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Lazy&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;initialize&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Integer&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;class&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;      &amp;amp;int_ &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.Integer&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Lazy&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;initialize&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;regular&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;expression&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;List&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;other&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;unsafe&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;characters&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;      &amp;amp;unsafe_chars_pattern_ &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.util.regex.Pattern&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;).compile(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;[\\&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;Lazy&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;initialize&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;hashtable&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;      &amp;amp;meta_chars_ &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.util.Hashtable&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &lt;br /&gt;      &lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;setup&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;meta&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;characters&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;      &amp;amp;meta_chars_.put(&lt;span class="syntax-KEYWORD2"&gt;Char&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;8&lt;/span&gt;), &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\b&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &amp;amp;meta_chars_.put(&lt;span class="syntax-KEYWORD2"&gt;Char&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;9&lt;/span&gt;), &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\t&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &amp;amp;meta_chars_.put(&lt;span class="syntax-KEYWORD2"&gt;Char&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;10&lt;/span&gt;), &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\n&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &amp;amp;meta_chars_.put(&lt;span class="syntax-KEYWORD2"&gt;Char&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;12&lt;/span&gt;), &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\f&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &amp;amp;meta_chars_.put(&lt;span class="syntax-KEYWORD2"&gt;Char&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;13&lt;/span&gt;), &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\r&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &amp;amp;meta_chars_.put(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\\&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;      &amp;amp;meta_chars_.put(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;end-method&lt;/span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;I adapted this code from the JavaScript &lt;code&gt;quote&lt;/code&gt; function in the json.org &lt;a href="http://www.json.org/json2.js"&gt;JSON2&lt;/a&gt; JavaScript parser. Yes, this solution does still use Java (&lt;a href="http://jjmpsj.blogspot.com/search/label/Regular%20Expressions"&gt;regular expressions&lt;/a&gt; and &lt;a href="http://jjmpsj.blogspot.com/2010/04/hex-encoding-characters.html"&gt;hexadecimal encoding&lt;/a&gt;), but it doesn't require external libraries. See, my real motivation was to eliminate external dependencies. I wanted code I could compile and leave in the database; code that didn't require OS file system modifications; code that would upgrade without impacting PS_HOME, psappsrv.cfg, psconfig.sh, or any other upgraded configuration file.&lt;/p&gt;&lt;p&gt;Why an App Class instead of a FUNCLIB? I originally wrote this code as a FUNCLIB function. Step one of the function would populate the hashtable. This meant for each function call, I would incur the overhead of creating and populating the hashtable. Since I know I will call this function multiple times while constructing a JSON string, I wanted a mechanism to persist the hashtable across function calls. An App Class's private instance variable provides this mechanism. What about Global variables? First, I have NEVER used them. Second, you CAN'T use them with variables of type JavaObject. What about serialization, scoping, and think-time functions with Java? I protect against the "First operand of . is Null" error by lazily initializing the hashtable and the regular expression. A postback will reset the JavaObject to Null, and my lazy initialization code will reinitialize it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1287833910928958239?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1287833910928958239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1287833910928958239' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1287833910928958239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1287833910928958239'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/04/json-encoding-in-peoplecode.html' title='JSON Encoding in PeopleCode'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-116086859362528472</id><published>2010-04-13T15:45:00.000-07:00</published><updated>2010-04-13T15:59:53.192-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Hex Encoding Characters</title><content type='html'>&lt;p&gt;Does anyone have a PeopleCode algorithm for hex encoding strings? I'm working on an &lt;code&gt;escapeJSON&lt;/code&gt; function and would like to come up with a good way to convert unsafe characters to unicode. Here is what I've come up with, but I would like to hear other ideas:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;&lt;span class="syntax-KEYWORD2"&gt;int&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.Integer&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;unicode;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT2"&gt;REM&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;**&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;I&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;hard&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;coded&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;source&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;character&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;A&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;for&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;this&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;example&lt;/span&gt;&lt;span class="syntax-COMMENT2"&gt;;&lt;/span&gt;&lt;br /&gt;&amp;amp;unicode &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;\u&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;Right&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;0000&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &amp;amp;&lt;span class="syntax-KEYWORD2"&gt;int&lt;/span&gt;.toHexString(&lt;span class="syntax-KEYWORD2"&gt;Code&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;A&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;)), &lt;span class="syntax-DIGIT"&gt;4&lt;/span&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This converts "A" to \u0041. The actual Hex part is&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.Integer&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;).toHexString(&lt;span class="syntax-KEYWORD2"&gt;Code&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;A&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;));&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;I don't think there is anything wrong with my solution. I am just wondering if I overlooked some PeopleCode function for displaying numbers in Hex.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-116086859362528472?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/116086859362528472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=116086859362528472' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/116086859362528472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/116086859362528472'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/04/hex-encoding-characters.html' title='Hex Encoding Characters'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2583474926879891597</id><published>2010-02-21T20:59:00.000-08:00</published><updated>2010-02-21T21:00:15.977-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Branding'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Page Assembler Strips Empty Elements -- This is Good!</title><content type='html'>&lt;p&gt;With the new release of PeopleTools and Enterprise Portal, I find myself modifying my old branding themes to incorporate new features. While testing a header, I noticed that it appeared correctly on homepages, but not on transaction pages. Upon further inspection, I noticed that certain HTML elements I included in my HTML definition appeared on homepages, but not on transaction pages. Specifically, if an HTML element had a bind variable as its only content and that bind variable was only relevant on a homepage, then the page assembler would strip my hard-coded &lt;em&gt;empty&lt;/em&gt; element from the transaction page. This caused me a bit of concern because I was actually using those elements to provide layout and styling. Consider the "Personalize Content | Layout" links that usually appear underneath the tabs in a standard Enterprise Portal implementation. Those links only appear on homepages, not on transaction pages. The PeopleSoft branding/assembly code uses designated bind variables to insert those links into a header HTML definition. If you wrap a block element, such as an HTML &lt;code&gt;div&lt;/code&gt; around that bind variable, then your &lt;code&gt;div&lt;/code&gt; will appear on a homepage, but not on a transaction page.&lt;/p&gt;&lt;p&gt;When I saw this behavior the other day I was quite surprised... and then I remembered I had seen it before. Several years ago while working with page level HTML Areas and Ajax, I noticed the same behavior. It is quite common to insert empty, hidden &lt;code&gt;div&lt;/code&gt; elements and other structural elements into HTML to act as containers for dynamic content. The only problem with this approach is that the page assembler seems to eliminate these empty elements. Here is the workaround I contrived for this issue: Add an HTML comment inside an empty HTML element as follows:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-MARKUP"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;div&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt; &lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;id&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;jjm_dynamicContent&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt; &lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;style="&lt;/span&gt;&lt;span class="syntax-KEYWORD2"&gt;height&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;10px&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;background-color&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-KEYWORD4"&gt;blue&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;"&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-COMMENT1"&gt;&amp;lt;!--&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;This&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;comment&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;will&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;force&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;the&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;page&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;assembler&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;to&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;render&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;this&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;element&lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt; &lt;/span&gt;&lt;span class="syntax-COMMENT1"&gt;--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-MARKUP"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;/&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;div&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The page assembler will see content (the comment) inside the element and will allow it to pass through to the browser. Since the content is a comment, the browser will ignore the content and treat the element as if it were empty, giving us our much desired empty element.&lt;/p&gt;&lt;p&gt;Now that we have a solution for creating empty elements, let's consider how to turn this seemingly annoying behavior into a positive feature. The PeopleTools branding makes extensive use of HTML definitions. These HTML definitions contain bind variables that may or may not have values, depending on the execution context. I've already given the example of the &lt;em&gt;Personalize&lt;/em&gt; links on a homepage. Wrapping items like these in HTML containers, such as &lt;code&gt;div&lt;/code&gt; elements, provides us with conditionals that otherwise might not exist. For example, by wrapping the &lt;em&gt;Personalize&lt;/em&gt; bind variable in a named &lt;code&gt;div&lt;/code&gt;, you create a div that will exist on homepages, but not on transaction pages. Using JavaScript, you can test for the existence of this named element and execute code accordingly. Likewise, you can use CSS to attach layout and design instructions to these elements that the browser will only apply if the element exists (conditions are met).&lt;/p&gt;&lt;p&gt;There was a time when I thought this was a bug that should be fixed. But, now that I am enlightened to the possibilities of conditionals, I see the benefits of this feature and would be very sorry to see this behavior change.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2583474926879891597?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2583474926879891597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2583474926879891597' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2583474926879891597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2583474926879891597'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/02/page-assembler-strips-empty-elements.html' title='Page Assembler Strips Empty Elements -- This is Good!'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1838564038210455617</id><published>2010-02-21T12:57:00.000-08:00</published><updated>2010-02-21T12:59:43.185-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>HEUG Alliance 2010</title><content type='html'>&lt;p&gt;I can't believe that &lt;a href="http://www.heug.org/p/cm/ld/fid=153"&gt;Alliance&lt;/a&gt; is next week! This is one of my favorite conferences - the people, the sessions, the locations... Alliance is one of the best opportunities to learn and share PeopleTools ideas.&lt;/p&gt;&lt;p&gt;I hope you can get into San Antonio early and get a good night's sleep Sunday night because my session, &lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3670&amp;req=info"&gt;27202 - PeopleTools Tips and Tricks&lt;/a&gt; is the first breakout session Monday morning. The &lt;a href="http://www.heug.org/index.php?mo=cm&amp;op=ld&amp;fid=149"&gt;fun run&lt;/a&gt; and &lt;a href="http://www.heug.org/index.php?mo=cm&amp;op=ld&amp;fid=160"&gt;golf tournament&lt;/a&gt; are great ways to get some exercise to acclimate yourself to the timezone differences, or just so you can sleep well in your hotel room.&lt;/p&gt;&lt;p&gt;The Alliance Agenda builder doesn't show sessions by vendor. Since I have a list of PeopleTools sessions offered by Oracle, I thought I would list them here. I will attend some of these sessions, but I am much more interested in attending your (the customer) sessions and seeing what you are doing.&lt;/p&gt;&lt;table border="1" cellspacing="0"&gt;&lt;tr&gt;&lt;th&gt;Title&lt;/th&gt;&lt;th&gt;Session&lt;/th&gt;&lt;th&gt;Time&lt;/th&gt;&lt;th&gt;Location&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="4" style="border-top: 1px solid #3c3c3c; border-bottom: 1px solid #3c3c3c;"&gt;&lt;strong&gt;&lt;em&gt;Monday&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3670&amp;req=info"&gt;PeopleTools Tips and Tricks&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27202&lt;/td&gt;&lt;td&gt;9:30 AM&lt;/td&gt;&lt;td&gt;Room 103A&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background-color: #d9d9d9;"&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3671&amp;req=info"&gt;PeopleSoft and WebCenter: The New World of Enterprsie 2.0&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27217&lt;/td&gt;&lt;td&gt;10:45 AM&lt;/td&gt;&lt;td&gt;Room 103A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3672&amp;req=info"&gt;Building Web Services with PeopleTools Integration Broker&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;27215&lt;/td&gt;&lt;td&gt;12:45 PM&lt;/td&gt;&lt;td&gt;Room 103B&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background-color: #d9d9d9;"&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3956&amp;req=info"&gt;PeopleTools Roadmap&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27197&lt;/td&gt;&lt;td&gt;3:15 PM&lt;/td&gt;&lt;td&gt;Grand Ballroom C3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3683&amp;req=info"&gt;PeopleTools Performance Tips and Tricks&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27201&lt;/td&gt;&lt;td&gt;4:30 PM&lt;/td&gt;&lt;td&gt;Room 103B&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background-color: #d9d9d9;"&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3575&amp;req=info"&gt;Maintenance Strategies for a PeopleSoft Enterprise Application&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27206&lt;/td&gt;&lt;td&gt;4:30 PM&lt;/td&gt;&lt;td&gt;Room 007A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="4" style="border-top: 1px solid #3c3c3c; border-bottom: 1px solid #3c3c3c;"&gt;&lt;strong&gt;&lt;em&gt;Tuesday&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3674&amp;req=info"&gt;PeopleTools 8.50 Highlights - For The Application Developer&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27205&lt;/td&gt;&lt;td&gt;12:45 PM&lt;/td&gt;&lt;td&gt;Room 103A&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background-color: #d9d9d9;"&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3685&amp;req=info"&gt;PeopleTools 8.50 Highlights - SOA and Integration&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27216&lt;/td&gt;&lt;td&gt;2:00 PM&lt;/td&gt;&lt;td&gt;Room 103B&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3676&amp;req=info"&gt;PeopleTools 8.50 Highlights - Application and Web Servers&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27200&lt;/td&gt;&lt;td&gt;3:15 PM&lt;/td&gt;&lt;td&gt;Room 103A&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background-color: #d9d9d9;"&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3677&amp;req=info"&gt;PeopleSoft PeopleTools Enterprise: A Panel Discussion&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27204&lt;/td&gt;&lt;td&gt;4:30 PM&lt;/td&gt;&lt;td&gt;Room 103A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="4" style="border-top: 1px solid #3c3c3c; border-bottom: 1px solid #3c3c3c;"&gt;&lt;strong&gt;&lt;em&gt;Wednesday&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3517&amp;req=info"&gt;PeopleTools 8.50 Highlights - Reporting and BI&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27199&lt;/td&gt;&lt;td&gt;9:30 AM&lt;/td&gt;&lt;td&gt;River Room 001B&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background-color: #d9d9d9;"&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3689&amp;req=info"&gt;Securing your PeopleSoft Application&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27198&lt;/td&gt;&lt;td&gt;10:45 AM&lt;/td&gt;&lt;td&gt;Room 103B&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.heug.org/e/in/eid=7&amp;s=3679&amp;req=info"&gt;Web 2.0 in Your Enterprise: Collaboration by Example&lt;/a&gt;&lt;/td&gt;&lt;td&gt;27207&lt;/td&gt;&lt;td&gt;10:45 AM&lt;/td&gt;&lt;td&gt;Room 103A&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Besides great sessions, be sure to stop by the Oracle demo grounds to see our new 8.50 and 9.1 applications! I haven't seen a final schedule, but &lt;em&gt;Meet the Experts&lt;/em&gt; will be in the demo grounds some time during the normal exhibit all hours. Be sure to look for the &lt;em&gt;Meet the Experts&lt;/em&gt; bistro tables in Oracle booth.&lt;/p&gt;&lt;p&gt;See you next week in San Antonio!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1838564038210455617?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1838564038210455617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1838564038210455617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1838564038210455617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1838564038210455617'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/02/heug-alliance-2010.html' title='HEUG Alliance 2010'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-8046277406109684527</id><published>2010-02-21T10:58:00.000-08:00</published><updated>2010-02-21T11:00:06.512-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Exec Processes while Controlling stdin and stdout</title><content type='html'>&lt;p&gt;A few months ago I read a question on the &lt;a href="http://peoplesoft.ittoolbox.com/groups/technical-functional/peopletools-l/getting-command-line-output-from-exec-3064057?subtype="&gt;ITToolbox PeopleTools-I&lt;/a&gt; forum asking if it was possible to read the output of a spawned process. Unfortunately this is not possible with the delivered PeopleCode &lt;a href="http://download.oracle.com/docs/cd/E15645_01/pt850pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#_4fb753ec_12575645bf8__5035"&gt;Exec&lt;/a&gt; function. I got to thinking about this though, and I wondered if it was possible to accomplish this by using Java's &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html"&gt;Runtime&lt;/a&gt; object from PeopleCode. The answer is yes. To test this, create a batch file in your &lt;code&gt;c:\temp&lt;/code&gt; directory named &lt;code&gt;sayHello.bat&lt;/code&gt; and then add the following batch file commands to this file:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD3"&gt;@&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;echo&lt;/span&gt; off&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;echo&lt;/span&gt; Hello &lt;span class="syntax-KEYWORD2"&gt;%1&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;echo&lt;/span&gt; How are you?&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Next, open App Designer and create a new App Engine program. Add a new PeopleCode action to this program and insert the following PeopleCode:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;runtime &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.Runtime&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;).getRuntime();&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;process &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;runtime.&lt;span class="syntax-KEYWORD2"&gt;exec&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;c:\temp\sayHello.bat&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-KEYWORD4"&gt;%OperatorId&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;inputStreamReader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.InputStreamReader&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;process.getInputStream());&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;bufferedReader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.BufferedReader&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;inputStreamReader);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;any&lt;/span&gt; &amp;amp;inputLine;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;While&lt;/span&gt; True&lt;br /&gt;   &amp;amp;inputLine &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;bufferedReader.readLine();&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&amp;amp;inputLine &amp;lt;&amp;gt; Null) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD2"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &amp;amp;inputLine);&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Else&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;Break&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;End-While&lt;/span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Open the new App Engine's properties and disable restart. From the App Designer menu bar, choose &lt;b&gt;Edit | Run Program&lt;/b&gt;. When the &lt;i&gt;Run Request&lt;/i&gt; dialog appears, select the &lt;b&gt;Output Log to File&lt;/b&gt; checkbox and then activate the &lt;b&gt;Run&lt;/b&gt; button. When the App Engine finishes, open the log file (usually c:\temp\NAME_OF_AE.log) and review its contents. Here is the contents of my log file. Notice that I was logged in as user &lt;code&gt;PS&lt;/code&gt; and named my App Engine &lt;code&gt;JJM_JAVAEXEC&lt;/code&gt;. I expect your results to differ slightly based on your tools version, operator ID, and program name.&lt;/p&gt;&lt;pre&gt;PeopleTools 8.49 - Application Engine&lt;br /&gt;Copyright (c) 1988-2010 PeopleSoft, Inc.&lt;br /&gt;All Rights Reserved&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hello "PS" (0,0)&lt;br /&gt; Message Set Number: 0&lt;br /&gt; Message Number: 0&lt;br /&gt; Message Reason: Hello "PS" (0,0) (0,0)&lt;br /&gt;&lt;br /&gt;How are you? (0,0)&lt;br /&gt; Message Set Number: 0&lt;br /&gt; Message Number: 0&lt;br /&gt; Message Reason: How are you? (0,0) (0,0)&lt;br /&gt;Application Engine program JJM_JAVAEXEC ended normally&lt;/pre&gt;&lt;p&gt;The following example is similar to the previous, but writes to &lt;code&gt;stdin&lt;/code&gt; as well as reading from &lt;code&gt;stdout&lt;/code&gt;. To run this example, you need a copy of grep. I use the version that comes with &lt;a href="http://unxutils.sourceforge.net/"&gt;UnxUtils&lt;/a&gt; (Note: You do not need grep or UnxUtils to write to stdin. Grep is a common command line tool, so I used it here for example purposes only). The following code writes two lines to the &lt;code&gt;grep&lt;/code&gt; program's standard input (stdin): EMPLID and OPRID. It then asks &lt;code&gt;grep&lt;/code&gt; to find the line containing &lt;code&gt;OPRID&lt;/code&gt;. The PeopleCode then reads the &lt;code&gt;grep&lt;/code&gt; program's output and writes it to the App Engine log.&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;runtime &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.lang.Runtime&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;).getRuntime();&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;process &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;runtime.&lt;span class="syntax-KEYWORD2"&gt;exec&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;grep&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;OPRID&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;inputStreamReader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.InputStreamReader&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;process.getInputStream());&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;bufferedReader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.BufferedReader&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;inputStreamReader);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;outputStreamWriter &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.OutputStreamWriter&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;process.getOutputStream());&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;outputBuffer &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.BufferedWriter&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;outputStreamWriter);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;any&lt;/span&gt; &amp;amp;inputLine;&lt;br /&gt;&lt;br /&gt;&amp;amp;outputBuffer.write(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;EMPLID:&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-KEYWORD4"&gt;%EmployeeId&lt;/span&gt;);&lt;br /&gt;&amp;amp;outputBuffer.newLine();&lt;br /&gt;&amp;amp;outputBuffer.write(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;OPRID:&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt; &lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-KEYWORD4"&gt;%OperatorId&lt;/span&gt;);&lt;br /&gt;&amp;amp;outputBuffer.close();&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Repeat&lt;/span&gt;&lt;br /&gt;   &amp;amp;inputLine &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;bufferedReader.readLine();&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&lt;span class="syntax-KEYWORD1"&gt;All&lt;/span&gt;(&amp;amp;inputLine)) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD2"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &lt;span class="syntax-DIGIT"&gt;0&lt;/span&gt;, &amp;amp;inputLine);&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Until None&lt;/span&gt;(&amp;amp;inputLine);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If you want to run this example and have a copy of &lt;code&gt;grep&lt;/code&gt; in your &lt;code&gt;%PATH%&lt;/code&gt; environment variable, then add a new step and PeopleCode action to your App Engine, deactivate the previously created step, and then run the program. Your output should look something like:&lt;/p&gt;&lt;pre&gt;PeopleTools 8.49 - Application Engine&lt;br /&gt;Copyright (c) 1988-2010 PeopleSoft, Inc.&lt;br /&gt;All Rights Reserved&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;OPRID: PS (0,0)&lt;br /&gt; Message Set Number: 0&lt;br /&gt; Message Number: 0&lt;br /&gt; Message Reason: OPRID: PS (0,0) (0,0)&lt;br /&gt;Application Engine program JJM_JAVAEXEC ended normally&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-8046277406109684527?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/8046277406109684527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=8046277406109684527' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8046277406109684527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8046277406109684527'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/02/exec-processes-while-controlling-stdin.html' title='Exec Processes while Controlling stdin and stdout'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5555389979358750251</id><published>2010-01-20T10:02:00.000-08:00</published><updated>2010-01-20T10:02:06.189-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Cryptography'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Integration'/><title type='text'>Base64 Encoding Binary Files</title><content type='html'>&lt;p&gt;Several months ago I posted a handful of methods for &lt;a href="http://jjmpsj.blogspot.com/search?q=base64"&gt;base64 encoding strings&lt;/a&gt;. At that time I suggested that the next important step was base64 encoding binary files. This represents a challenge because PeopleCode does not offer methods for reading binary files. The following PeopleCode uses the Java API and the &lt;a href="http://commons.apache.org/codec/"&gt;Apache Commons Codec&lt;/a&gt; library to show how to base64 encode a binary file. To run this example, download the commons-codec library and place the jar file in your local &lt;code&gt;%PS_HOME\class&lt;/code&gt; directory. Next, create an App Engine with a PeopleCode step and insert the following PeopleCode:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;f_in &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.FileInputStream&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;c:\temp\binaryfile.gif&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;coder_in &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;org.apache.commons.codec.binary.Base64InputStream&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;f_in, True);&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;JavaObject&lt;/span&gt; &amp;amp;reader &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.BufferedReader&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-KEYWORD2"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;java.io.InputStreamReader&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &amp;amp;coder_in));&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;string&lt;/span&gt; &amp;amp;b64Data &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; &lt;span class="syntax-KEYWORD3"&gt;any&lt;/span&gt; &amp;amp;line;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;While&lt;/span&gt; True&lt;br /&gt;   &amp;amp;line &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;reader.readLine();&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;If&lt;/span&gt; (&amp;amp;line &amp;lt;&amp;gt; Null) &lt;span class="syntax-KEYWORD1"&gt;Then&lt;/span&gt;&lt;br /&gt;      &amp;amp;b64Data &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &amp;amp;b64Data &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &amp;amp;line &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;Char&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;13&lt;/span&gt;) &lt;span class="syntax-OPERATOR"&gt;|&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;Char&lt;/span&gt;(&lt;span class="syntax-DIGIT"&gt;10&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;Else&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;Break&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax-KEYWORD1"&gt;End-If&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;End-While&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-KEYWORD1"&gt;Local&lt;/span&gt; File &amp;amp;b64File &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-KEYWORD2"&gt;GetFile&lt;/span&gt;(&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;c:\temp\base64_encoded.txt&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;A&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, &lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;A&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;&amp;quot;&lt;/span&gt;, %FilePath_Absolute);&lt;br /&gt;&amp;amp;b64File.WriteLine(&amp;amp;b64Data);&lt;br /&gt;&amp;amp;b64File.Close();&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The Java objects at the top of this listing read binary data from a file and transform that data into a base64 text listing, which is then stored in the variable &lt;code&gt;&amp;amp;b64Data&lt;/code&gt;. For demonstration purposes, I wrote the contents of &lt;code&gt;&amp;amp;b64Data&lt;/code&gt; to a file. In real life, you would add this contents to a &lt;code&gt;CDATA&lt;/code&gt; node prior to sending a message through the Integration Broker.&lt;/p&gt;&lt;p&gt;Before running this code, replace &lt;code&gt;c:\temp\binaryfile.gif&lt;/code&gt; with the full path to a real binary file on your workstation. After adding the PeopleCode listed above, disable restart and run your App Engine. When the App Engine completes, look in your local &lt;code&gt;c:\temp&lt;/code&gt; directory for a file named &lt;code&gt;base64_encoded.txt&lt;/code&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5555389979358750251?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5555389979358750251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5555389979358750251' title='61 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5555389979358750251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5555389979358750251'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/01/base64-encoding-binary-files.html' title='Base64 Encoding Binary Files'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>61</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5148139602010254879</id><published>2010-01-12T21:19:00.000-08:00</published><updated>2010-01-12T21:20:05.199-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleTools'/><title type='text'>Pre-order My PeopleTools Tips Book</title><content type='html'>&lt;p&gt;My PeopleSoft PeopleTools Tips and Techniques book is now available for Pre-order through popular book resellers:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.mhprofessional.com/product.php?isbn=0071664939"&gt;McGraw Hill&lt;/a&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/PeopleSoft-PeopleTools-Techniques-Osborne-ORACLE/dp/0071664939"&gt;Amazon&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.psoftpros.net/peoplesoft-books/index.php/peoplesoft-peopletools-tips-techniques-osborne-oracle-press-series/"&gt;PsoftPros&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.borders.com/online/store/TitleDetail?sku=0071664939"&gt;Borders&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://search.barnesandnoble.com/PeopleSoft-PeopleTools-Tips-and-Techniques/Marion/e/9780071664936"&gt;Barnes &amp;amp; Noble&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Expected availability is July 22, 2010. This book took a lot of effort and I especially want to thank my wife who performed the first edit and rewrite (the biggest chunk). Without her, there wouldn't be an intelligible sentence or complete thought in the book. Secondly, I would like to thank my technical editors Tim Burns and Graham Smith, two very well known faces in the PeopleSoft community. These guys tested every example prior to publication.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5148139602010254879?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5148139602010254879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5148139602010254879' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5148139602010254879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5148139602010254879'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2010/01/pre-order-my-peopletools-tips-book.html' title='Pre-order My PeopleTools Tips Book'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5560029321963807223</id><published>2009-10-26T21:26:00.001-07:00</published><updated>2009-10-26T21:29:48.655-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>OpenWorld Presentations Available</title><content type='html'>&lt;p&gt;The 2009 &lt;a href="http://openworld.vportal.net/?auid=10565"&gt;PeopleTools Tips and Tricks&lt;/a&gt; session I presented is available (audio and slides) on &lt;a href="http://openworld.vportal.net/"&gt;Oracle OpenWorld On Demand&lt;/a&gt;. Unfortunately there are no screenshots for the demos.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5560029321963807223?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5560029321963807223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5560029321963807223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5560029321963807223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5560029321963807223'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/10/openworld-presentations-available.html' title='OpenWorld Presentations Available'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-4930499208875885581</id><published>2009-10-15T22:12:00.000-07:00</published><updated>2010-04-15T09:31:51.618-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Change the Advanced Search Page Default Search Operator</title><content type='html'>&lt;p&gt;In my OOW presentation yesterday I showed that it is possible to change the default search operator for a specific &lt;em&gt;advanced&lt;/em&gt; search page. The JavaScript required to implement this behavior follows:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax-MARKUP"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt; &lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;type&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;=&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;"&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;text&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;/&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;javascript&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;"&lt;/span&gt;&lt;span class="syntax-MARKUP"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  $&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;document&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;ready&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; newValue &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-DIGIT"&gt;9&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; coll &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; $&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;select[name='APT_UI_SCRIPTS_MENUNAME$op']&lt;/span&gt;&lt;span class="syntax-LITERAL1"&gt;"&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-KEYWORD1"&gt;if&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;coll&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;val&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;!&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; newValue&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      coll&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;val&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;newValue&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;change&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-MARKUP"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The code above uses &lt;a href="http://jjmpsj.blogspot.com/search/label/jQuery"&gt;jQuery&lt;/a&gt; for event handling and therefore requires that you inject jQuery along with the JavaScript above. I demonstrate how to accomplish this in the injection blog post referenced below.&lt;/p&gt;&lt;p&gt;In my PeopleTools book I provide full details for implementing this behavior, but if you want to get a head start, I'll give you some hints. First, you need a mechanism for injecting this JavaScript into a search page. To learn more about injection, read my post &lt;a href="http://jjmpsj.blogspot.com/2009/01/injecting-javascript-libraries-into.html"&gt;Injecting JavaScript Libraries into PeopleSoft Pages&lt;/a&gt;. Next, you need a way to target a specific component. For this, see my post &lt;a href="http://jjmpsj.blogspot.com/2009/08/javascript-complement-of-peoplecode.html"&gt;JavaScript complement of PeopleCode Global Vars&lt;/a&gt;. Your final step is to write some JavaScript to determine if the open page is a search page. I determine this by testing for the existence of an object named &lt;code&gt;#ICSearch&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;To determine the numerical code for a search page operator (9 = between), open the HTML source of any advanced search page and search for the option child nodes of &lt;code&gt;PSDROPDOWNLIST&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update (April 15, 2010)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The code above works great with PeopleTools 8.49 and lower. PeopleTools 8.50 uses Ajax to switch from the basic to the advanced search page. The 8.50 Ajax does not trigger the $(document).ready code. I have another solution for PeopleTools 8.50 (documented in my book). I'll post it soon.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-4930499208875885581?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/4930499208875885581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=4930499208875885581' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4930499208875885581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4930499208875885581'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/10/change-advanced-search-page-default.html' title='Change the Advanced Search Page Default Search Operator'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3388825401849127731</id><published>2009-10-07T00:59:00.000-07:00</published><updated>2009-10-07T01:11:28.103-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>Learn Development Tips and Techniques at OpenWorld 2009</title><content type='html'>&lt;p&gt;Next Wednesday, October 14th, I will be sharing &lt;a href="http://www.eventreg.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S308230&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=&amp;search_advance=yes&amp;horizontal1=20"&gt;PeopleTools Tips and Tricks&lt;/a&gt; from 11:45 to 12:45 in Moscone West room 2002/2004 (level 2). In this session I will share with you some very practical development tips (TDD, design patterns, best practices, etc) as well as demonstrate exotic user interface customizations using AJAX and Flex. Time permitting, I will share with you some real-time integration solutions for legacy (non web service) applications and I won't use DB links or SQR.&lt;/p&gt;&lt;p&gt;What type of AJAX demonstrations do I have this year?&lt;p&gt;&lt;ul&gt;&lt;li&gt;Using Thickbox/lightbox with PeopleSoft&lt;/li&gt;&lt;li&gt;Creating a custom toolbar&lt;/li&gt;&lt;li&gt;Change the search page default search operator&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Best of all, these AJAX examples are configurable, except for 10 lines of JavaScript added to one PeopleSoft delivered definition. Yes, that is right! By adding 10 lines of JavaScript to a single delivered definition, I can add code to any PeopleSoft page without modifying the page in AppDesigner. Furthermore, using Meta-data, I can configure page specific customizations or global customizations.&lt;/p&gt;&lt;p&gt;If you have room in your OpenWorld schedule, I highly recommend this Tips and Tricks session.&lt;/p&gt;&lt;p&gt;On Thursday at 10:30, come by the &lt;a href="http://www.eventreg.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=nishit&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S311741&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=&amp;search_advance=yes&amp;horizontal1=20"&gt;Create a Rich Internet UI for Oracle Applications with Oracle Application Development Framework&lt;/a&gt; hands on session at the Marriott Golden Gate A3 to see a demonstration of how to build mobile applications for PeopleSoft using Oracle ADF.&lt;/p&gt;&lt;p&gt;Here is a list of other sessions I recommend:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.eventreg.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S308411&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=&amp;search_advance=yes&amp;horizontal1=20"&gt;How to Customize PeopleSoft Applications Safely&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.eventreg.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S308261&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=PeopleTools&amp;search_advance=yes&amp;horizontal1=20"&gt;Got Enhancements for PeopleSoft PeopleTools?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.eventreg.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S308231&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=PeopleTools&amp;search_advance=yes&amp;horizontal1=20"&gt;PeopleSoft PeopleTools: A Panel Discussion&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.eventreg.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S308257&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=PeopleTools&amp;search_advance=yes&amp;horizontal1=20"&gt;PeopleSoft PeopleTools 8.50: Highlights for Application Developers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.eventreg.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=PeopleTools&amp;search_advance=yes&amp;horizontal1=20"&gt;Any other PeopleTools Session&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3388825401849127731?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3388825401849127731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3388825401849127731' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3388825401849127731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3388825401849127731'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/10/learn-development-tips-and-techniques.html' title='Learn Development Tips and Techniques at OpenWorld 2009'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1371871417019882543</id><published>2009-09-18T11:25:00.000-07:00</published><updated>2009-09-18T11:30:46.606-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleTools'/><title type='text'>PeopleTools 8.50 Released!</title><content type='html'>&lt;p&gt;The PeopleTools team just announced the general availability of PeopleTools 8.50. I have had the fortunate opportunity to work with PeopleTools 8.50 for a couple of months and I am very pleased with the enhancements provided in this new release. For more information, please read the PeopleTools Team's &lt;a href="http://blogs.oracle.com/peopletools/2009/09/general_availability_ga_of_peopletools_850.html"&gt;blog post&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1371871417019882543?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1371871417019882543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1371871417019882543' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1371871417019882543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1371871417019882543'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/09/peopletools-850-released.html' title='PeopleTools 8.50 Released!'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-4075723557210129940</id><published>2009-09-09T01:54:00.000-07:00</published><updated>2009-09-09T02:02:26.133-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>Cast your Vote for the next PeopleTools Features</title><content type='html'>&lt;p&gt;&lt;a href="https://mix.oracle.com/user_profiles/10573-greg-kelly"&gt;Greg Kelley&lt;/a&gt; from PeopleTools Product Strategy just posted a &lt;a href="http://blogs.oracle.com/peopletools/2009/09/got_peopletools_enhancements_b.html"&gt;request for PeopleTools enhancement ideas and votes&lt;/a&gt;. If you have an idea, post it in the &lt;a href="https://mix.oracle.com/groups/18611"&gt;PeopleTools Strategy Mix Group&lt;/a&gt;. What's that you say? You don't have any ideas? Log in to Mix anyway and vote for ideas submitted by other developers. The best ideas will be discussed at an OOW session on Wednesday, October 14th from 1:00 - 1:30 PM.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-4075723557210129940?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/4075723557210129940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=4075723557210129940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4075723557210129940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4075723557210129940'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/09/cast-your-vote-for-next-peopletools.html' title='Cast your Vote for the next PeopleTools Features'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-8254264763518752903</id><published>2009-09-01T09:07:00.000-07:00</published><updated>2009-09-01T09:15:44.697-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Rich Text Editor for PT 8.4x</title><content type='html'>&lt;p&gt;&lt;a href="http://it.toolbox.com/people/roso_todd"&gt;Todd Kummer&lt;/a&gt;, a regular contributor to &lt;a href="http://it.toolbox.com/"&gt;IT Toolbox&lt;/a&gt;, just posted a wiki that describes how to insert the &lt;a href="http://it.toolbox.com/wiki/index.php/Rich_Text_Editor"&gt;FCKEditor into PeopleSoft Pages&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-8254264763518752903?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/8254264763518752903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=8254264763518752903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8254264763518752903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8254264763518752903'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/09/rich-text-editor-for-pt-84x.html' title='Rich Text Editor for PT 8.4x'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-6156709284858882168</id><published>2009-08-31T01:00:00.000-07:00</published><updated>2009-08-31T01:10:55.239-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript complement of PeopleCode Global Vars</title><content type='html'>&lt;p&gt;While writing some JavaScript for my new &lt;a href="http://jjmpsj.blogspot.com/2009/07/new-peopletools-book.html"&gt;PeopleTools book&lt;/a&gt;, I came up with a JavaScript complement to some of the common PeopleCode global variables. Here is the code:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;jjmpsj&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;sysVars &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;url&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-KEYWORD1"&gt;var&lt;/span&gt; matches &lt;span class="syntax-OPERATOR"&gt;=&lt;/span&gt; url&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-FUNCTION"&gt;match&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-MARKUP"&gt;/ps[pc]\/&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;+&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;?&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;?&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt;_\d&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;*&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;?&lt;/span&gt;\&lt;span class="syntax-MARKUP"&gt;/(.+?)\/&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;+&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;?&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;\&lt;span class="syntax-MARKUP"&gt;/c\/&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;+&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;?&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;\&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;+&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;?&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;\&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;+&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;?&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;$&lt;span class="syntax-OPERATOR"&gt;/&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-LABEL"&gt;getSite&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; matches&lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;span class="syntax-DIGIT"&gt;1&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;]&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-LABEL"&gt;getPortal&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; matches&lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;span class="syntax-DIGIT"&gt;2&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;]&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-LABEL"&gt;getNode&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; matches&lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;span class="syntax-DIGIT"&gt;3&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;]&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-LABEL"&gt;getMenu&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; matches&lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;span class="syntax-DIGIT"&gt;4&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;]&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-LABEL"&gt;getComponent&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; matches&lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;span class="syntax-DIGIT"&gt;5&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;]&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-LABEL"&gt;getMarket&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;:&lt;/span&gt; &lt;span class="syntax-KEYWORD1"&gt;function&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt; &lt;span class="syntax-OPERATOR"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax-KEYWORD1"&gt;return&lt;/span&gt; matches&lt;span class="syntax-OPERATOR"&gt;[&lt;/span&gt;&lt;span class="syntax-DIGIT"&gt;6&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;]&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax-OPERATOR"&gt;}&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;(&lt;/span&gt;window&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;location&lt;span class="syntax-OPERATOR"&gt;.&lt;/span&gt;pathname&lt;span class="syntax-OPERATOR"&gt;)&lt;/span&gt;&lt;span class="syntax-OPERATOR"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now, wouldn't you just love to know how I intend to use this code... to learn that you will have to wait for the book.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-6156709284858882168?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/6156709284858882168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=6156709284858882168' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6156709284858882168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6156709284858882168'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/08/javascript-complement-of-peoplecode.html' title='JavaScript complement of PeopleCode Global Vars'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2823563434440538454</id><published>2009-08-17T21:17:00.000-07:00</published><updated>2009-08-17T22:00:35.922-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>OpenWorld 2009</title><content type='html'>&lt;p&gt;&lt;a href="http://www.oracle.com/us/openworld/index.htm"&gt;OpenWorld 2009&lt;/a&gt; is only two months away. If you are looking for an interesting &lt;a href="http://www20.cplan.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=PeopleTools&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=PeopleTools&amp;icriteria9=+&amp;icriteria6=&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=&amp;search_advance=yes&amp;horizontal1=85"&gt;PeopleTools session&lt;/a&gt;, be sure to show up in Moscone West L2 Room 2002/2004 on Wednesday 10/14/2009 at 11:40 (session time is 11:45 - 12:45). I will be presenting another exciting series of &lt;a href="http://www20.cplan.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S308230&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=&amp;search_advance=yes&amp;horizontal1=85"&gt;PeopleTools Advanced Tips and Techniques&lt;/a&gt;. Whether you are a functional user interested in seeing what's possible, or an expert looking for something new, I can guarantee you will hear and see something of interest. As always, I plan to pack three days worth of content into one hour.&lt;/p&gt;&lt;p&gt;Besides the &lt;a href="http://www20.cplan.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=PeopleTools+8.50&amp;search_advance=yes&amp;horizontal1=85"&gt;PeopleTools 8.50 sessions&lt;/a&gt; that every developer will attend, I recommend the session &lt;a href="http://www20.cplan.com/cc221_new/newCatalog.jsp?ilc=221-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;icriteria2=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria8=&amp;openTagSearch=&amp;icriteria9=+&amp;icriteria6=S308411&amp;icriteria3=+&amp;icriteria4=+&amp;icriteria7=&amp;search_advance=yes&amp;horizontal1=85"&gt;How to Customize PeopleSoft Applications Safely&lt;/a&gt; led by Graham Smith. Graham is a personal friend of mine from UKOUG.&lt;/p&gt;&lt;p&gt;I will also be working the demo grounds. I'll post my schedule once it is finalized.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2823563434440538454?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2823563434440538454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2823563434440538454' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2823563434440538454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2823563434440538454'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/08/openworld-2009.html' title='OpenWorld 2009'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-8748648618202256360</id><published>2009-08-02T22:22:00.000-07:00</published><updated>2009-11-17T20:32:06.902-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Best Practices'/><title type='text'>Using jEdit to Edit PeopleSoft Files</title><content type='html'>&lt;p&gt;A couple of years ago, Chris Heller wrote a great article on &lt;a href="http://blog.greysparling.com/2007/11/editing.html"&gt;editing PeopleSoft files with the Notepad++ text editor&lt;/a&gt;. Since I prefer &lt;a href="http://www.jedit.org/"&gt;jEdit&lt;/a&gt; over Notepad++ (my jEdit fascination dates back to my Java programming roots and, more recently, the jEdit Ruby plugin). I have a collection of custom jEdit syntax files in my &lt;a href="http://www.box.net/shared/ecjhpoidjs"&gt;box.net jEdit shared folder&lt;/a&gt;. In this folder, you will find DMS and PeopleCode syntax files (unlike Notepad++, jEdit includes SQR syntax files out of the box). Feel free to download and use these files. Caveat: these files are far from complete. I add to them on an as-needed basis. If you find errors and/or omissions, please leave a comment here, and I'll do my best to update my shared syntax files. See the jEdit help file for how to add these syntax files to jEdit (hint: jEdit calls syntax files "Edit Modes").&lt;/p&gt;&lt;p&gt;By the way, jEdit has a &lt;a href="http://plugins.jedit.org/plugins/?Code2HTML"&gt;Code2HTML&lt;/a&gt; plugin. I use the syntax files in my shared folder along with the Code2HTML plugin to generate the syntax highlighting used on this blog.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-8748648618202256360?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/8748648618202256360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=8748648618202256360' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8748648618202256360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8748648618202256360'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/08/using-jedit-to-edit-peoplesoft-files.html' title='Using jEdit to Edit PeopleSoft Files'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3388936178868622770</id><published>2009-07-31T16:28:00.000-07:00</published><updated>2009-07-31T16:32:43.399-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>HOWTO: Generate GUID from PeopleCode</title><content type='html'>&lt;p&gt;A few months ago I demonstrated a handful of ways to Base64 encode strings &amp;mdash; none of them were delivered. That post generated some outstanding feedback. Customers, consultants, and Oracle employees pointed me at several other alternatives, including the delivered &lt;a href="http://jjmpsj.blogspot.com/2009/05/base64-encoding-with-pluggable.html"&gt;Pluggable Encryption&lt;/a&gt; technique documented in PeopleBooks. I hope this post generates the same amount of discussion.&lt;/p&gt;&lt;p&gt;First, why would a PeopleSoft developer generate a GUID? My motivation is a database cache. I have a transaction that inserts information into a cache Record and an &lt;a href="http://jjmpsj.blogspot.com/search/label/IScripts"&gt;IScript&lt;/a&gt; that reads values from that cache. Rather than pass transaction keys to the IScript, I just pass a GUID that identifies the transaction's row in the cache. Besides decoupling the IScript from a transaction, it provides a bit of security through obfuscation (see &lt;a href="http://www.owasp.org/index.php/Top_10_2007-A4"&gt;OWASP Top 10 2007-Insecure Direct Object Reference&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;Now, how to generate a GUID from PeopleCode... PeopleBooks does not list any GUID generation functions, so the next place to look for this functionality is in related technologies accessible to PeopleCode. For example, the Oracle database provides the SYS_GUID function for generating GUID's in the RAW. Here is the SYS_GUID function in action:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;guid;&lt;br /&gt;&lt;span class="syntax9"&gt;SQLExec&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;SELECT&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;RAWTOHEX(SYS_GUID())&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FROM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;PS_INSTALLATION&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;guid);&lt;br /&gt;&lt;span class="syntax9"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;GUID&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;from&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;DB:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;guid);&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If you are just looking for a random string, then read no further. If you want a formatted GUID, then you will need to add the dashes yourself. Microsoft SQL Server has a similar function that actually returns a fully formatted plain text GUID.&lt;/p&gt;&lt;p&gt;The problem with these SQL alternatives is that they are database specific. I'm not going to complain about a user taking full advantage of the database's features. But, if there is an alternative that may reduce future maintenance costs (like the cost of swtiching from one database to another), then I'll consider the low cost alternative.&lt;/p&gt;&lt;p&gt;Since all PeopleSoft application servers run Java, we can use the JRE's GUID methods to generate a GUID. If you are on PeopleTools 8.49 with Java 1.5, then this short PeopleCode snippet will give you a fully formatted GUID:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax0"&gt;&lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.util.UUID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).randomUUID().toString();&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;On my laptop, the code above generated &lt;code&gt;d65ca460-fc93-4420-a889-8b36311ee4a0&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;What if you are using an older version of PeopleTools (prior to 8.49)? The Apache &lt;a href="http://commons.apache.org/sandbox/id/"&gt;commons id&lt;/a&gt; project has a UUID Java class that is similar to the delivered Java 1.5 &lt;a href="http://commons.apache.org/sandbox/id/apidocs/org/apache/commons/id/uuid/UUID.html"&gt;UUID&lt;/a&gt; class. For more information about Java GUID generation, see this &lt;a href="http://www.asciiarmor.com/post/33736615/java-util-uuid-mini-faq"&gt;java.util.UUID mini-FAQ&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Who knows, if you dig through your application's PeopleCode, you might find an undocumented method for generating GUID's ;)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3388936178868622770?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3388936178868622770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3388936178868622770' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3388936178868622770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3388936178868622770'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/07/howto-generate-guid-from-peoplecode.html' title='HOWTO: Generate GUID from PeopleCode'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1127306994491807386</id><published>2009-07-10T07:33:00.000-07:00</published><updated>2009-10-29T00:34:03.815-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleTools'/><title type='text'>New PeopleTools Book</title><content type='html'>&lt;p&gt;&lt;span style="text-decoration: line-through;"&gt;Pre order copies of my new book &lt;a href="http://mhprofessional.com/product.php?isbn=0071664939"&gt;PeopleSoft PeopleTools Tips &amp;amp; Techniques&lt;/a&gt;.&lt;/span&gt; The publication date is set for July, 2010, about one year from now.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Updated Oct 29, 2009:&lt;/b&gt; Unfortunately, you cannot pre order yet. McGraw Hill removed the placeholder page from their site. McGraw Hill will repost and begin taking pre orders as we get closer to the release date. I will post an update at that time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1127306994491807386?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1127306994491807386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1127306994491807386' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1127306994491807386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1127306994491807386'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/07/new-peopletools-book.html' title='New PeopleTools Book'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-6324896323853314509</id><published>2009-05-06T15:09:00.000-07:00</published><updated>2009-05-06T15:19:17.233-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Ajax Experience '08 JavaScript Presentation</title><content type='html'>I was researching some JavaScript techniques and ran across the video &lt;a href="http://tv.adobe.com/#vi+f15643v1022"&gt;Advanced JavaScript: Closures, Prototypes, Demystified&lt;/a&gt;. If you read this blog and like the JavaScript customization ideas that you see, but aren't very comfortable with JavaScript, then watch this presentation. It does a great job of explaining some of the features of the JavaScript language.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-6324896323853314509?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/6324896323853314509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=6324896323853314509' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6324896323853314509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6324896323853314509'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/05/ajax-experience-08-javascript.html' title='Ajax Experience &apos;08 JavaScript Presentation'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2881662818562951303</id><published>2009-05-04T21:23:00.000-07:00</published><updated>2009-05-04T21:24:38.327-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Cryptography'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Encoding'/><title type='text'>Base64 Encoding with Pluggable Encryption</title><content type='html'>&lt;p&gt;I dedicate this post to &lt;a href="http://blog.greysparling.com/"&gt;Chris Heller&lt;/a&gt; since he is the person that pointed me at PeopleSoft's pluggable encryption in his comments to my last post on &lt;a href="http://jjmpsj.blogspot.com/2009/05/base64-encoding-for-peoplesoft.html"&gt;Base64 Encoding for PeopleSoft&lt;/a&gt;. I had not considered PeopleSoft's pluggable encryption for &lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;base64&lt;/a&gt; encoding. Thanks Chris!&lt;/p&gt;&lt;p&gt;Before we can base64 encode strings with &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tsec/htm/tsec13.htm#g037ee99c9453fb39_ef90c_10c791ddc07_633"&gt;PeopleSoft's Pluggable Encryption&lt;/a&gt;, we need to create an &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tsec/htm/tsec13.htm#g037ee99c9453fb39_ef90c_10c791ddc07_79f"&gt;Algorithm Chain&lt;/a&gt; and an &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tsec/htm/tsec13.htm#g037ee99c9453fb39_ef90c_10c791ddc07_7a2"&gt;Encryption Profile&lt;/a&gt;. PeopleBooks does an excellent job of explaining each of these terms as well as telling how to create each of these components. Since PeopleSoft delivers the base64 encryption algorithm with the PSPETSSL encryption library, we can move right into defining the Algorithm Chain. To define the chain, navigate to PeopleTools &amp;gt; Security &amp;gt; Encryption &amp;gt; Algorithm Chain. Add the new value BASE64_ENCODE and add the following Algorithms in order:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;PSUnicodeToAscii&lt;/li&gt;&lt;li&gt;base64_encode&lt;/li&gt;&lt;li&gt;PSAsciiToUnicode&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Be sure to set the sequence number for each row (1-3). Save and navigate to PeopleTools &amp;gt; Security &amp;gt; Encryption &amp;gt; Encryption Profile. Add the new value BASE64_ENCODE. Specify the algorithm chain BASE64_ENCODE and save. We can now test this pluggable encryption profile with a little PeopleCode:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; object &amp;amp;crypto &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr14.htm#d0e41286"&gt;&lt;span class="syntax9"&gt;CreateObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Crypt&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;)&lt;/a&gt;;&lt;br /&gt;&amp;amp;crypto.Open(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;BASE64_ENCODE&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&amp;amp;crypto.UpdateData(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Hello&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;World&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax9"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Encrypted:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;crypto.Result);&lt;/pre&gt;&lt;p&gt;And, the result should be: &lt;code&gt;SGVsbG8gV29ybGQ=&lt;/code&gt;. I am sure you will all agree that this solution is much simpler than the ugly Java Reflection I previously demonstrated. Furthermore, this method is well documented in PeopleBooks and supported by PeopleSoft.&lt;/p&gt;&lt;p&gt;If I am reading PeopleBooks right, Pluggable Encryption only works with ASCII text. That is why we have to use the PSUnicodeToAscii and PSAsciiToUnicode algorithms in our algorithm chain. What this means is that we still need to use an alternative for base64 encoding binary data, a requirement when embedding binary data in XML documents.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2881662818562951303?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2881662818562951303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2881662818562951303' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2881662818562951303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2881662818562951303'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/05/base64-encoding-with-pluggable.html' title='Base64 Encoding with Pluggable Encryption'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3784321324008132312</id><published>2009-05-03T20:25:00.000-07:00</published><updated>2009-05-04T04:17:06.674-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Cryptography'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Reflection'/><category scheme='http://www.blogger.com/atom/ns#' term='Meta-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Encoding'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Base64 Encoding for PeopleSoft</title><content type='html'>&lt;p&gt;This week on the &lt;a href="http://peoplesoft.ittoolbox.com/groups/technical-functional/peopletools-l/"&gt;ittoolbox peopeltools-I forum&lt;/a&gt;, I ran across a question on &lt;a href="http://peoplesoft.ittoolbox.com/groups/technical-functional/peopletools-l/binary-documents-within-soap-messages-2730164"&gt;base64 encoding binary data using PeopleCode&lt;/a&gt;. There are a couple of ways to base64 encode data, none of which are delivered. Before deciding which method to use, we first have to answer two questions:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Where is the data (file, database, text string)?&lt;/li&gt;&lt;li&gt;Is the data in binary or plain text format?&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If the data resides in the database, then we can select it out using the following SQL:&lt;p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;SELECT&lt;/span&gt; UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(&lt;span class="syntax13"&gt;'&lt;/span&gt;&lt;span class="syntax13"&gt;Hello&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;World&lt;/span&gt;&lt;span class="syntax13"&gt;'&lt;/span&gt;))) &lt;span class="syntax8"&gt;FROM&lt;/span&gt; DUAL;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;In fact, rewrite that as:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;SELECT&lt;/span&gt; UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(%TextIn(:&lt;span class="syntax5"&gt;1&lt;/span&gt;)))) &lt;span class="syntax8"&gt;FROM&lt;/span&gt; DUAL;&lt;/pre&gt;&lt;p&gt;And, if you are an Oracle database user, then you have a generic SQL statement you can use to base64 encode any plain text. If you name the SQL definition BASE_64_ENCODE, then you can call that SQL definition as follows:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;source &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Hello&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;World&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;encoded;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;number&lt;/span&gt; &amp;amp;i;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax9"&gt;SQLExec&lt;/span&gt;(SQL.BASE_64_ENCODE, &amp;amp;source, &amp;amp;encoded);&lt;br /&gt;&lt;span class="syntax9"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;base64:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;encoded);&lt;/pre&gt;&lt;p&gt;The PeopleCode and SQL above will work for any text string as long as you are using an Oracle database. Now, what if you want to base64 encode binary data? If the binary data is in the database, then modify the SQL accordingly.&lt;/p&gt;&lt;p&gt;Did you notice the &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl03.htm#d0e62726"&gt;%TextIn&lt;/a&gt; &lt;a href="http://jjmpsj.blogspot.com/search/label/Meta-SQL"&gt;Meta-SQL&lt;/a&gt; I sneaked into the SQL above? Use it whenever you are sending large amounts of text to the database. For a string as short as "Hello World," you don't need it, but if you are trying to base64 encode an entire XML document, then you might.&lt;/p&gt;&lt;p&gt;What if you are &lt;b&gt;not&lt;/b&gt; using Oracle database? Perhaps T-SQL has a base64 encoding routine? If so, great. If not, then the following code provides a Java/PeopleCode solution. Unfortunately, the 2 common Java base64 encoding algorithms use method and constructor overloads in a manner that requires some ugly Java reflection PeopleCode.&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;create&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;an&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;instance&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;of&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;Java&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;base64&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;encoder&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;encoder &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;sun.misc.BASE64Encoder&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;get&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;a&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;reference&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;to&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;a&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;Java&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;class&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;instance&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;for&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;primitive&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;byte&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;array&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;arrayClass &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.reflect.Array&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;bytArrClass &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;arrayClass.newInstance(&lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Byte&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).TYPE, &lt;span class="syntax5"&gt;0&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;use&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;reflection&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;to&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;get&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;a&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;reference&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;to&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;method&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;we&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;want&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;to&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;call&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;encodeArgTypes &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Class[]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;bytArrClass.getClass());&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;encodeMethod &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;encoder.getClass().getMethod(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;encode&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;encodeArgTypes);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;call&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;method&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;bytes &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.String&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Hello&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;World&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).getBytes();&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;result &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;encodeMethod.invoke(&amp;amp;encoder, &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Object[]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;bytes));&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;print&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;result&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax9"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Result:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;result.toString());&lt;/pre&gt;&lt;p&gt;If you know enough about Java to compile a wrapper class and you have access to your app server's class directory, then you can eliminate the Java reflection code in favor of a wrapper:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax9"&gt;package&lt;/span&gt; com.blogspot.jjmpsj;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax9"&gt;import&lt;/span&gt; java.io.IOException;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax9"&gt;import&lt;/span&gt; sun.misc.BASE64Encoder;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;public&lt;/span&gt; &lt;span class="syntax10"&gt;class&lt;/span&gt; Base64Coder &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax8"&gt;public&lt;/span&gt; &lt;span class="syntax8"&gt;static&lt;/span&gt; String &lt;span class="syntax6"&gt;encodeString&lt;/span&gt;(String data) &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        BASE64Encoder encoder &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;BASE64Encoder&lt;/span&gt;();&lt;br /&gt;        &lt;span class="syntax8"&gt;return&lt;/span&gt; encoder.&lt;span class="syntax6"&gt;encode&lt;/span&gt;(data.&lt;span class="syntax6"&gt;getBytes&lt;/span&gt;());&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="syntax8"&gt;public&lt;/span&gt; &lt;span class="syntax8"&gt;static&lt;/span&gt; String &lt;span class="syntax6"&gt;encodeBytes&lt;/span&gt;(&lt;span class="syntax10"&gt;byte&lt;/span&gt;[] data) &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        BASE64Encoder encoder &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;BASE64Encoder&lt;/span&gt;();&lt;br /&gt;        &lt;span class="syntax8"&gt;return&lt;/span&gt; encoder.&lt;span class="syntax6"&gt;encode&lt;/span&gt;(data);&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;... and call it like so:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;encoder &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;com.blogspot.jjmpsj.Base64Coder&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;result &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;encoder.encodeString(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Hello&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;World&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax9"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &amp;amp;result);&lt;/pre&gt;&lt;p&gt;As you can see from this final example, when working with overloaded constructors and methods, Java wrappers dramatically simplify PeopleCode.&lt;/p&gt;&lt;p&gt;Each of the examples above uses "Hello World" as the text string. What is "Hello World" in base64? &lt;code&gt;SGVsbG8gV29ybGQ=&lt;/code&gt;. You can find an online base64 encoder/decoder &lt;a href="http://www.motobit.com/util/base64-decoder-encoder.asp"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I will have to leave the question of base64 encoding binary files for another day. I am on the East coast attending Collaborate '09 and I need to get some rest so I can be &lt;a href="http://idioms.thefreedictionary.com/be+as+right+as+rain"&gt;right as rain&lt;/a&gt; for the conference tomorrow morning.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update May 4th, 2009 at 4:09 AM:&lt;/b&gt; In the comments to this post, &lt;a href="http://devwfb.blogspot.com/"&gt;devwfb&lt;/a&gt; suggests that developers use &lt;a href="http://commons.apache.org/codec/"&gt;&lt;code&gt;org.apache.commons.codec.binary.Base64&lt;br /&gt;&lt;/code&gt;&lt;/a&gt; rather than &lt;code&gt;sun.misc.BASE64Encoder&lt;/code&gt; because classes in the sun package are undocumented and unsupported. &lt;a href="http://devwfb.blogspot.com/"&gt;devwfb&lt;/a&gt; is right and I should have mentioned this fact in my original post.  I chose to use sun's base64 encoder because it is delivered and doesn't require customers to add more jars to the $PS_HOME/class directory. I will post the commons-codec example and link to it from here. See &lt;a href="http://java.sun.com/products/jdk/faq/faq-sun-packages.html"&gt;Sun's FAQ&lt;/a&gt; for more information.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3784321324008132312?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3784321324008132312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3784321324008132312' title='27 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3784321324008132312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3784321324008132312'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/05/base64-encoding-for-peoplesoft.html' title='Base64 Encoding for PeopleSoft'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>27</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1266738535690853272</id><published>2009-05-03T12:56:00.000-07:00</published><updated>2009-05-03T13:02:00.247-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Meta-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Productivity gains through Meta-SQL</title><content type='html'>&lt;p&gt;I hope the designer of PeopleSoft's &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl03.htm#g037ee99c9453fb39_ef90c_10c791ddc07__3e72"&gt;Meta-SQL&lt;/a&gt; is extremely wealthy. I believe Meta-SQL usage is one of the most under utilized PeopleTools development practices. Do you want to improve your productivity as a PeopleSoft developer? Learn Meta-SQL. Consider the &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl03.htm#d0e60955"&gt;%InsertSelect&lt;/a&gt; Meta-SQL statement... A PeopleSoft SQL &lt;em&gt;insert into/select from&lt;/em&gt; statement may contain 100 or more fields. Maintaining the mappings between the insert clause and the select clause can be quite daunting. &lt;code&gt;%InsertSelect&lt;/code&gt; eliminates this mapping nightmare through &lt;a href="http://en.wikipedia.org/wiki/Convention_over_Configuration"&gt;convention&lt;/a&gt;: source fields with the same name are automatically mapped to destinations with the same name. If your scenario deviates from this convention, then a minor configuration in the Meta-SQL statement allows you to override the default behavior.&lt;/p&gt;&lt;p&gt;Likewise, using Meta-SQL, it is possible to write generic SQL that works regardless of the target table. Consider the following PeopleCode:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;Record&lt;/span&gt; &amp;amp;rec &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateRecord&lt;/span&gt;(&lt;span class="syntax10"&gt;Record&lt;/span&gt;.xxx);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;exists;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;set&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;&amp;amp;rec&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;key&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;field&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;values,&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;copy&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;from&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;component&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;buffer,&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;etc&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax9"&gt;SQLExec&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;SELECT&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;'X'&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FROM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;%Table(:1)&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;WHERE&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;%KeyEqual(:1)&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;rec, &amp;amp;exists);&lt;/pre&gt;&lt;p&gt;No matter what table I specify, this same SQL statement will tell me if a matching row exists in that table. PeopleSoft includes many of these &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl03.htm#d0e63522"&gt;Meta-SQL shortcuts&lt;/a&gt;. By combining a couple of Meta-SQL statements into a FUNCLIB, I can create a generic PeopleCode compliment to the Oracle merge statement (some call it &lt;a href="http://en.wikipedia.org/wiki/Upsert"&gt;UPSERT&lt;/a&gt;):&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; Merge(&amp;amp;rec As &lt;span class="syntax10"&gt;Record&lt;/span&gt;)&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;exists;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax9"&gt;SQLExec&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;SELECT&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;'X'&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FROM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;%Table(:1)&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;WHERE&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;%KeyEqual(:1)&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;rec, &amp;amp;exists);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax8"&gt;If&lt;/span&gt; (&lt;span class="syntax9"&gt;All&lt;/span&gt;(&amp;amp;exists)) &lt;span class="syntax8"&gt;Then&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax9"&gt;SQLExec&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;%Update(:1)&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;rec);&lt;br /&gt;   &lt;span class="syntax8"&gt;Else&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax9"&gt;SQLExec&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;%Insert(:1)&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;rec);&lt;br /&gt;   &lt;span class="syntax8"&gt;End-If&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;/pre&gt;&lt;p&gt;Where would I use a merge function like this? Let's say you need to clone data in the current buffer, but change a key field (EFFDT perhaps?). Using the Copy methods of stand-alone &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr34.htm#d0e128760"&gt;Rowsets&lt;/a&gt; and &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr32.htm#d0e125613"&gt;Records&lt;/a&gt;, I can copy the component buffer into stand-alone rowsets and records, change the key fields, and then, with a generic loop, iterate over the rows and records, inserting or updating database values using the Merge function above.&lt;/p&gt;&lt;p&gt;There are several Meta-SQL routines. Some exist to provide database independence, but many exist to provide meta-data driven shortcuts for repetitive tasks. I encourage you to take some time to review the PeopleBooks Meta-SQL documentation. I trust you will be pleasantly surprised with the productivity gains you can achieve through Meta-SQL. Now, if I could just get someone to create an open source port of PeopleSoft's Meta-SQL that I can use with JDBC...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1266738535690853272?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1266738535690853272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1266738535690853272' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1266738535690853272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1266738535690853272'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/05/productivity-gains-through-meta-sql.html' title='Productivity gains through Meta-SQL'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-4249130531966466420</id><published>2009-04-13T15:00:00.000-07:00</published><updated>2010-04-20T06:26:32.789-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Test Driven Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Extreme Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Application Classes'/><category scheme='http://www.blogger.com/atom/ns#' term='PSUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>"Introducing PSUnit" now in Wiki</title><content type='html'>&lt;p&gt;I just moved the "Introducing PSUnit" document to Oracle's Wiki: &lt;a href="http://wiki.oracle.com/page/Introducing+PSUnit"&gt;Introducing PSUnit&lt;/a&gt;. Please feel free to update, discuss, and contribute using the tools provided by Oracle's Wiki.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-4249130531966466420?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/4249130531966466420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=4249130531966466420' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4249130531966466420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4249130531966466420'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/04/introducing-psunit-now-in-wiki.html' title='&quot;Introducing PSUnit&quot; now in Wiki'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-8303792766737410608</id><published>2009-04-10T16:37:00.000-07:00</published><updated>2009-04-10T16:42:25.438-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>Collaborate '09</title><content type='html'>&lt;p&gt;&lt;a href="http://www.collaborate09.com/"&gt;Collaborate '09&lt;/a&gt; is less than a month away. I will presenting session 61450 - PeopleTools Tips and Techniques on Tuesday from 4:30 pm to 5:30 pm. See you there!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-8303792766737410608?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/8303792766737410608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=8303792766737410608' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8303792766737410608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8303792766737410608'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/04/collaborate-09.html' title='Collaborate &apos;09'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2332538092353082615</id><published>2009-04-08T21:51:00.000-07:00</published><updated>2009-04-08T21:55:14.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='IScripts'/><title type='text'>Using JDBC to Execute Stored Procedures with Output Parameters</title><content type='html'>&lt;p&gt;PeopleSoft allows developers to execute database stored procedures using PeopleCode that resembles &lt;code&gt;SQLExec("EXEC PACKAGE.PROC_NAME(:1, :2)", &amp;bind1, &amp;bind2);&lt;/code&gt;. Even though stored procedures can have input and output parameters, &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e50665"&gt;SQLExec&lt;/a&gt; discards output parameters. Several years ago I found an interesting post that described how to use &lt;a href="http://download.oracle.com/docs/cd/F49540_01/DOC/server.815/a68001/dbms_pip.htm"&gt;DBMS_PIPE&lt;/a&gt; with Oracle database to return output parameters, but, it appears the author removed that post. What made the &lt;code&gt;DBMS_PIPE&lt;/code&gt; solution so compelling was that it shared the PeopleSoft database connection. The alternative presented below, unfortunately, requires you to maintain a user name and password, preferably encrypted and stored in a secure location. Because of the class loading issues mentioned in my post &lt;a href="http://jjmpsj.blogspot.com/2009/03/using-oracle-jdbc-from-peoplecode.html"&gt;Using Oracle JDBC from PeopleCode&lt;/a&gt;, this post uses the Oracle specific data access classes. If you use a different database, the classes will differ, but the concept is the same. Furthermore, if you use a different database and JDBC driver, you may be able to use the standard, generic JDBC classes as described in the PSST0101 post &lt;a href="http://psst0101.wordpress.com/2008/07/29/writing-to-access-databases/"&gt;Writing to Access Databases&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Before demonstrating how to call a stored procedure from PeopleCode, we need a stored procedure to call. The following &lt;a href="http://en.wikipedia.org/wiki/PL_SQL"&gt;PL/SQL&lt;/a&gt; describes a stored procedure that has two parameters: one in and one in/out. The implementation of the procedure hard codes the output value for simplicity.&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;CREATE&lt;/span&gt; &lt;span class="syntax8"&gt;OR&lt;/span&gt; &lt;span class="syntax9"&gt;REPLACE&lt;/span&gt; &lt;span class="syntax8"&gt;PACKAGE&lt;/span&gt; JJM_IN_OUT &lt;span class="syntax8"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="syntax8"&gt;PROCEDURE&lt;/span&gt; P(&lt;br /&gt;    IN1    &lt;span class="syntax8"&gt;IN&lt;/span&gt;     &lt;span class="syntax8"&gt;VARCHAR2&lt;/span&gt;,&lt;br /&gt;    INOUT1 &lt;span class="syntax8"&gt;IN&lt;/span&gt; &lt;span class="syntax8"&gt;OUT&lt;/span&gt; &lt;span class="syntax8"&gt;VARCHAR2&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax8"&gt;END&lt;/span&gt; JJM_IN_OUT;&lt;br /&gt;&lt;span class="syntax18"&gt;/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;CREATE&lt;/span&gt; &lt;span class="syntax8"&gt;OR&lt;/span&gt; &lt;span class="syntax9"&gt;REPLACE&lt;/span&gt; &lt;span class="syntax8"&gt;PACKAGE&lt;/span&gt; &lt;span class="syntax8"&gt;BODY&lt;/span&gt; JJM_IN_OUT &lt;span class="syntax8"&gt;AS&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax8"&gt;PROCEDURE&lt;/span&gt; P(&lt;br /&gt;    IN1    &lt;span class="syntax8"&gt;IN&lt;/span&gt;     &lt;span class="syntax8"&gt;VARCHAR2&lt;/span&gt;,&lt;br /&gt;    INOUT1 &lt;span class="syntax8"&gt;IN&lt;/span&gt; &lt;span class="syntax8"&gt;OUT&lt;/span&gt; &lt;span class="syntax8"&gt;VARCHAR2&lt;/span&gt;) &lt;span class="syntax8"&gt;IS&lt;/span&gt;&lt;br /&gt;  &lt;span class="syntax8"&gt;BEGIN&lt;/span&gt;&lt;br /&gt;    INOUT1 &lt;span class="syntax18"&gt;:=&lt;/span&gt; &lt;span class="syntax13"&gt;'&lt;/span&gt;&lt;span class="syntax13"&gt;Hello World&lt;/span&gt;&lt;span class="syntax13"&gt;'&lt;/span&gt;;&lt;br /&gt;  &lt;span class="syntax8"&gt;END&lt;/span&gt; P;&lt;br /&gt;&lt;span class="syntax8"&gt;END&lt;/span&gt; JJM_IN_OUT;&lt;br /&gt;&lt;span class="syntax18"&gt;/&lt;/span&gt;&lt;br /&gt;show errors&lt;/pre&gt;&lt;p&gt;To build this package, copy the PL/SQL above into a text editor and then run it from &lt;a href="http://www.oracle.com/technology/docs/tech/sql_plus/index.html"&gt;SQLPlus&lt;/a&gt;. The procedure test follows:&lt;/p&gt;&lt;pre&gt;SQL&amp;gt; var out1 varchar2(100)&lt;br /&gt;SQL&amp;gt; exec JJM_IN_OUT.P('x', :out1);&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; print out1&lt;br /&gt;&lt;br /&gt;OUT1&lt;br /&gt;-------------------------------------------------------&lt;br /&gt;Hello World&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;&lt;/pre&gt;&lt;p&gt;The following &lt;a href="http://jjmpsj.blogspot.com/search/label/IScripts"&gt;IScript&lt;/a&gt; demonstrates calling a procedure with in/out parameters from PeopleCode:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; IScript_OutParms()&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;driver &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;oracle.jdbc.OracleDriver&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;info &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.util.Properties&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &amp;amp;info.put(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;user&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;dbuser&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &amp;amp;info.put(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;password&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;secret&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;conn &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;driver.connect(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;jdbc:oracle:thin:@server:1521:SID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;info);&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;stmt &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;conn.prepareCall(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;{call&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;JJM_IN_OUT.P&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;(?,?)}&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;types &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.sql.Types&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;set&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;input&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;parameter&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;values&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;   &amp;amp;stmt.setString(&lt;span class="syntax5"&gt;1&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;aa&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &amp;amp;stmt.setString(&lt;span class="syntax5"&gt;2&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;bb&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;register&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;second&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;parameter&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;as&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;a&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;output&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;parameter&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;   &amp;amp;stmt.registerOutParameter(&lt;span class="syntax5"&gt;2&lt;/span&gt;, &amp;amp;types.VARCHAR);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax2"&gt;REM ** execute the SQL statement;&lt;/span&gt;&lt;br /&gt;   &amp;amp;stmt.execute();&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.SetContentType(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;text/plain&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;Display&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;value&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;of&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;second&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;parameter&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.WriteLine(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;JJM_IN_OUT.P&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;output&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;parameter&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;value:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;stmt.getString(&lt;span class="syntax5"&gt;2&lt;/span&gt;));&lt;br /&gt;   &lt;br /&gt;   &amp;amp;conn.close();&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;/pre&gt;&lt;p&gt;After making the connection, the code prepares an SQL statement: &lt;code&gt;{call JJM_IN_OUT.P (?,?)}&lt;/code&gt;. JDBC procedure calls use the syntax &lt;code&gt;{call proc_name (?,?)}&lt;/code&gt; (the question marks represent the procedure's parameters).&lt;/p&gt;&lt;p&gt;The code above is for demonstration purposes only. Be sure to store the database user name and password in a secure manner. When executing SQL using a second connection, be sure to consider deadlock, race conditions, etc.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2332538092353082615?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2332538092353082615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2332538092353082615' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2332538092353082615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2332538092353082615'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/04/using-jdbc-to-execute-stored-procedures.html' title='Using JDBC to Execute Stored Procedures with Output Parameters'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-8242607149297262958</id><published>2009-03-25T07:15:00.000-07:00</published><updated>2009-03-25T07:35:26.456-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>JSON In (and out) of Oracle - JSON Data Type</title><content type='html'>&lt;p&gt;&lt;a href="http://www.linkedin.com/in/lewiscunningham"&gt;Lewis Cunningham&lt;/a&gt; just posted this link in a comment to one of my &lt;a href="http://jjmpsj.blogspot.com/search/label/JSON"&gt;JSON&lt;/a&gt; posts: &lt;a href="http://database-geek.com/2009/03/25/json-in-and-out-of-oracle-json-data-type/"&gt;JSON In (and out) of Oracle - JSON Data Type&lt;/a&gt;. Nice work Lewis!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-8242607149297262958?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/8242607149297262958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=8242607149297262958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8242607149297262958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8242607149297262958'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/03/json-in-and-out-of-oracle-json-data.html' title='JSON In (and out) of Oracle - JSON Data Type'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-8386211493747043713</id><published>2009-03-23T06:47:00.000-07:00</published><updated>2009-03-23T18:42:45.175-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='ServletFilters'/><category scheme='http://www.blogger.com/atom/ns#' term='Web server'/><title type='text'>GZip Compress Static Files</title><content type='html'>&lt;p&gt;My PeopleSoft web server contains several JavaScript and CSS files that I embed in PeopleSoft pages using the various techniques described in this blog. Unlike files served by the PeopleSoft application, the web server does not GZip compress these static text files. Until recently, I used the GZip ServletFilter described by Jayson Falkner in his post &lt;a href="http://www.onjava.com/pub/a/onjava/2003/11/19/filters.html"&gt;Two Servlet Filters Every Web Application Should Have&lt;/a&gt;. But GZipping every request for the same static file seemed like an unnecessary waste of CPU cycles. I got to thinking...&lt;/p&gt;&lt;blockquote&gt;Could I eliminate the CPU cycles expended by GZipping those static files on every request? Is there a way store static GZipped content and serve the GZipped version to browsers that accept GZip encoding while still making the plain text version available to other browsers?&lt;/blockquote&gt;&lt;p&gt;Here is the solution I cooked up: using the following rules with the tuckey.org &lt;a href="http://tuckey.org/urlrewrite/"&gt;UrlRewriteFilter&lt;/a&gt; ServletFilter, I can serve a static GZip file to browsers that accept GZip compression while still serving the plain text version to browsers that don't.&lt;/p&gt;&lt;p&gt;The URL Rewrite rules:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax1"&gt;&amp;lt;!--&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;Browsers&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;that&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;support&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;GZip&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;header&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;name&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Accept-Encoding&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;.*gzip.*&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;^/scripts/([^&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;lt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;gt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;:"/\|?*]+\.js)$&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;forward&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;/compressed/bin/scripts/$1.gz&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;set&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;response-header&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;name&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Content-Encoding&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;gzip&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;set&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;header&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;name&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Accept-Encoding&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;.*gzip.*&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;^/css/([^&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;lt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;gt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;:"/\|?*]+\.css)$&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;forward&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;/compressed/bin/css/$1.gz&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;set&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;response-header&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;name&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Content-Encoding&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;gzip&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;set&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax1"&gt;&amp;lt;!--&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;Browsers&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;that&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;do&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;NOT&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;support&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;GZip&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;header&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;name&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Accept-Encoding&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;operator&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;notequal&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;.*gzip.*&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;^/scripts/([^&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;lt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;gt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;:"/\|?*]+\.js)$&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;forward&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;/compressed/minified/scripts/$1&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;header&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;name&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Accept-Encoding&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;operator&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;notequal&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;.*gzip.*&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;condition&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;^/css/([^&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;lt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;&lt;span class="syntax14"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax14"&gt;gt&lt;/span&gt;&lt;span class="syntax14"&gt;;&lt;/span&gt;:"/\|?*]+\.css)$&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;from&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;forward&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;/compressed/minified/css/$1&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;to&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;rule&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;From this rules file, you can see that I store GZip compressed versions of my JavaScript files in /compressed/bin/scripts. If a requesting browser has the value &lt;code&gt;gzip&lt;/code&gt; in the Accept-Encoding header and the request is for a file in the /scripts/ directory, then the first rule tells the UrlRewriteFilter to add the response header &lt;code&gt;Content-Encoding: gzip&lt;/code&gt; and serve the version located at /compressed/bin/scripts/. Rule #2 is similar, but for CSS files. Rules 3 and 4 are the inverse of rules 1 and 2, telling the UrlRewriteFilter to serve files from /compressed/minified/scripts/ and /compressed/minified/css/. For example, if an IE 7 browser requests /scripts/jquery-1.3.2.min.js, then the UrlRewriteFilter will add the &lt;code&gt;Content-Encoding: gzip&lt;/code&gt; response header and serve /compressed/bin/scripts/jquery-1.3.2.min.js.gz. If an &lt;a href="http://search.cpan.org/~gaas/libwww-perl-5.825/lib/LWP.pm"&gt;LWP&lt;/a&gt; Perl browser posted the same request, then the UrlRewriteFilter would serve the file located at /compressed/minified/scripts/jquery-1.3.2.min.js (assuming the LWP Accept-Encoding header is not set).&lt;/p&gt;&lt;p&gt;Using URL Rewriting in this manner, I don't serve files from my /scripts/ and /css/ directories, and, therefore, don't need these directories on my web server. To avoid confusion caused by developers searching for these files on my web server, I put readme.txt files in each of these directories to explain that URL's pointing at these directories are rewritten to the /compressed directory.&lt;/p&gt;&lt;p&gt;If you use the UrlRewriteFilter, then be sure to use &lt;code&gt;filter-mapping&lt;/code&gt; patterns that won't rewrite PeopleSoft URL's. Here are my mappings for the /css/ and /scripts/ URL's&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;filter-mapping&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;filter-name&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;GzipFilter&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;filter-name&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;url-pattern&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;/scripts/*&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;url-pattern&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;filter-mapping&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;filter-mapping&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;filter-name&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;GzipFilter&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;filter-name&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;url-pattern&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;/css/*&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;url-pattern&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;filter-mapping&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;You can create GZip versions of your files using the following command:&lt;/p&gt;&lt;pre&gt;cat $file_location/scripts/jquery.js | gzip --stdout -9 &gt; $file_location/bin/scripts/jquery.js.gz&lt;/pre&gt;&lt;p&gt;And on Windows:&lt;/p&gt;&lt;pre&gt;cat %file_location%\scripts\jquery.js | gzip --stdout -9 &gt; %file_location%\bin\scripts\jquery.js.gz&lt;/pre&gt;&lt;p&gt;Unfortunately, Windows doesn't have a &lt;code&gt;cat&lt;/code&gt; or &lt;code&gt;gzip&lt;/code&gt; command. To utilize these commands on Windows, I recommend installing &lt;a href="http://unxutils.sourceforge.net/"&gt;UnxUtils&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Caveat: adding ServletFilters as described in this post may violate your PeopleSoft limited use web server license. Consult your license agreement to ensure compliance. If you use WebLogic, you can leverage the full power of your WebLogic instance by purchasing a WebLogic license from your Oracle rep. For a low cost alternative, you can reverse proxy your PeopleSoft web server with Apache's &lt;a href="http://httpd.apache.org/"&gt;httpd&lt;/a&gt; server and use Apache's URL Rewrite engine (&lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html"&gt;mod_rewrite&lt;/a&gt;) instead of the ServletFilter mentioned in this post.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-8386211493747043713?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/8386211493747043713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=8386211493747043713' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8386211493747043713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/8386211493747043713'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/03/gzip-compress-static-files.html' title='GZip Compress Static Files'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1700049069149254733</id><published>2009-03-22T22:26:00.000-07:00</published><updated>2009-03-22T22:35:18.597-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><title type='text'>PeopleSoft as a Password Authentication "Ticket" Server</title><content type='html'>&lt;p&gt;My post &lt;a href="http://jjmpsj.blogspot.com/2008/07/generating-authtoken-for-switchuser.html"&gt;Generating an AuthToken for SwitchUser&lt;/a&gt; demonstrates how to acquire and expire PeopleSoft authentication tokens. Using this approach, you could hook any custom application into the PeopleSoft security model, allowing PeopleSoft to manage security for many of your custom enterprise applications. Continuous token (ticket) validation could be implemented through a very simple web service that calls &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e51764"&gt;SwitchUser&lt;/a&gt; and returns the result. If &lt;code&gt;SwitchUser&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;, then the token is valid.&lt;/p&gt;&lt;p&gt;Really, if you are interested in a centeralized, integrated security solution, then you should speak with your Oracle rep about Oracle's &lt;a href="http://www.oracle.com/technology/products/id_mgmt/index.html"&gt;Identity Management Suite&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1700049069149254733?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1700049069149254733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1700049069149254733' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1700049069149254733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1700049069149254733'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/03/peoplesoft-as-password-authentication.html' title='PeopleSoft as a Password Authentication &quot;Ticket&quot; Server'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-654230938563416320</id><published>2009-03-22T22:16:00.000-07:00</published><updated>2009-03-22T22:16:25.335-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleTools'/><title type='text'>Generating an AuthToken for SwitchUser</title><content type='html'>&lt;p&gt;As the name implies, the PeopleCode &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e51764"&gt;SwitchUser&lt;/a&gt; function allows developers to switch the logged in Operator ID from one user to another. For security reasons, you can only switch identities if you either have another user's operator ID and password or another user's valid authentication token (AuthToken). While I'm sure there are numerous uses for this function, here are my top two:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Presenting a sign on Pagelet to a GUEST user&lt;/li&gt;&lt;li&gt;Switching the runtime context of Integration Broker PeopleCode&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In both of these scenarios, PeopleCode is already running as one user, but you need to switch the runtime context to a different user. For example, if we build a web service that exposes Approval Workflow Engine (AWE) approvals, we must authenticate the caller to ensure the caller has access to a specific approval.&lt;/p&gt;&lt;p&gt;The PeopleCode &lt;code&gt;SwitchUser&lt;/code&gt; function takes four parameters. If you use the first two parameters, &lt;code&gt;UserID&lt;/code&gt; and &lt;code&gt;Password&lt;/code&gt;, then you don't use the third. Likewise, if you use the third parameter, &lt;code&gt;AuthToken&lt;/code&gt;, then you don't use the first and second. They are mutually exclusive. The fourth parameter is irrelevant for this discussion. Since the first two parameters are self explanatory, the remainder of this discussion will focus on the third parameter, the &lt;code&gt;AuthToken&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Let's further consider the AWE example. Here is the scenario:&lt;/p&gt;&lt;blockquote&gt;Managers want to approve AWE transactions from their mobile devices (BlackBerry, iPhone, etc). PeopleSoft, however, does not support mobile browsers. One method to enable mobile access is to create a stand alone web application that communicates with PeopleSoft using web services. The initial page for this web application will prompt the user for a PeopleSoft user name and password. The second page of this web application will display information about an approval and provide the manager with action buttons to approve, deny, or push back the transaction. When the manager selects one of the action buttons, the web application will use web services to update the PeopleSoft AWE transaction.&lt;/blockquote&gt;&lt;p&gt;The process flow in this scenario requires the web application to call at least two PeopleSoft web services. Since web services are stateless, we need to authenticate the user on each call. Because these web service calls span multiple request/response cycles, the web application will need to store that authentication information between mobile client requests, making session variables the logical place to store this information. At this point, the question we need to ask is, "What authentication information do we want to store in a session variable?" User name and password? As an alternative, we could store an AuthToken in a session variable and use that as a parameter to &lt;code&gt;SwitchUser&lt;/code&gt;. Unlike user names and passwords, authentication tokens can be invalidated and are subject to configurable expiration rules.&lt;/p&gt;&lt;p&gt;How do you generate an AuthToken? Here is the method I use: I create an HTTP connection to my PeopleSoft server's sign on URL and then parse the returned cookies. Here is an example that uses Java and Jakarta Commons &lt;a href="http://hc.apache.org/httpclient-3.x/"&gt;HttpClient&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;HttpClient client &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;HttpClient&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;//&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;Posting&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;to&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;the&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;PS&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;login&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;URL&lt;/span&gt;&lt;br /&gt;PostMethod post &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;PostMethod&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;http://my.ps-server.com/psp/hrms/?cmd=login&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;post.&lt;span class="syntax6"&gt;addParameter&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;userid&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, username);&lt;br /&gt;post.&lt;span class="syntax6"&gt;addParameter&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;pwd&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, password);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;//&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;expect&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;redirect&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;response&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;code&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;if&lt;/span&gt;(client.&lt;span class="syntax6"&gt;executeMethod&lt;/span&gt;(post) &lt;span class="syntax18"&gt;!&lt;/span&gt;&lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax5"&gt;302&lt;/span&gt;) &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax8"&gt;throw&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;Exception&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Expected&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;a&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;redirect&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;response&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;code.&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Cookie[] cookies &lt;span class="syntax18"&gt;=&lt;/span&gt; client.&lt;span class="syntax6"&gt;getState&lt;/span&gt;().&lt;span class="syntax6"&gt;getCookies&lt;/span&gt;();&lt;br /&gt;Cookie pstokenCookie &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax14"&gt;null&lt;/span&gt;;&lt;br /&gt;String pstoken &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax14"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;for&lt;/span&gt; (&lt;span class="syntax10"&gt;int&lt;/span&gt; cookieIdx &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax5"&gt;0&lt;/span&gt;; cookieIdx &lt;span class="syntax18"&gt;&amp;lt;&lt;/span&gt; cookies.length; cookieIdx&lt;span class="syntax18"&gt;+&lt;/span&gt;&lt;span class="syntax18"&gt;+&lt;/span&gt;) &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;    Cookie cookie &lt;span class="syntax18"&gt;=&lt;/span&gt; cookies[cookieIdx];&lt;br /&gt;    &lt;span class="syntax8"&gt;if&lt;/span&gt; (cookie.&lt;span class="syntax6"&gt;getName&lt;/span&gt;().&lt;span class="syntax6"&gt;equals&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;PS_TOKEN&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;) &lt;span class="syntax18"&gt;&amp;amp;&lt;/span&gt;&lt;span class="syntax18"&gt;&amp;amp;&lt;/span&gt; &lt;br /&gt;        cookie.&lt;span class="syntax6"&gt;getDomain&lt;/span&gt;().&lt;span class="syntax6"&gt;equals&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;.ps-server.com&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;)) &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        pstoken &lt;span class="syntax18"&gt;=&lt;/span&gt; cookie.&lt;span class="syntax6"&gt;getValue&lt;/span&gt;();&lt;br /&gt;        pstokenCookie &lt;span class="syntax18"&gt;=&lt;/span&gt; cookie;&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;if&lt;/span&gt; (pstoken &lt;span class="syntax18"&gt;=&lt;/span&gt;&lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax14"&gt;null&lt;/span&gt;) &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax8"&gt;throw&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;Exception&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Ack!&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Didn't&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;find&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;PS_TOKEN&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;cookie&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;With my AuthToken (PS_TOKEN) identified, I can store it in a session variable, pass it along to Integration Broker, and then invalidate it when the mobile user logs out. Here is some sample code that demonstrates how to invalidate an AuthToken:&lt;/p&gt;&lt;pre&gt;HttpClient client &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;HttpClient&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;client.&lt;span class="syntax6"&gt;getState&lt;/span&gt;().&lt;span class="syntax6"&gt;addCookie&lt;/span&gt;(pstokenCookie);&lt;br /&gt;&lt;br /&gt;GetMethod get &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;GetMethod&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;http://my.ps-server.com/psp/hrms/?cmd=logout&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax10"&gt;int&lt;/span&gt; httpResponseCode &lt;span class="syntax18"&gt;=&lt;/span&gt; client.&lt;span class="syntax6"&gt;executeMethod&lt;/span&gt;(get);&lt;br /&gt;&lt;span class="syntax2"&gt;//&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;TODO:&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;validate&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;response&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;code&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-654230938563416320?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/654230938563416320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=654230938563416320' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/654230938563416320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/654230938563416320'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/07/generating-authtoken-for-switchuser.html' title='Generating an AuthToken for SwitchUser'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3981960545453427126</id><published>2009-03-21T09:44:00.000-07:00</published><updated>2010-04-20T06:26:01.746-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Test Driven Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Extreme Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='PSUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='XP'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleTools'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Test Driven Development for PeopleSoft</title><content type='html'>&lt;p&gt;The PeopleTools blogging team just released an &lt;strong&gt;unsupported&lt;/strong&gt; tool for test driven PeopleCode development: &lt;a href="http://blogs.oracle.com/peopletools/"&gt;PSUnit&lt;/a&gt;. The blog post contains the PSUnit source code and a document that describes how to use PSUnit to test drive PeopleCode development. If you are familiar with one of the xUnit frameworks (&lt;a href="http://www.junit.org/"&gt;jUnit&lt;/a&gt;, &lt;a href="http://www.nunit.org/index.php"&gt;nUnit&lt;/a&gt;, &lt;a href="http://utplsql.sourceforge.net/"&gt;utPLSQL&lt;/a&gt;, &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html"&gt;Test::Unit&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks"&gt;etc&lt;/a&gt;) and &lt;a href="http://en.wikipedia.org/wiki/Extreme_Programming"&gt;eXtreme Programming&lt;/a&gt;, then you know the value of test driven development. If you are new to Test Driven Development (TDD), then take a look at Kent Beck's book &lt;a href="http://search.barnesandnoble.com/Test-Driven-Development/Kent-Beck/e/9780321146533/?itm=1"&gt;Test Driven Development by Example&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;As a fellow PeopleCode programmer, I believe we can create better solutions by applying proven disciplines and methodologies to PeopleCode development.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3981960545453427126?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3981960545453427126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3981960545453427126' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3981960545453427126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3981960545453427126'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/03/test-driven-development-for-peoplesoft.html' title='Test Driven Development for PeopleSoft'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-6598605072168521968</id><published>2009-03-19T08:20:00.000-07:00</published><updated>2009-03-19T08:21:11.593-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='IScripts'/><title type='text'>Serve JSON from PeopleSoft</title><content type='html'>&lt;p&gt;Last month a reader asked me for an example of serving &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt; from PeopleSoft. The following &lt;a href="http://jjmpsj.blogspot.com/search/label/IScripts"&gt;IScript&lt;/a&gt; demonstrates how to serve JSON by printing user and role information in JSON format:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; IScript_GetJSON&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; SQL &amp;amp;usersCursor &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e12439"&gt;CreateSQL&lt;/a&gt;&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;SELECT&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;OPRID,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;OPRDEFNDESC,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;EMAILID&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FROM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;PSOPRDEFN&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;WHERE&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ROWNUM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;6&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; SQL &amp;amp;rolesCursor;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;oprid;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;oprdefndesc;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;emailid;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;rolename;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;boolean&lt;/span&gt; &amp;amp;isFirstUser &lt;span class="syntax18"&gt;=&lt;/span&gt; True;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;boolean&lt;/span&gt; &amp;amp;isFirstRole &lt;span class="syntax18"&gt;=&lt;/span&gt; True;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax11"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#d0e65641"&gt;%Response&lt;/a&gt;&lt;/span&gt;.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr19.htm#d0e51121"&gt;Write&lt;/a&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;[&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax8"&gt;While&lt;/span&gt; &amp;amp;usersCursor.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr39.htm#d0e142627"&gt;Fetch&lt;/a&gt;(&amp;amp;oprid, &amp;amp;oprdefndesc, &amp;amp;emailid)&lt;br /&gt;      &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;comma&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;logic&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="syntax8"&gt;If&lt;/span&gt; (&amp;amp;isFirstUser) &lt;span class="syntax8"&gt;Then&lt;/span&gt;&lt;br /&gt;         &amp;amp;isFirstUser &lt;span class="syntax18"&gt;=&lt;/span&gt; False;&lt;br /&gt;      &lt;span class="syntax8"&gt;Else&lt;/span&gt;&lt;br /&gt;         &lt;span class="syntax11"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#d0e65641"&gt;%Response&lt;/a&gt;&lt;/span&gt;.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr19.htm#d0e51121"&gt;Write&lt;/a&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;      &lt;span class="syntax8"&gt;End-If&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;      &lt;span class="syntax11"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#d0e65641"&gt;%Response&lt;/a&gt;&lt;/span&gt;.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr19.htm#d0e51121"&gt;Write&lt;/a&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;{&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e19241"&gt;EscapeJavascriptString&lt;/a&gt;&lt;/span&gt;(&amp;amp;oprid) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRDEFNDESC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e19241"&gt;EscapeJavascriptString&lt;/a&gt;&lt;/span&gt;(&amp;amp;oprdefndesc) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMAILID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e19241"&gt;EscapeJavascriptString&lt;/a&gt;&lt;/span&gt;(&amp;amp;emailid) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ROLES&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;[&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;      &amp;amp;rolesCursor &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e12439"&gt;CreateSQL&lt;/a&gt;&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;SELECT&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ROLENAME&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FROM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;PSROLEUSER&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;WHERE&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ROLEUSER&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;:1&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;AND&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ROWNUM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;6&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;oprid);&lt;br /&gt;      &amp;amp;isFirstRole &lt;span class="syntax18"&gt;=&lt;/span&gt; True;&lt;br /&gt;      &lt;br /&gt;      &lt;span class="syntax8"&gt;While&lt;/span&gt; &amp;amp;rolesCursor.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr39.htm#d0e142627"&gt;Fetch&lt;/a&gt;(&amp;amp;rolename);&lt;br /&gt;         &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;comma&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;logic&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;         &lt;span class="syntax8"&gt;If&lt;/span&gt; (&amp;amp;isFirstRole) &lt;span class="syntax8"&gt;Then&lt;/span&gt;&lt;br /&gt;            &amp;amp;isFirstRole &lt;span class="syntax18"&gt;=&lt;/span&gt; False;&lt;br /&gt;         &lt;span class="syntax8"&gt;Else&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax11"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#d0e65641"&gt;%Response&lt;/a&gt;&lt;/span&gt;.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr19.htm#d0e51121"&gt;Write&lt;/a&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;         &lt;span class="syntax8"&gt;End-If&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;         &lt;span class="syntax11"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#d0e65641"&gt;%Response&lt;/a&gt;&lt;/span&gt;.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr19.htm#d0e51121"&gt;Write&lt;/a&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e19241"&gt;EscapeJavascriptString&lt;/a&gt;&lt;/span&gt;(&amp;amp;rolename) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;      &lt;span class="syntax8"&gt;End-While&lt;/span&gt;;&lt;br /&gt;      &lt;br /&gt;      &amp;amp;rolesCursor.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr39.htm#d0e142492"&gt;Close&lt;/a&gt;();&lt;br /&gt;      &lt;span class="syntax11"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#d0e65641"&gt;%Response&lt;/a&gt;&lt;/span&gt;.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr19.htm#d0e51121"&gt;Write&lt;/a&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;]}&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax8"&gt;End-While&lt;/span&gt;;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax11"&gt;&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl04.htm#d0e65641"&gt;%Response&lt;/a&gt;&lt;/span&gt;.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr19.htm#d0e51121"&gt;Write&lt;/a&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &amp;amp;usersCursor.&lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcr/htm/tpcr39.htm#d0e142492"&gt;Close&lt;/a&gt;();&lt;br /&gt;   &lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;/pre&gt;&lt;p&gt;The code above uses embedded SQL. In production, be sure to use App Designer SQL definitions. This code listing also embeds JSON formatting strings. As an alternative, I recommend HTML definitions and HTML bind variables. In this manner, HTML definitions serve as templates for structured JSON data.&lt;/p&gt;&lt;p&gt;Formatted, the output from my demo database looks like:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax18"&gt;[&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ADRIESSEN&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRDEFNDESC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Anton&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Driessen&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMAILID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ADRIESSEN@server.com&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ROLES&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax18"&gt;[&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Processes&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Query&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Access&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Groups&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EPM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Scorecard&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Viewer&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Portal&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;User&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Query&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Access&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;-&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FSCM&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax18"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ADUPOND&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRDEFNDESC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Alain&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Dupond&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMAILID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ADUPOND@server.com&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ROLES&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax18"&gt;[&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Processes&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Query&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Access&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Groups&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EPM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Scorecard&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Viewer&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Portal&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;User&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Query&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Access&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;-&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FSCM&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax18"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;AEGLI&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRDEFNDESC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Anna&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Egli&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMAILID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;AEGLI@server.com&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ROLES&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax18"&gt;[&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Processes&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Query&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Access&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Groups&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EPM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Scorecard&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Viewer&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Employee&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Global&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Payroll&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Portal&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;User&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax18"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;AERICKSON&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRDEFNDESC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Arthur&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Erickson&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMAILID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;AERICKSON@server.com&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ROLES&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax18"&gt;[&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Accounts&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Payable&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Manager&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Processes&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Query&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Access&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Groups&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Application&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Homepages&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EP&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;General&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Options&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax18"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;AFAIRCHILD&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;OPRDEFNDESC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Alison&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Fairchild&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMAILID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;AFAIRCHILD@server.com&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ROLES&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax18"&gt;[&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Applicant&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Processes&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;All&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Query&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Access&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Groups&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EPM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Scorecard&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Viewer&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Employee&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ELM&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax18"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax18"&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;IScripts provide a secure free-form mechanism for serving data. This makes them perfect for serving JSON in response to a logged in user's AJAX request. If you want to serve PeopleSoft data in JSON format for consumption in a page outside PeopleSoft, then try using an Integration Broker synchronous message handler.&lt;/p&gt;&lt;p&gt;If you need help prototyping your JSON, take a look at the &lt;a href="http://json.org"&gt;JSON&lt;/a&gt; homepage and &lt;a href="http://www.jsonlint.com/"&gt;JSONLint&lt;/a&gt;, an online JSON validator. I rely heavily on JSONLint when prototyping JSON.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-6598605072168521968?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/6598605072168521968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=6598605072168521968' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6598605072168521968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6598605072168521968'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/03/serve-json-from-peoplesoft.html' title='Serve JSON from PeopleSoft'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5157280998139562451</id><published>2009-03-17T12:12:00.000-07:00</published><updated>2010-04-14T14:17:07.961-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><title type='text'>Using Oracle JDBC from PeopleCode</title><content type='html'>&lt;p&gt;&lt;a href="http://psst0101.wordpress.com/"&gt;PSST0101's&lt;/a&gt; post &lt;a href="http://psst0101.wordpress.com/2008/07/29/writing-to-access-databases/"&gt;Writing to Access Databases&lt;/a&gt; demonstrates how to call standard JDBC boiler plate code from PeopleCode. I tried it with the Oracle JDBC driver, but couldn't get the driver to load. First, &lt;code&gt;class.forName&lt;/code&gt; kept throwing &lt;code&gt;java.lang.ClassNotFoundException: oracle/jdbc/OracleDriver&lt;/code&gt;. Since the intent of &lt;code&gt;class.forName&lt;/code&gt; is to register the driver with the JDBC &lt;code&gt;DriverManager&lt;/code&gt;, I thought I would see if I could register it manually:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;driverManager &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.sql.DriverManager&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&amp;amp;driverManager.registerDriver(&lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;oracle.jdbc.OracleDriver&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;));&lt;/pre&gt;&lt;p&gt;This time the JVM found the class, but, when I executed &lt;code&gt;DriverManager.getConnection&lt;/code&gt;, the JVM threw &lt;code&gt;java.sql.SQLException: No suitable driver&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The point of boiler plate JDBC code is to abstract the persistence layer from the code tier, allowing for configurable data repositories. Since PeopleCode requires Java class names as strings, PeopleCode affords us this configurable feature without the JDBC abstraction. Therefore, we can skip the JDBC niceties in favor of direct driver usage:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;driver &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;oracle.jdbc.OracleDriver&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;info &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.util.Properties&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&amp;amp;info.put(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;user&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;john_doe&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&amp;amp;info.put(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;password&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;secret&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;conn &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;driver.connect(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;jdbc:oracle:thin:@servername:1521:SID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;info);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;stmt &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;conn.createStatement();&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;rs &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;stmt.executeQuery(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;SELECT&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ROLENAME&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FROM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;PSROLEDEFN&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;WHERE&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ROWNUM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;&amp;lt;&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;11&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;number&lt;/span&gt; &amp;amp;rowIdx;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;While&lt;/span&gt; &amp;amp;rs.next()&lt;br /&gt;   &amp;amp;rowIdx &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;rowIdx &lt;span class="syntax18"&gt;+&lt;/span&gt; &lt;span class="syntax5"&gt;1&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax9"&gt;MessageBox&lt;/span&gt;(&lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax5"&gt;0&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Row&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;rowIdx &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;column&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;1:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;rs.getObject(&lt;span class="syntax5"&gt;1&lt;/span&gt;).toString());&lt;br /&gt;&lt;span class="syntax8"&gt;End-While&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax-COMMENT2"&gt;REM ** Close JDBC resources per Cheryl's comment below;&lt;/span&gt;&lt;br /&gt;&amp;amp;rs.close();&lt;br /&gt;&amp;amp;stmt.close();&lt;br /&gt;&amp;amp;conn.close();&lt;/pre&gt;&lt;p&gt;Even though I find this example thought provoking, I have not used it in production. When integrating with other applications, I first consider Integration Broker's asynchronous services. Integration Broker provides services such as queuing that aren't available with direct access. If I can't find a delivered target connector and can't create a custom target connector to suit my needs, then my next consideration is Oracle database links.&lt;/p&gt;&lt;p&gt;PeopleSoft's flexible architecture provides developers with a vast array of options. It is important for us as developers to know how and when to use these options.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update (March 24, 2009)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.blogger.com/profile/06634519580752248909"&gt;Nicolas&lt;/a&gt; pointed out that users should not hard code user names and passwords. I absolutely agree. The code above is provided as an example. If you implement a solution like this, I strongly encourage you to &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e18343"&gt;Encrypt&lt;/a&gt; the password and store it somewhere else. PeopleCode has &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#d0e18343"&gt;Encrypt&lt;/a&gt; and &lt;a href="http://download.oracle.com/docs/cd/E13292_01/pt849pbr0/eng/psbooks/tpcl/htm/tpcl02.htm#g037ee99c9453fb39_ef90c_10c791ddc07__3dd7"&gt;Decrypt&lt;/a&gt; functions for this purpose. You can either store the user name and password encrypted in the database or store it in a protected file off line. Furthermore, don't use a privileged user. Use a database user that only has the database access required to accomplish the coded task.&lt;/p&gt;&lt;p&gt;Besides a hard coded password, the code above contains a hard coded SQL string literal. I strongly discourage this practice as well. Use App Designer SQL definitions to store SQL statements. Unlike string literals, PeopleSoft change management tools can search, compare, and maintain managed objects referenced in SQL definitions.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5157280998139562451?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5157280998139562451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5157280998139562451' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5157280998139562451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5157280998139562451'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/03/using-oracle-jdbc-from-peoplecode.html' title='Using Oracle JDBC from PeopleCode'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-6761306776118438104</id><published>2009-02-01T22:26:00.000-08:00</published><updated>2009-02-02T11:53:08.001-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>Alliance 2009 Sessions</title><content type='html'>&lt;p&gt;It is almost time for Alliance 2009. It looks like the Alliance technical content committee put together another outstanding lineup of technical customer led sessions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.heug.org/e/in/eid=5&amp;s=2553&amp;req=info"&gt;26010: Iscript, You Script Why Not JavaScript?&lt;/a&gt; &lt;i&gt;North Carolina State University&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.heug.org/e/in/eid=5&amp;s=3054&amp;req=info"&gt;26100: Virtually Refreshing: Virtualizing and Refreshing your PeopleSoft Environments with VMWare&lt;/a&gt; &lt;i&gt;Brigham Young University - Hawaii&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.heug.org/e/in/eid=5&amp;s=3055&amp;req=info"&gt;26040: Enterprise Portal 9.0 - Is it worth it?&lt;/a&gt; &lt;i&gt;Coppin State University&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.heug.org/e/in/eid=5&amp;s=3057&amp;req=info"&gt;26243: Putting the Service into SOA - Consuming WSDL's in PeopleSoft&lt;/a&gt; &lt;i&gt;University of Utah&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.heug.org/e/in/eid=5&amp;s=2564&amp;req=info"&gt;26534: PeopleCode Enhanced Logging Using Log4j&lt;/a&gt; &lt;i&gt;University of Utah&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.heug.org/e/in/eid=5&amp;s=2565&amp;req=info"&gt;26609: Sign On Peoplecode: A Drilldown&lt;/a&gt; &lt;i&gt;Texas Christian University&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;My Oracle peers will present several great technical sessions as well. To see a full list of Oracle technical sessions, browse to the &lt;a href="http://www.heug.org/e/in/?eid=5&amp;req=info"&gt;Alliance 2009 Registration and Agenda Builder&lt;/a&gt; and select &lt;strong&gt;Track:&lt;/strong&gt; &lt;em&gt;Technical&lt;/em&gt; and &lt;strong&gt;Primary Speaker Organization:&lt;/strong&gt; &lt;em&gt;Oracle/PeopleSoft&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;I will present session &lt;a href="http://www.heug.org/e/in/eid=5&amp;s=2571&amp;req=info"&gt;26372: PeopleTools Tips and Techniques&lt;/a&gt; on tuesday, March 24th, 2009 from 9:50 AM to 10:50 AM. This year's Tips and Techniques presentation will major in productivity tips with a minor in Ajax and Java.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-6761306776118438104?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/6761306776118438104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=6761306776118438104' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6761306776118438104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6761306776118438104'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/02/alliance-2009-sessions.html' title='Alliance 2009 Sessions'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-89684706464924143</id><published>2009-01-08T20:53:00.000-08:00</published><updated>2009-04-09T09:45:07.701-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='File Attachment API'/><category scheme='http://www.blogger.com/atom/ns#' term='IScripts'/><title type='text'>Exporting Attachments Part 2</title><content type='html'>&lt;p&gt;In my post &lt;a href="http://jjmpsj.blogspot.com/2008/05/export-peoplesoft-attachments-using.html"&gt;Export PeopleSoft Attachments using PL/SQL&lt;/a&gt;, I mentioned that PeopleSoft provides the File Attachment API for storing, retrieving, and viewing file attachments. These API functions comprise the recommended method for working with attachments. If you want to process an attachment, use the &lt;code&gt;GetAttachment&lt;/code&gt; function to move that attachment into a file so you can access it from your app server. The &lt;code&gt;ViewAttachment&lt;/code&gt; function, on the other hand, will send a copy of an attachment to a client browser. The &lt;code&gt;ViewAttachment&lt;/code&gt; function is the only method provided by the Attachment API that allows a user to view the contents of an attachment. What if you want more control over the way PeopleSoft displays attachments? For example, let's say you use the File Attachment API to allow selected users to upload audio files (news, recorded training sessions, etc) and you have another page that allows other users to listen to those recordings. Should the "view" page display a "View Attachment" link or should it play the selected clip as embedded audio?&lt;/p&gt;&lt;p&gt;If you store attachments in the database using a &lt;code&gt;RECORD://&lt;/code&gt; style URL, then you can extract those attachments using PeopleCode. Here is an &lt;a href="http://jjmpsj.blogspot.com/search/label/IScripts"&gt;IScript&lt;/a&gt; that demonstrates this:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; IScript_GetAttachment()&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;any&lt;/span&gt; &amp;amp;data;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;file_name &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;attachment.doc&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;;   &lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; SQL &amp;amp;cursor &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateSQL&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;SELECT&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FILE_DATA&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;FROM&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;PS_EO_PE_MENU_FILE&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;WHERE&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;ATTACHSYSFILENAME&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;=&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;:1 ORDER BY FILE_SEQ&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;file_name);&lt;br /&gt;&lt;br /&gt;   &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;Set the following header if you want a download prompt. Don't set it if you want inline content&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.SetHeader(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;content-disposition&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;attachment;filename=&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;file_name);&lt;br /&gt;&lt;br /&gt;   &lt;span class="syntax8"&gt;While&lt;/span&gt; &amp;amp;cursor.Fetch(&amp;amp;data);&lt;br /&gt;      &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.WriteBinary(&amp;amp;data);&lt;br /&gt;   &lt;span class="syntax8"&gt;End-While&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;/pre&gt;&lt;p&gt;This method allows you to embed audio/video, provide user configurable background images, display inline PDF files, etc.&lt;/p&gt;&lt;p&gt;If you follow my blog closely, you may remember that my &lt;a href="http://jjmpsj.blogspot.com/2008/02/what-is-iscript.html"&gt;IScripts&lt;/a&gt; post claims there is no way to write binary data to an HTTP response. Notice the use of the &lt;code&gt;%Response.WriteBinary&lt;/code&gt; method above? I was wrong. I was reading the comments of the post &lt;a href="http://www.erpassociates.com/peoplesoft-corner-weblog/peopletools/browse-the-app-server-filesystem-via-iscript.html"&gt;Browse the App Server Filesystem via iScript&lt;/a&gt; and noticed &lt;a href="http://xtrahot.chili-mango.net/"&gt;Joe's&lt;/a&gt; reference to &lt;code&gt;%Response.WriteBinary()&lt;/code&gt;. Even though it isn't documented in PeopleBooks, I tried it and it worked. Thanks Joe!&lt;/p&gt;&lt;p&gt;Note that I hard coded my SQL statement. I did this for simplicity in this blog post. For production systems, I encourage you to use SQL definitions. Of course, if you implement this solution, you will need to change the SQL select table name to the name of your attachment table. Likewise, you will probably derive your file name from a parameter rather than hard code it as shown here.&lt;/p&gt;&lt;p&gt;As with any custom development, make sure you write secure code. For example, when executing SQL based on parameters, use SQL binds. Failure to use SQL binds can result in SQL injection flaws. Likewise, if you accept an attachment from a user and then display that attachment using a means other than the provided &lt;code&gt;ViewAttachment&lt;/code&gt; function, then make sure you either validate that input or validate the output. For example, let's say you have a page that allows users to upload JavaScript or other HTML that will be executed on other pages. Failure to restrict this type of usage provides malicious users with an opportunity to create HTML injection and cross site scripting vulnerabilities.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-89684706464924143?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/89684706464924143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=89684706464924143' title='61 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/89684706464924143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/89684706464924143'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/01/exporting-attachments-part-2.html' title='Exporting Attachments Part 2'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>61</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2276816386752716450</id><published>2009-01-06T11:51:00.000-08:00</published><updated>2009-11-23T10:50:20.998-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='IScripts'/><title type='text'>Serve those JavaScript Libraries Quickly... and Safely</title><content type='html'>&lt;p&gt;If at all possible, don't serve JavaScript libraries from PeopleSoft applications (dynamic PeopleCode). The best place to serve a JavaScript library is from a static file residing on the PeopleSoft web server. Many PeopleSoft developers, however, don't have access to their web server file systems. The next logical place to store a JavaScript library is in an HTML definition in app designer. This is where the PeopleTools developers store JavaScript libraries and, therefore, is the preferred location for small JavaScript libraries. Unfortunately, the maximum size of a PeopleTools 8.4x HTML definition is too small to fit a good JavaScript library like &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt;. Enter John and Derek. John and Derek both wrote about a workaround to this limitation. Rather than using HTML Definitions, these innovative developers used the message catalog to store their JavaScript libraries (jQuery, of course). Here are links to those blog posts:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://campus-codemonkeys.blogspot.com/2007/09/ajax-and-peoplesoft.html"&gt;Ajax and PeopleSoft&lt;/a&gt; from John Wagenleitner&lt;/li&gt;&lt;li&gt;&lt;a href="http://community.psoftpros.net/profiles/blogs/injecting-javascript-amp-ajax"&gt;Injecting Javascript &amp;amp; AJAX into a PeopleSoft Page&lt;/a&gt; from Derek Tomei&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Both of these posts provide an alternative for PeopleSoft developers that want to use a JavaScript library but don't have access to their PeopleSoft web servers' file structure. Building upon John's and Derek's approach, here are some ideas to help improve performance.&lt;/p&gt;&lt;h4&gt;Packing/Minification/Raw&lt;/h4&gt;&lt;p&gt;Based on Julien Lecomte's post &lt;a href="http://www.julienlecomte.net/blog/2007/08/13/"&gt;Gzip Your Minified JavaScript Files&lt;/a&gt;, we can see that &lt;a href="http://dean.edwards.name/"&gt;Dean Edwards's&lt;/a&gt; &lt;a href="http://dean.edwards.name/weblog/2007/04/packer3/"&gt;Packer&lt;/a&gt; algorithm produces the smallest compressed file. As Julien notes, however, the benefit of that smaller download is offset by a corresponding increase in execution/evaluation time. Julien points out that other compression techniques like &lt;a href="www.crockford.com"&gt;Douglas Crockford's&lt;/a&gt; &lt;a href="http://www.crockford.com/javascript/jsmin.html"&gt;JSMin&lt;/a&gt; and &lt;a href="http://developer.yahoo.com"&gt;Yahoo's&lt;/a&gt; &lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI Compressor&lt;/a&gt; produce larger files that evaluate much faster. Therefore, when using JavaScript compression alone, you, as an analyst or developer, need to determine which method is appropriate for your implementation. Do you have low bandwidth connecting powerful computers to your PeopleSoft instance? If so, then maybe the Packer algorithm is more appropriate for you. If you have good bandwidth (or low bandwidth and low power client computers), then maybe you should consider JSMin or the YUI Compressor. Both of these compression techniques produce compressed text files that can be stored in a message catalog entry as described by John and Derek.&lt;/p&gt;&lt;h4&gt;Caching&lt;/h4&gt;&lt;p&gt;Browsers are designed to cache static, externally referenced resources. The methods demonstrated in the previously mentioned blogs insert the contents of a JavaScript library into the body of an HTML page. By inserting the contents directly into a page, the browser is not able to cache it with other JavaScripts, stylesheets, and images. An alternative approach is to serve JavaScript libraries stored as message catalog entries from &lt;a href="http://jjmpsj.blogspot.com/search/label/IScripts"&gt;IScripts&lt;/a&gt;. Using this approach, you could reference your JavaScript library using HTML like:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax17"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;type&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax17"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;text&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;javascript&lt;/span&gt;&lt;span class="syntax17"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;language&lt;/span&gt;&lt;span class="syntax17"&gt;=&lt;/span&gt;&lt;span class="syntax17"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;JavaScript&lt;/span&gt;&lt;span class="syntax17"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt; &lt;/span&gt;&lt;span class="syntax17"&gt;src=&lt;/span&gt;&lt;span class="syntax17"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;psc&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;portal&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;EMPLOYEE&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;EMPL&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;s&lt;/span&gt;&lt;span class="syntax17"&gt;/&lt;/span&gt;&lt;span class="syntax17"&gt;WEBLIB_JS_LIBS&lt;/span&gt;&lt;span class="syntax17"&gt;.&lt;/span&gt;&lt;span class="syntax17"&gt;ISCRIPT1&lt;/span&gt;&lt;span class="syntax17"&gt;.&lt;/span&gt;&lt;span class="syntax17"&gt;FieldFormula&lt;/span&gt;&lt;span class="syntax17"&gt;.&lt;/span&gt;&lt;span class="syntax17"&gt;IScript_jQuery&lt;/span&gt;&lt;span class="syntax17"&gt;"&lt;/span&gt;&lt;span class="syntax17"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax17"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The PeopleCode for this IScript would look something like:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; IScript_jQuery()&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;jq &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;MsgGetExplainText&lt;/span&gt;(&lt;span class="syntax5"&gt;28000&lt;/span&gt;, &lt;span class="syntax5"&gt;1&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;alert('Unable&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;to&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;load&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;the&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;jQuery&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;JavaScript&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;library!\n\nThe&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Message&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;Catalog&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;entry&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;(28000,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;1)&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;does&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;not&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;exist.');&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span style="text-decoration: line-through;"&gt;&lt;span class="syntax11"&gt;%Response&lt;/span&gt;.SetHeader(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Cache-Control&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;max-age=28800,&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;proxy-revalidate&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.WriteLine(&amp;amp;jq);&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Update November 23, 2009:&lt;/strong&gt; &lt;em&gt;PeopleSoft actually overwrites the Cache-Control header. I have not found a way to set this through an IScript. The only solution I have found to cache IScript content is to use a ServletFilter to set the Cache-Control header after PeopleSoft returns a response.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The benefit of this approach is that users only download the JavaScript library once, rather than once per page visit. Considering cache, file size is not as important as execution time. Because the Packer algorithm produces a smaller file size, it excels in low bandwidth scenarios. With caching, however, the one time bandwidth hit might not compensate for the on going evaluation cost of the Packer algorithm. If you cache your JavaScript library, then a minification algorithm like JSMin or YUI Compressor may provide better performance.&lt;/p&gt;&lt;h4&gt;GZip Compression&lt;/h4&gt;&lt;p&gt;The first column of stats on Julien Lecomte's matrix compares the size of jQuery when packed, minified, or YUI Compressed. The second column compares that same content GZip compressed. GZip compressed, all three JavaScript compression methods result in a fairly comparable download size. When GZipped, the main difference between JSMin/YUI and Packer is the browser evaluation time required to "unpack" the packed JavaScript library.&lt;/p&gt;&lt;p&gt;The next performance improvement to explore with our IScript scenario is GZip compression. Fortunately, PeopleSoft takes care of GZip compression for us. If you look at your Web Profile settings, you will notice a check box labeled &lt;strong&gt;Compress Responses&lt;/strong&gt;. If you enable this setting, PeopleSoft will automatically GZip compress the contents of your IScripts (and the contents of any other PeopleSoft page).&lt;/p&gt;&lt;p&gt;Whatever approach you take, be sure to consider security. OWASP listed &lt;a href="http://www.owasp.org/index.php/Top_10_2007-A2"&gt;Injection flaws&lt;/a&gt; as the Number 2 security concern in the &lt;a href="http://www.owasp.org/index.php/Top_10_2007"&gt;OWASP 2007 top 10&lt;/a&gt;. Injection isn't limited to SQL. If you take user entered values and insert them into the HTML of a page, unescaped, then you have given that user the ability to inject malicious content into a page. If you use a message catalog approach and insert the contents of a message catalog entry into a page, then be sure to secure your message catalog. Failure to do so could have the same impact as the number one security threat in the OWASP 2007 Top 10: &lt;a href="http://www.owasp.org/index.php/Top_10_2007-A1"&gt;Cross Site Scripting (XSS)&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2276816386752716450?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2276816386752716450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2276816386752716450' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2276816386752716450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2276816386752716450'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/01/serve-thosejavascript-libraries-quickly.html' title='Serve those JavaScript Libraries Quickly... and Safely'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5677052334921363077</id><published>2009-01-06T09:31:00.000-08:00</published><updated>2009-01-07T20:30:58.391-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='DHTML'/><title type='text'>Injecting JavaScript Libraries into PeopleSoft Pages</title><content type='html'>&lt;p&gt;Before you start creating Ajax and Dynamic HTML usability enhancements for your PeopleSoft applications, I recommend learning a good JavaScript library. When creating client side usability enhancements, JavaScript libraries significantly reduce the amount of JavaScript you have to write and maintain. The first page of a Google search for &lt;a href="http://www.google.com/search?q=JavaScript+library"&gt;JavaScript libraries&lt;/a&gt; should display several alternatives. Wikipedia also maintains a list of &lt;a href="http://en.wikipedia.org/wiki/List_of_JavaScript_libraries#JavaScript"&gt;JavaScript libraries&lt;/a&gt; (my favorite JavaScript library is &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt;). After you select a JavaScript library, read the library's documentation, read some tutorials, and write some static HTML test pages. It is a good idea to get to know your chosen JavaScript library before you try to integrate it with PeopleSoft.&lt;/p&gt;&lt;p&gt;After you find and become proficient with a good JavaScript library, you will need a way to inject that library into your PeopleSoft application. If you limit your Ajax/DHTML plans to modifying a select number of delivered pages or enhancing a custom page, then you can inject your JavaScript library by adding a new HTML Area to your target page with the appropriate &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag pointing to the location of your JavaScript library. If your plans call for adding a generic usability enhancement to every page, then you will want a different solution. It is not practical or advisable to modify every page of your PeopleSoft application.&lt;/p&gt;&lt;p&gt;One way to make a JavaScript modification available to all pages within your application is to find an Application Designer managed object that can act as a vehicle, carrying that JavaScript modification to the client browser. We could then modify that object, injecting our JavaScript library into all PeopleSoft pages. Now that we have a potential solution, let's use our analytical skills to try to find a managed object that is common to all PeopleSoft pages. An analyst is a lot like a detective; investigating computer systems looking for patterns and solutions. Like any mystery, let's start with what we know &amp;#45; the facts. One thing we know is that the PeopleSoft user interface is comprised of HTML, JavaScript, CSS, and images. Using our browser we can view the source of the PeopleSoft generated HTML, CSS, and JavaScript, looking for patterns and other clues. Browser based tools like &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; dramatically simplify this type of investigation, allowing us to view all of a page's JavaScript and CSS resources from a drop-down list. Using Firebug, we can see that the &lt;em&gt;cs&lt;/em&gt; servlet serves many of the images, CSS, and JavaScript resources used by PeopleSoft pages. Since we know that the PeopleSoft application compiles CSS files from App Designer stylesheets and that images served by PeopleSoft come from Image Definitions stored in App Designer, it stands to reason that those JavaScript files served by the &lt;em&gt;cs&lt;/em&gt; servlet would also come from managed objects in App Designer. Making the case stronger, we can see that PeopleSoft applications store JavaScript files in the web server cache directory, the location for all client-side managed objects.&lt;/p&gt;&lt;p&gt;Based on the previously established anecdotal evidence, we will assume that JavaScript files are managed object. If this is true, the next logical question to ask is, "What type of managed object?" Just as CSS files translate to Stylesheet managed objects, there must be some type of managed object that contains JavaScript. Searching PeopleBooks for JavaScript, we can see that the function &lt;code&gt;GetJavaScriptURL()&lt;/code&gt; serves an HTML Definition as a JavaScript file. Based on this information, we form the following hypothesis:&lt;/p&gt;&lt;blockquote&gt;JavaScript files served by the &lt;em&gt;cs&lt;/em&gt; servlet are HTML Definitions and can be modified in App Designer like any other HTML Definition.&lt;/blockquote&gt;&lt;p&gt;To test this, we can copy the name of a JavaScript file, like &lt;code&gt;PT_PAGESCRIPT&lt;/code&gt;, and try to open that item as an HTML Definition. This test passes. Should we now conclude that JavaScript files served by the &lt;em&gt;cs&lt;/em&gt; servlet are HTML Definitions? Two more tests:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Compare the HTML Definition to the downloaded JavaScript file. Don't expect a perfect match. The HTML Definition may contain Meta-HTML whereas the downloaded JavaScript file will contain the Meta-HTML's resolved value.&lt;/li&gt;&lt;li&gt;Modify an HTML Definition and check the results.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Using a file diff utility like &lt;a href="http://support.microsoft.com/kb/159214"&gt;WinDiff&lt;/a&gt; or &lt;a href="http://www.jedit.org/"&gt;jEdit's&lt;/a&gt; JDiffPlugin, we can compare the downloaded JavaScript file to the contents of the &lt;code&gt;PT_PAGESCRIPT&lt;/code&gt; HTML Definition.&lt;/p&gt;&lt;p&gt;To satisfy the modification test, I suggest adding a short comment to the end of &lt;code&gt;PT_PAGESCRIPT&lt;/code&gt;, something like /* XXX */. Since both of these tests pass, we have very strong evidence that JavaScript files served by the &lt;em&gt;cs&lt;/em&gt; servlet are, in fact, HTML Definitions and can be modified using App Designer. Based on this investigation, we have discovered an object type that can we can use as a vehicle to carry our global customizations to our users' browsers. Since we have been using &lt;code&gt;PT_PAGESCRIPT&lt;/code&gt; for testing, it would seem logical to continue with that HTML Definition, customizing it as needed to add additional JavaScript based DHTML usability enhancements. I tried this once. After writing a few lines of code and saving, App Designer displayed an error telling me that the HTML Definition had exceeded the maximum size and would be truncated. Generally speaking, the actual size limitation is not relevant. What is relevant is that we know a size limitation exists. Considering the size of &lt;code&gt;PT_PAGESCRIPT&lt;/code&gt; without any modifications, there is no room for us to add additional JavaScript to &lt;code&gt;PT_PAGESCRIPT&lt;/code&gt;. Looking through the list of JavaScript files common to all PeopleSoft pages, I suggest &lt;code&gt;PT_COPYURL&lt;/code&gt;. &lt;code&gt;PT_COPYURL&lt;/code&gt; appears to contain the JavaScript required to make the copy URL button work. The copy URL button is that double paper/carbon copy button in the page bar at the top of most PeopleSoft pages. I don't think early 8.4x versions of PeopleTools had this button. I don't remember when it was added, but I do remember seeing it as early as PT 8.46. If you have that button, then chances are, you have the &lt;code&gt;PT_COPYURL&lt;/code&gt; HTML Definition. If you don't, then you may have to find a different HTML Definition to modify.&lt;/p&gt;&lt;p&gt;Once you identify an HTML Definition, add JavaScript similar to the following to the end of the delivered HTML Definition:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax1"&gt;/*&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;Conditionally&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;include&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;a&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;JavaScript/Ajax&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;libary&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;if&lt;/span&gt;(&lt;span class="syntax18"&gt;!&lt;/span&gt;window&lt;span class="syntax18"&gt;.&lt;/span&gt;jQuery) &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;  document&lt;span class="syntax18"&gt;.&lt;/span&gt;&lt;span class="syntax6"&gt;write&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;&amp;lt;scr&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;+&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ipt&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;id='jq'&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;+&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;src='/scripts/jquery.js'&amp;gt;&amp;lt;\/script&amp;gt;&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;)&lt;span class="syntax18"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax1"&gt;/*&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;Unconditionally&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;insert&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;a&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;JavaScript&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;file&lt;/span&gt;&lt;span class="syntax1"&gt; &lt;/span&gt;&lt;span class="syntax1"&gt;*/&lt;/span&gt;&lt;br /&gt;document&lt;span class="syntax18"&gt;.&lt;/span&gt;&lt;span class="syntax6"&gt;write&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;&amp;lt;scr&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;+&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;ipt&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;id='xxx_ui'&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;+&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;src='/scripts/ui.js'&amp;gt;&amp;lt;\/script&amp;gt;&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;)&lt;span class="syntax18"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The first 3 lines demonstrate how to insert a static JavaScript file into all PeopleSoft pages conditioned upon the existence of an object. We typically display PeopleSoft pages in a frameset where the content frame only contains the HTML, JavaScript, and CSS required for that page. It is possible, however, to use a display template that proxies a page's content into the same HTML page as the header. The &lt;code&gt;HOMEPAGE_DESIGNER_TEMPLATE&lt;/code&gt; is an example of this type of HTML template. If your header also contains a reference to your JavaScript library, then, best case, you will have multiple instances of your JavaScript library in memory. Worst case, your page will quit working. One way to work around this issue is to test for the existence of your JavaScript library prior to inserting it into a page. Since I use &lt;a href="http://jquery.com"&gt;jquery&lt;/a&gt;, my code tests for the existence of the jQuery object.&lt;/p&gt;&lt;p&gt;The last line of the example above shows how to blindly insert a static JavaScript file into a PeopleSoft page. This approach works well for static JavaScript that you know isn't used by your header.&lt;/p&gt;&lt;p&gt;If you don't have access to your web server to install static JavaScript files or if your JavaScript needs to be dynamic, then take a look at John's post &lt;a href="http://campus-codemonkeys.blogspot.com/2007/09/ajax-and-peoplesoft.html"&gt;AJAX and PeopleSoft&lt;/a&gt;. In the post and comments, you can read about alternative ways of storing and serving JavaScript to PeopleSoft pages.&lt;/p&gt;&lt;p&gt;Changing a delivered HTML Definition is considered a modification. Like all modifications, you will need to consider compatibility and upgrade issues. To manage this modification through PeopleTools upgrades and patches, make sure you adequately document your modifications with code comments, project comments, and additional project management documentation. When considering upgrades, your documentation goal is to identify your modification and point the person applying an upgrade to any documentation related to this modification. Because of size limitations, you may not be able to document your entire modification inline. You will, however, be able to point other people at your documentation for this modification. For an effective, short, inline comment, I suggest something like:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax1"&gt;&amp;lt;!% BEGIN xxx_1234, 13-DEC-2008, you@yourcompany.com --&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;Your modified code goes here...&lt;/em&gt;&lt;br /&gt;&lt;span class="syntax1"&gt;&amp;lt;!% END xxx_1234, 13-DEC-2008, you@yourcompany.com --&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;With this comment, I have documented the start and end of this modification, the project name of the modification (xxx_1234), the date of the modification (13-DEC-2008), and the developer that made the modification (you@yourcompany.com). I have applied several patches over other developers' modified code. Without this type of START/END comment, it is impossible to differentiate between delivered code and modified code. Likewise, sharing a common prefix for all modifications (xxx_ in this case), dramatically simplifies searching for and identifying modifications.&lt;/p&gt;&lt;p&gt;Any time you modify a delivered object, you risk rendering that object unusable. If you modify a delivered PeopleTools object like &lt;code&gt;PT_PAGESCRIPT&lt;/code&gt;, ensure that the delivered code works the same as it did before you modified it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5677052334921363077?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5677052334921363077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5677052334921363077' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5677052334921363077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5677052334921363077'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2009/01/injecting-javascript-libraries-into.html' title='Injecting JavaScript Libraries into PeopleSoft Pages'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-4043036960178450293</id><published>2008-11-26T16:48:00.001-08:00</published><updated>2008-11-26T16:58:23.714-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>See you at UKOUG</title><content type='html'>&lt;p&gt;I am headed to Birmingham, UK next week to present PeopleTools tips and PeopleSoft RIA at the &lt;a href="http://peoplesoft.ukoug.org/"&gt;UKOUG PeopleSoft conference&lt;/a&gt;. I will be traveling from the US, West Coast. If you have ventured this route before, then please share your travel tips with me. For example, what is the cheapest way to get to London from Heathrow?&lt;/p&gt;&lt;p&gt;While in Birmingham, I will have the opportunity to chair a PeopleTools round table. If you are attending, please bring questions and advice. This will be an open forum where we will all have the opportunity to share suggestions and solutions.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-4043036960178450293?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/4043036960178450293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=4043036960178450293' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4043036960178450293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/4043036960178450293'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/11/see-you-at-ukoug.html' title='See you at UKOUG'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5506128158003118747</id><published>2008-10-03T15:53:00.000-07:00</published><updated>2008-10-03T16:02:11.314-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Presentations'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>OOW 2008 Presentation Available</title><content type='html'>&lt;p&gt;My PeopleTools Advanced Tips and Techniques session slides are available from Oracle's OOW content catalog. To download OpenWorld presentations, you will need to log into the &lt;a href="http://www28.cplan.com/cc208/login.jsp"&gt;content catalog&lt;/a&gt; using your OpenWorld Registration ID. After you log in, you can download these slides by following the instructions given &lt;a href="http://www28.cplan.com/cc208/sessionCatalog.jsp?ilc=208-1&amp;ilg=english&amp;isort_sessions=&amp;isort_demos=&amp;isort_exhibitors=&amp;is=yes&amp;ip=%3C%2Fipresentations%3E&amp;isort_sessions_type=&amp;isort_exhibitors_type=&amp;isort_demos_type=&amp;search_sessions=yes&amp;icriteria1=+&amp;icriteria2=+&amp;icriteria5=+&amp;icriteria8=&amp;icriteria9=+&amp;icriteria6=S299116&amp;icriteria3=+&amp;icriteria7="&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If you didn't register for OpenWorld, but still want to see the slides, you can purchase &lt;em&gt;Oracle OpenWorld OnDemand&lt;/em&gt; from the log in page.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5506128158003118747?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5506128158003118747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5506128158003118747' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5506128158003118747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5506128158003118747'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/10/oow-2008-presentation-available.html' title='OOW 2008 Presentation Available'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-9206333562216201746</id><published>2008-09-20T23:08:00.000-07:00</published><updated>2008-09-20T23:17:55.892-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='formatting'/><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Strings'/><title type='text'>printf for Peoplesoft</title><content type='html'>&lt;p&gt;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 &lt;a href="http://en.wikipedia.org/wiki/Printf"&gt;printf Wikipedia entry&lt;/a&gt;. If you are familiar with printf and just want to know how to use it, then take a look at the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax"&gt;Format String Syntax&lt;/a&gt; of the &lt;a class="code" href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html"&gt;java.util.Formatter&lt;/a&gt; class. The code below actually uses the &lt;a class="code" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#format(java.util.Locale,%20java.lang.String,%20java.lang.Object...)"&gt;format(Locale l, String format, Object... args)&lt;/a&gt; method of the &lt;a class="code" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html"&gt;java.lang.String&lt;/a&gt; class. If you are interested in using printf with PeopleCode, here is an example to get you started:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; printf(&amp;amp;language As &lt;span class="syntax10"&gt;string&lt;/span&gt;, &amp;amp;country As &lt;span class="syntax10"&gt;string&lt;/span&gt;, &amp;amp;message As &lt;span class="syntax10"&gt;string&lt;/span&gt;, &amp;amp;parms As &lt;span class="syntax10"&gt;array&lt;/span&gt; of &lt;span class="syntax10"&gt;any&lt;/span&gt;) &lt;span class="syntax9"&gt;Returns&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;jLocale &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.util.Locale&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;language, &amp;amp;country);&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;jParms &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaArray&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Object[]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;parms.&lt;span class="syntax9"&gt;Len&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax9"&gt;CopyToJavaArray&lt;/span&gt;(&amp;amp;parms, &amp;amp;jParms);&lt;br /&gt;   &lt;span class="syntax9"&gt;Return&lt;/span&gt; &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.String&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).format(&amp;amp;jLocale, &amp;amp;message, &amp;amp;jParms);&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; IScript_TestPrintf()&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;message &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Amount&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;gained&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;or&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;lost&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;since&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;last&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;statement&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;dated&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;%1$tc:&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;$&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;%2$(,.2f&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;array&lt;/span&gt; of &lt;span class="syntax10"&gt;any&lt;/span&gt; &amp;amp;parms &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateArrayAny&lt;/span&gt;();&lt;br /&gt;   &amp;amp;parms.Push(&lt;span class="syntax11"&gt;%Datetime&lt;/span&gt;);&lt;br /&gt;   &amp;amp;parms.Push(&lt;span class="syntax5"&gt;252356&lt;/span&gt;.&lt;span class="syntax5"&gt;69&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.SetContentType(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;text/plain&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.WriteLine(printf(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;en&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;us&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;message, &amp;amp;parms));&lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.WriteLine(printf(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;es&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;es&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;message, &amp;amp;parms));&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;/pre&gt;&lt;p&gt;Notice that my &lt;code&gt;printf&lt;/code&gt; function takes a language code and a country code. These are the ISO language and country codes defined in &lt;a href="http://www.loc.gov/standards/iso639-2/englangn.html"&gt;ISO-639&lt;/a&gt; and &lt;a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html"&gt;ISO-3166&lt;/a&gt; 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.&lt;/p&gt;&lt;p&gt;One thing that is interesting to note is that the &lt;code&gt;format&lt;/code&gt; method of the &lt;code&gt;java.lang.String&lt;/code&gt; 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 &lt;a class="code" href=""&gt;java.lang.Object&lt;/a&gt;, we can use the &lt;code&gt;CopyToJavaArray&lt;/code&gt; PeopleCode function to copy an array of type &lt;code&gt;Any&lt;/code&gt; into a Java Array of type &lt;a class="code" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html"&gt;java.lang.Object&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-9206333562216201746?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/9206333562216201746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=9206333562216201746' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/9206333562216201746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/9206333562216201746'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/09/printf-for-peoplesoft.html' title='printf for Peoplesoft'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-2455473414112665836</id><published>2008-09-17T14:52:00.000-07:00</published><updated>2008-09-17T14:55:43.306-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Reflection'/><title type='text'>Parsing JSON with PeopleCode</title><content type='html'>&lt;p&gt;A lot of web services return results in JSON format rather than XML. Is it possible to parse JSON in PeopleCode? Can you consume JSON web services uisng PeopleCode? Absolutely. My first attempt at parsing JSON in PeopleCode used &lt;code&gt;eval&lt;/code&gt; and the &lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt; JavaScript scripting engine as documented in my post &lt;a href="http://jjmpsj.blogspot.com/2007/06/scripting-peoplesoft.html"&gt;Scripting PeopleSoft&lt;/a&gt;. Because the &lt;a href="http://jakarta.apache.org/bsf/"&gt;Bean Scripting Framework's&lt;/a&gt; &lt;a href="http://www.java2s.com/Open-Source/Java-Document/Scripting/bsf-2.4.0/org/apache/bsf/BSFEngine.java.java-doc.htm#evalStringintintObject"&gt;BSFEngine.eval&lt;/a&gt; method returns a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html"&gt;java.lang.Object&lt;/a&gt;, I was left in a state of painful &lt;a href="http://jjmpsj.blogspot.com/search/label/Java%20Reflection"&gt;Java Reflection&lt;/a&gt; (executing each call using Java Reflection). Looking over the &lt;a href="http://json.org"&gt;json.org&lt;/a&gt; website, I took note of the collection of Java JSON parsers. After choosing the &lt;a href="http://www.json.org/java/index.html"&gt;org.json&lt;/a&gt; parser. I again found myself having to deal with the pain of Java Reflection (and, most definitely, I was left wishing PeopleCode had a &lt;code&gt;JavaCast&lt;/code&gt; function). Rather than deal with the Java reflection required to create an instance of a &lt;a href="http://www.json.org/javadoc/org/json/JSONObject.html"&gt;JSONObject&lt;/a&gt; or &lt;a href="http://www.json.org/javadoc/org/json/JSONArray.html"&gt;JSONArray&lt;/a&gt;, I chose an easier route: write a helper class to construct JSON objects. Here is the source:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax9"&gt;package&lt;/span&gt; yourcompany.json;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax9"&gt;import&lt;/span&gt; org.json.JSONArray;&lt;br /&gt;&lt;span class="syntax9"&gt;import&lt;/span&gt; org.json.JSONException;&lt;br /&gt;&lt;span class="syntax9"&gt;import&lt;/span&gt; org.json.JSONObject;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;public&lt;/span&gt; &lt;span class="syntax10"&gt;class&lt;/span&gt; ParseHelper &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax8"&gt;private&lt;/span&gt; &lt;span class="syntax6"&gt;ParseHelper&lt;/span&gt;() &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="syntax8"&gt;public&lt;/span&gt; &lt;span class="syntax8"&gt;static&lt;/span&gt; JSONObject &lt;span class="syntax6"&gt;objectFromString&lt;/span&gt;(String json) &lt;span class="syntax8"&gt;throws&lt;/span&gt; JSONException &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax8"&gt;return&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;JSONObject&lt;/span&gt;(json);&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="syntax8"&gt;public&lt;/span&gt; &lt;span class="syntax8"&gt;static&lt;/span&gt; JSONArray &lt;span class="syntax6"&gt;arrayFromString&lt;/span&gt;(String json) &lt;span class="syntax8"&gt;throws&lt;/span&gt; JSONException &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax8"&gt;return&lt;/span&gt; &lt;span class="syntax8"&gt;new&lt;/span&gt; &lt;span class="syntax6"&gt;JSONArray&lt;/span&gt;(json);&lt;br /&gt;    &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If my JSON looks like&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMPLID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;E1234&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;NAME&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Marion,Jim&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;DIRECTS&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax18"&gt;[&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMPLID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;E5678&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;NAME&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Doe,John&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;br /&gt;        &lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="syntax18"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;EMPLID&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;E2468&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;NAME&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Doe,Jane&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;br /&gt;        &lt;span class="syntax18"&gt;}&lt;/span&gt; &lt;br /&gt;    &lt;span class="syntax18"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax18"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Then I can enumerate the directs array using PeopleCode like:&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;json_data &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;my&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;JSON&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;string...&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;use&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;static&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;helper&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;class&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;to&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;avoid&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;ugly&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;Java&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;reflection&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;json &lt;span class="syntax18"&gt;=&lt;/span&gt;  &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;yourcompany.json.ParseHelper&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).objectFromString(&amp;amp;json_data);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;directsArr &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;json.getJSONArray(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;DIRECTS&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;number&lt;/span&gt; &amp;amp;length &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;directsArr.length();&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;number&lt;/span&gt; &amp;amp;directsIdx &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax5"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;For&lt;/span&gt; &amp;amp;directsIdx &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax5"&gt;0&lt;/span&gt; To &amp;amp;length - &lt;span class="syntax5"&gt;1&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;direct &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;directsArr.getJSONObject(&amp;amp;directsIdx);&lt;br /&gt;   &amp;amp;logger.debug(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;DIRECTS&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;[&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;directsIdx &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;]&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &amp;amp;direct.get(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;NAME&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).toString());&lt;br /&gt;&lt;span class="syntax8"&gt;End-For&lt;/span&gt;;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-2455473414112665836?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/2455473414112665836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=2455473414112665836' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2455473414112665836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/2455473414112665836'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/09/parsing-json-with-peoplecode.html' title='Parsing JSON with PeopleCode'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-1119695431668320488</id><published>2008-09-05T09:40:00.001-07:00</published><updated>2008-09-05T10:25:38.769-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='XMPP'/><category scheme='http://www.blogger.com/atom/ns#' term='Chat'/><title type='text'>Make Your Reports Chat</title><content type='html'>&lt;p&gt;I just found this on the &lt;a href="http://blog.greysparling.com/"&gt;Grey Sparling PeopleSoft Expert's Corner&lt;/a&gt;: &lt;a href="http://blog.greysparling.com/2006/01/integrating-googletalk-with-peoplesoft.html"&gt;Integrating GoogleTalk with PeopleSoft &lt;/a&gt;. I apologize for not pointing it out when Chris posted it back in 2006. Even though this post describes how to integrate with GTalk, this same code could be used to integrate with any XMPP chat server. Many companies use the XMPP protocol for their internal enterprise chat servers.&lt;/p&gt;&lt;p&gt;Nice work Chris! Thanks for the great idea!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-1119695431668320488?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/1119695431668320488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=1119695431668320488' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1119695431668320488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/1119695431668320488'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/09/make-your-reports-chat.html' title='Make Your Reports Chat'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-6115325723440019523</id><published>2008-09-05T09:10:00.000-07:00</published><updated>2009-08-05T07:44:26.840-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Reflection'/><category scheme='http://www.blogger.com/atom/ns#' term='Logging'/><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><title type='text'>Calling log4j's Logger.error from PeopleCode</title><content type='html'>&lt;p&gt;A couple of years have passed since I first posted about using log4j as a logging framework for PeopleCode. In my post &lt;a href="http://jjmpsj.blogspot.com/2006/11/log4j-and-peoplecode-part-ii.html"&gt;log4j and PeopleCode Part II&lt;/a&gt;, I noted that it is &lt;strong&gt;not&lt;/strong&gt; possible to directly call the &lt;a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Category.html#error(java.lang.Object)"&gt;&lt;code&gt;Logger.error&lt;/code&gt;&lt;/a&gt; method because &lt;code&gt;error&lt;/code&gt; is a keyword in PeopleCode. I also mentioned that it would be possible to use reflection to call this method. Here is the PeopleCode required to call the &lt;code&gt;error&lt;/code&gt; method using reflection:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;logger &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;org.apache.log4j.Logger&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).getLogger(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;my.custom.logger&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;jErrorArgTypes &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Class[]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Object&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;));&lt;br /&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;jErrorMethod &lt;span class="syntax18"&gt;=&lt;/span&gt; &amp;amp;logger.getClass().getMethod(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;error&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &amp;amp;jErrorArgTypes);&lt;br /&gt;&lt;br /&gt;&amp;amp;jErrorMethod.invoke(&amp;amp;logger, &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Object[]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;This&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;is&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;an&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;error&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;message&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;));&lt;/pre&gt;&lt;p&gt;Want it all on one line?&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;JavaObject&lt;/span&gt; &amp;amp;logger &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;org.apache.log4j.Logger&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;).getLogger(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;my.custom.logger&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&amp;amp;logger.getClass().getMethod(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;error&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Class[]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;GetJavaClass&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Object&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;))).invoke(&amp;amp;logger, &lt;span class="syntax9"&gt;CreateJavaObject&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;java.lang.Object[]&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;This&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;is&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;another&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;error&lt;/span&gt;&lt;span class="syntax13"&gt; &lt;/span&gt;&lt;span class="syntax13"&gt;message&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;));&lt;/pre&gt;&lt;p&gt;Using reflection from PeopleCode can get ugly. If you are going to use &lt;a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Category.html#error(java.lang.Object)"&gt;&lt;code&gt;Logger.error&lt;/code&gt;&lt;/a&gt;, then you may want to hide the Java implementation details in an app class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-6115325723440019523?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/6115325723440019523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=6115325723440019523' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6115325723440019523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6115325723440019523'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/09/calling-log4js-loggererror-from.html' title='Calling log4j&apos;s Logger.error from PeopleCode'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-6825127498940953801</id><published>2008-08-17T21:56:00.000-07:00</published><updated>2009-11-23T10:25:41.036-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Calendar'/><category scheme='http://www.blogger.com/atom/ns#' term='iCalendar'/><category scheme='http://www.blogger.com/atom/ns#' term='IScripts'/><category scheme='http://www.blogger.com/atom/ns#' term='Dates'/><title type='text'>PeopleSoft/Calendar Integration</title><content type='html'>&lt;p&gt;Last week three different people asked me if it was possible to integrate PeopleSoft with a calendar management program (Microsoft Outlook, to be specific). Whether you are trying to create appointments for HRMS Enterprise Learning classes, ELM training classes, or eRecruiting interviews, the solution is the same. Since most calendar programs support the &lt;a href="http://en.wikipedia.org/wiki/ICalendar"&gt;iCalendar&lt;/a&gt; (ics) format and since iCalendar files are text files, we can generate appointments from PeopleSoft &lt;a href="http://jjmpsj.blogspot.com/search/label/IScripts"&gt;IScripts&lt;/a&gt; and serve those as file downloads. As a starting point, we can copy the event example from the &lt;a href="http://www.ietf.org/rfc/rfc2445.txt"&gt;iCalendar RFC&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;BEGIN&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VCALENDAR&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax10"&gt;VERSION&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;2.0&lt;br /&gt;&lt;span class="syntax10"&gt;PRODID&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;-//hacksw/handcal//NONSGML v1.0//EN&lt;br /&gt;&lt;span class="syntax8"&gt;BEGIN&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VEVENT&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax10"&gt;DTSTART&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;19970714T170000Z&lt;br /&gt;&lt;span class="syntax10"&gt;DTEND&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;19970715T035959Z&lt;br /&gt;&lt;span class="syntax10"&gt;SUMMARY&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;Bastille Day Party&lt;br /&gt;&lt;span class="syntax8"&gt;END&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VEVENT&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;END&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VCALENDAR&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Modifying this a little, we can convert it to an HTML object with bind parameters:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;BEGIN&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VCALENDAR&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax10"&gt;VERSION&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;2.0&lt;br /&gt;&lt;span class="syntax10"&gt;PRODID&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;-//My Company//PeopleCode vCal 1.0//EN&lt;br /&gt;&lt;span class="syntax8"&gt;BEGIN&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VEVENT&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax10"&gt;DTSTART&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;%Bind(:1)&lt;br /&gt;&lt;span class="syntax10"&gt;DTEND&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;%Bind(:2)&lt;br /&gt;&lt;span class="syntax10"&gt;SUMMARY&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;%Bind(:3)&lt;br /&gt;&lt;span class="syntax8"&gt;END&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VEVENT&lt;/span&gt;&lt;br /&gt;&lt;span class="syntax8"&gt;END&lt;/span&gt;&lt;span class="syntax18"&gt;:&lt;/span&gt;&lt;span class="syntax9"&gt;VCALENDAR&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;We can serve this text to a client browser using an IScript that looks something like:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; IScript_GetICalendarEvent&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;DateTime&lt;/span&gt; &amp;amp;startTime;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;DateTime&lt;/span&gt; &amp;amp;endTime;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;DateTime&lt;/span&gt; &amp;amp;tempTime;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;startTimeUTC;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;endTimeUTC;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;string&lt;/span&gt; &amp;amp;eventTitle;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;TODO:&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;Initialize&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;date&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;and&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;title&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;variables&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;from&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;database&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="syntax2"&gt;REM&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;**&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;change&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;time&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;zone&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;to&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;your&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;time&lt;/span&gt;&lt;span class="syntax2"&gt; &lt;/span&gt;&lt;span class="syntax2"&gt;zone&lt;/span&gt;&lt;span class="syntax2"&gt;;&lt;/span&gt;&lt;br /&gt;   &amp;amp;tempTime &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;DateTimeToTimeZone&lt;/span&gt;(&amp;amp;startTime, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;PST&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;UTC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &amp;amp;startTimeUTC &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;DateTimeToLocalizedString&lt;/span&gt;(&amp;amp;tempTime, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;yyyyMMdd'T'HHmmss'Z'&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;   &amp;amp;tempTime &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;DateTimeToTimeZone&lt;/span&gt;(&amp;amp;endTime, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;PST&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;UTC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &amp;amp;endTimeUTC &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;DateTimeToLocalizedString&lt;/span&gt;(&amp;amp;tempTime, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;yyyyMMdd'T'HHmmss'Z'&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.SetContentType(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;text/calendar&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="syntax11"&gt;%Response&lt;/span&gt;.WriteLine(&lt;span class="syntax9"&gt;GetHTMLText&lt;/span&gt;(HTML.ICAL_EVT, &amp;amp;startTimeUTC, &amp;amp;endTimeUTC, &amp;amp;eventTitle);&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;/pre&gt;&lt;p&gt;All you have to do is fetch your event data from the database and provide your users with a means to access this IScript. If you want your users to be able to access this IScript from a workflow event, then modify your e-mail workflow template to include a link to this IScript. Likewise, if you want your users to be able to download a calendar event from a page, add a link for this IScript to that page. When creating a link to this IScript, be sure to include all the keys required to fetch the event's data from your database.&lt;/p&gt;&lt;p&gt;If you study the &lt;a href="http://www.ietf.org/rfc/rfc2445.txt"&gt;iCalendar RFC&lt;/a&gt;, you will notice that it also includes a specification for tasks. You could modify this example to add tasks for voucher due dates, etc. I'll leave the possibilities and implementation to your imagination.&lt;/p&gt;&lt;p&gt;This example is only meant to be a starting point. Since iCalendar support has many potential uses in PeopleSoft, I would create a reusable App Class API for rendering iCalendar (ics) files.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-6825127498940953801?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/6825127498940953801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=6825127498940953801' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6825127498940953801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/6825127498940953801'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/08/peoplesoftcalendar-integration.html' title='PeopleSoft/Calendar Integration'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-3389753219187980151</id><published>2008-08-17T21:32:00.000-07:00</published><updated>2008-08-17T21:51:13.487-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Dates'/><title type='text'>DateTimeToTimeZone with Invalid Timezone</title><content type='html'>&lt;p&gt;I've been working on a PeopleCode App Class API for creating iCalendar files. To convert from an event's time zone to the iCalendar UTC format, I've been using the PeopleCode &lt;code&gt;DateTimeToTimeZone&lt;/code&gt; function. I was curious what would happen if I used an invalid time zone value for the source time zone parameter. I thought the function would throw an error. Instead, the function performs the conversion, but uses the &lt;em&gt;base&lt;/em&gt; time zone as the source time zone. The function will also use the base time zone if you pass in an invalid time zone for the destination time zone. In fact, if you pass in an invalid time zone for both the source and destination time zone, then this function will not perform a conversion. Instead, it will return the same value as the &lt;code&gt;OldDateTime&lt;/code&gt; parameter.&lt;/p&gt;&lt;p&gt;Since it is Summer, I thought I would try passing &lt;code&gt;PDT&lt;/code&gt; and &lt;code&gt;EDT&lt;/code&gt;. Of course, I expected a 3 hour difference between the 2 time zones. I was &lt;em&gt;shocked&lt;/em&gt; to see the same results for both time zones. It was this test that clued me in to this &lt;em&gt;base time zone&lt;/em&gt; behavior. Just to confirm, I tried &lt;code&gt;JJM&lt;/code&gt;, &lt;code&gt;123456&lt;/code&gt;, &lt;code&gt;PST&lt;/code&gt;, &lt;code&gt;EST&lt;/code&gt;, and &lt;code&gt;EET&lt;/code&gt;. &lt;code&gt;JJM&lt;/code&gt;, &lt;code&gt;123456&lt;/code&gt;, and &lt;code&gt;PST&lt;/code&gt; all returned the same result, the base time zone value (&lt;code&gt;PST&lt;/code&gt; is my base time zone). &lt;code&gt;EST&lt;/code&gt; and &lt;code&gt;EET&lt;/code&gt; returned the expected values corresponding to those time zones.&lt;/p&gt;&lt;p&gt;Just in case you are working on your own ics calendar integration and are wondering how to format dates, here is the code I'm using:&lt;/p&gt;&lt;pre&gt;&lt;span class="syntax8"&gt;Function&lt;/span&gt; formatDateTimeToUTC (&amp;amp;dttm as &lt;span class="syntax10"&gt;DateTime&lt;/span&gt;, &amp;amp;timezone as &lt;span class="syntax10"&gt;String&lt;/span&gt;) &lt;span class="syntax9"&gt;Returns&lt;/span&gt; &lt;span class="syntax10"&gt;String&lt;/span&gt;&lt;br /&gt;   &lt;span class="syntax8"&gt;Local&lt;/span&gt; &lt;span class="syntax10"&gt;datetime&lt;/span&gt; &amp;amp;tempTime &lt;span class="syntax18"&gt;=&lt;/span&gt; &lt;span class="syntax9"&gt;DateTimeToTimeZone&lt;/span&gt;(&amp;amp;dttm, &amp;amp;timezone, &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;UTC&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;   &lt;span class="syntax9"&gt;Return&lt;/span&gt; &lt;span class="syntax9"&gt;Year&lt;/span&gt;(&amp;amp;tempTime) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;NumberToDisplayString&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;%02&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;Month&lt;/span&gt;(&amp;amp;tempTime)) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;NumberToDisplayString&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;%02&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;Day&lt;/span&gt;(&amp;amp;tempTime)) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;T&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt; &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;NumberToDisplayString&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;%02&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;Hour&lt;/span&gt;(&amp;amp;tempTime)) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;NumberToDisplayString&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;%02&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;Minute&lt;/span&gt;(&amp;amp;tempTime)) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax9"&gt;NumberToDisplayString&lt;/span&gt;(&lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;%02&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;, &lt;span class="syntax9"&gt;Second&lt;/span&gt;(&amp;amp;tempTime)) &lt;span class="syntax18"&gt;|&lt;/span&gt; &lt;span class="syntax13"&gt;"&lt;/span&gt;&lt;span class="syntax13"&gt;Z&lt;/span&gt;&lt;span class="syntax13"&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span class="syntax8"&gt;End-Function&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-3389753219187980151?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/3389753219187980151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=3389753219187980151' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3389753219187980151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/3389753219187980151'/><link rel='alternate' type='text/html' href='http://jjmpsj.blogspot.com/2008/08/datetimetotimezone-with-invalid.html' title='DateTimeToTimeZone with Invalid Timezone'/><author><name>Jim Marion</name><uri>http://www.blogger.com/profile/12995110203807924786</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_gGZ8eLek5pw/SIUmDEb9EAI/AAAAAAAAAAc/tGWXdZEXPME/S220/jjm.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34020393.post-5530159653704247278</id><published>2008-07-31T10:23:00.000-07:00</published><updated>2008-07-31T10:28:41.073-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PeopleCode'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><title type='text'>Using JDBC from PeopleCode</title><content type='html'>&lt;p&gt;&lt;a href="http://psst0101.wordpress.com/"&gt;PSST0101&lt;/a&gt; wrote a very good example of using JDBC from PeopleCode in a post titled &lt;a href="http://psst0101.wordpress.com/2008/07/29/writing-to-access-databases/"&gt;Writing to Access Databases&lt;/a&gt;. Even though this example is Microsoft Access specific, you will notice it uses standard JDBC code, and, therefore, could be used to connect to any database that has a JDBC driver. Just make sure you put your target database JDBC driver in your classpath. On a standard app server, that is either $PS_HOME/class or %PS_HOME%\class.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34020393-5530159653704247278?l=jjmpsj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jjmpsj.blogspot.com/feeds/5530159653704247278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34020393&amp;postID=5530159653704247278' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34020393/posts/default/5530159653704247278'/><l
