Posts Tagged ‘Coding Tricks’

Server-Side Validation – Deleting Knowledge Directory Cards

Monday, April 29th, 2013

Those of you that are familiar with the WebCenter Interaction Knowledge Directory have likely had a need to delete a batch of cards from a folder. But, if you have a lot of cards and try to delete more than 50 at a time, you’re presented with this little gem:
select-50-javascript-popup

That’s a Javascript popup that refuses to allow you to delete more than 50 cards at a time – but what if you have 25,000 cards that you need to delete? This scenario presented itself to me recently, and I was definitely not looking forward to the prospect of deleting them 50 at a time – 500 separate deletions, which is more complicated by the fact that the Knowledge Directory shows only 20 cards at a time, so for each deletion you have to change the pagination as well.

Importantly, there is a difference between “client-side validation” and “server-side validation” – doing a check in Javascript to prevent users from doing something is completely different than doing a check on the server side for the same reason. Fortunately for me the original developers neglected to do a server-side check that would prevent the deletion of more than 50 cards. So, using the IE Developer Tools (hitting F12), I was able to add a breakpoint at this Javascript condition, and simply use the “Set next statement” option to get this method to return true:
ie-developer-breakpoint

That way, I could get the browser to submit deletion requests for 1,000 or more objects at a time.

Use this as a reminder as you develop your custom code: always confirm data entry both on the client and server sides if you don’t want users doing things they shouldn’t!

Prevent Session Timeouts

Monday, September 24th, 2012

We ran into a problem recently where one of our web applications, Frevvo, was timing out. Because Frevvo is a form building tool and we were conducting an extensive survey, occasionally users would take longer than the standard 15-minute session timeout interval. Consequently, when they submitted the survey, the web app wasn’t able to to reconcile the browser’s cookie with a server-side session, and the submission failed – resulting in a lost survey response and unhappy users.

One option was to increase the session time-out, but that could have resulted in wasted resources for users who had already closed their browser windows. Instead, we wanted users with their browser windows still open to keep their session indefinitely, while others would safely close and conserve server resources. To accomplish this, we used the following JavaScript to ensure that an HTTP request was generated from the browser to the server every 10 minutes.

The request doesn’t actually do anything, but it allows the application server to keep the session alive while the user fills out the survey. Of course, this type of script could be used for any web application that relies on sessions, and I’ve used similar scripts in the past in the Plumtree portal, where a lost session can also cause problems:

<script>
     var sessionInterval = 1000 * 60 *10; // milliseconds to minutes
       var sessionRefreshURL = "/frevvo/web/login";

       refreshFrevvoSession = function() {

              // make the request
              var xmlhttp;
              if (window.XMLHttpRequest)
                     xmlhttp=new XMLHttpRequest();  // IE7+, Firefox, Chrome, Opera, Safari
              else
                     xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");  // code for IE6, IE5
              xmlhttp.open("GET",sessionRefreshURL+"?sessionRefresh="+new Date().getTime(),true);
              xmlhttp.send();

              // set the timer to run again
              setTimeout (refreshFrevvoSession, sessionInterval);
       }
       setTimeout (refreshFrevvoSession, sessionInterval); // set the initial timer
</script>

Don’t send portlet settings you’re not using

Friday, June 15th, 2012

A question came up recently about WCI Portlet Caching, and I thought I’d share with you a little side effect of the caching strategy for portlets.

As you can see in the documentation, portlet caching is pretty intelligent, and has been since the Plumtree days of the MPPE (Massively Parallel Portal Engine) through the Aqualogic User Interaction days of the PPE/LB (Parallel Portal Engine/Load Balancer). The docs basically say that the cache key is created based on the preferences that you send to a portlet.

Which, if you think about it, is really smart: If you’re not sending the user name to the portlet, then it’s likely that the portlet isn’t returning different content based on the user that’s logged in – and therefore you can have one cache entry for that portlet and all users. On the flip side, if you do have a particular preference or user information being sent, then that portlet is likely going to be returning user-specific content based on who’s viewing the portlet, so separate caches have to be maintained for each user.

In other words: to maximize the effectiveness of your cache by preventing cache-thrashing, don’t just blindly check all the boxes in the Web Service configuration. That way, the cache will be able to maintain as few versions as possible for as many users as possible.

Use Adaptive Tags to alternate row colors

Friday, June 8th, 2012

The ability to alternate row colors exists in the WCI portal style sheets, but it’s not completely obvious how to get nice alternating background colors where you’re rendering a list like search results.

There’s some documentation on how to create an adaptive layout Knowledge Base page that’s unusually comprehensive, and it sheds some light on a little trick: Adaptive Tags can do basic math with pt:logic.intexpr.

So for example, you could work your way through a $result list variable and run a mod operator on the index, which basically allows you to compute the remainder of a division operation. Which means, if you divide by 2 for every integer, the remainder will be zero half of the time and 1 the other half.

Using this nugget of knowledge, we can write code like this to alternately apply a background style color to each row of a table:

<pt:logic.intops pt:expr="($result.rank) % 2" pt:key="remainder" />
<pt:logic.intexpr pt:expr="($remainder) > 0" pt:key="isOdd" />
<pt:logic.if pt:expr="$isOdd">
	<pt:logic.iftrue>
		<tr height="25" class="listText listItemOneBG">
	</pt:logic.iftrue>
	<pt:logic.iffalse>
		<tr height="25" class="listText listItemTwoBG">
	</pt:logic.iffalse>
</pt:logic.if>

Credit to Rick Ptasnik for sharing this code a couple of years ago!

Rest APIs in Oracle WebCenter Interaction

Friday, June 1st, 2012

Here’s something I hadn’t really stumbled across before: Oracle added REST APIs to WebCenter Interaction 10gR3. You can use these APIs to do basic Knowledge Directory manipulation, User management, and Activity Stream updates.

Unfortunately, the documentation is weak, the interfaces aren’t comprehensive, and you’ll get a lot more bang for your development buck by just sticking to the Server APIs, or even the IDK. If you want to hazard a look, though, it seems there’s some Javascript included with the portal in the imageserver that you can check out:

Too little, too late for this I’m afraid. As WCI fades away, it’s clear this mechanism for interacting with portal objects will never reach widespread adoption.

Debugging JavaScript in IE, FF, and Chrome

Thursday, October 13th, 2011

Javascript debugging can be tough – particularly when dealing with the multiple tiers that the WebCenter Interaction portal pulls code from, JS can come from different locations and get combined on one page, resulting in name collisions and other subtle problems when the portal page is rendered in the browser.

Sure would be nice to step through that JavaScript code in IE Developer or Firebug, right? Sure, you can set breakpoints in both of those tools, but what if you don’t know exactly where to set it?

Simple, just use this line in your Javascript code:

debugger;

Whenever your debug window is open, this command will instruct the tool to break immediately, which will allow you to monitor variables, set other breakpoints, and step through the code. Bonus tip: whether you’re using Internet Explorer, Firebug, or Chrome, the F12 key will bring up the respective “debug window” in that environment.

One thing to keep in mind with this command is that it breaks the code immediately. So, in the above example, the breakpoint is hit before the DOM even loads. In this case, you may be scratching your head wondering why some elements in the DOM or variables in the script aren’t being displayed properly in the Watch window. That’s because if the JS or HTML comes after your breakpoint, then the browser wouldn’t have processed it from the DOM yet.

Sorting News Articles in ALUI Publisher

Thursday, October 14th, 2010

Out of the box, WebCenter Interaction Publisher has a News portlet template that allows Content Managers to create News Articles, and display them in a summary portlet with a link to see the entire list of articles.  The articles themselves are:

  1. stored as Content Items under the -article_path-/ Articles folder,
  2. created based on the templates in /Portlet Templates/ _NEWS/ en/, and
  3. rendered by the “Main Page” (the portlet itself showing the top n articles) and “Index” (the list of all news articles when the user clicks “more”) Presentation Templates.

The problem is, the articles are listed based on when they were published, not when they were created or modified.  Which doesn’t make sense all the time – what if someone goes in and publishes the entire folder?  You’d end up with all news items showing up on the same day.  The fix here is to update the two Presentation Templates mentioned above to sort and display on when the “article” Content Items were modified, not published.

What you may not know is that when a user creates a portlet from a Publisher template (such as the one in /Portlet Templates/ _NEWS/ en/), Publisher creates a COPY of ALL OBJECTS into the new Publisher folder the Content Manager specifies when creating it.  The implication here is that you not only need to apply these fixes to the Content Item TEMPLATES in Publisher, but also each individual News Portlet independently.  (Or, you could use something like PublisherManager, but that’s another story entirely).

However you do it, the changes that need to be made can be found after the break. (more…)

Deploying WCI API applications without the portal installed

Monday, July 5th, 2010

Many of you have developed WebCenter Interaction portlets (and ALUI before that, and Plumtree before that), and you likely know the difference between the WebCenter Interaction Development Kit (IDK) and the Portal Server API. The difference is pretty straightforward: the IDK provides a relatively simple way to get started and provides Portal Remote Calls (PRC) to manipulate various objects. But it’s not all that powerful, and there are a LOT of things you simply can’t do with the PRC. That’s where the Server API comes in: it can pretty much do anything the portal itself can, but it is significantly more involved to setup. This has to do with how they both work:

  • The IDK / PRC makes remote SOAP calls to the WS API server in the portal stack. The WS API server (and, in some cases, Collaboration Server or Publisher Server) are the services that actually do the heavy lifting, like manipulating the database.
  • The API, on the other hand, is essentially a fully working portal loaded using either .jars (Java) or .DLLs (.NET), so it has full access to do anything the portal can, but also needs all the portal configuration files and secondary libraries (such as for the search server) installed on the machine.

The easiest way to use the API on a remote server is to install a portal component such as the portal itself, or Automation Server. But in some cases, this isn’t desirable; you just want your application running on the remote tier without actually installing the portal. In this case, you will need to do a pseudo-install by copying all the correct files to your portlet server, updating the configuration properly, and setting various environment variables so the portal code can find the files it needs. I should also point out that there is no harm in using Java files on the remote tier even if you’re using a .NET portal; the code is the same, and fundamentally serves the same purpose – handling updates to the database.

So, here’s a quick guide on how to set up a portlet on a remote server that doesn’t have the portal installed:

  1. Make sure your application has the same .jar files (or .dlls, if it’s a .NET app) as the portal is using in your environment: you want to make sure that your remote libraries are exactly the same as the portal libraries so they do the same thing when run.
  2. Copy the ptportal, settings, and common directories from %PT_HOME% on one of your portal servers to a folder on your remote server – in my case, I’m using C:\integryst\, so you should have the following subfolders:
    1. c:\integryst\ptportal
    2. c:\integryst\settings
    3. c:\integryst\common
  3. Update c:\integryst\settings\configuration.xml: replace all instances of c:\bea\alui\ptportal\10.3.0\webapp with c:\integryst (or whatever source/destination folders you’re using). Also, replace the original machine name with the remote server’s machine name.
  4. Set the following environment variables:
    1. ICU_PATH=C:\integryst\common\icu\2.6\bin\native
    2. INXIGHT_PATH=C:\integryst\common\inxight\3.7.7\bin\native
    3. OUTSIDEIN_PATH=C:\integryst\common\outsidein\8.1.9\bin\native
    4. PORTALLIB_PATH=C:\integryst\ptportal\10.3.0\bin\native
    5. PORTAL_HOME=C:\integryst\ptportal\10.3.0
    6. PTHREADS_PATH=C:\integryst\common\pthreads\2002.11.04\bin\native
    7. PT_HOME=C:\integryst
    8. PATH= C:\integryst\ptportal\10.3.0\bin\native; C:\integryst\common\pthreads\2002.11.04\bin\native; C:\integryst\common\outsidein\8.1.9\bin\native; C:\integryst\common\inxight\3.7.7\bin\native; C:\integryst\common\icu\2.6\bin\native;

… and that should do it! Now, when you run your application, if you have PTSpy installed (or even if you don’t), you should see messages in there when the app starts up that look just like the portal startup messages, because that’s essentially what you’re doing in your code – loading the entire portal and leveraging any APIs that are available to the portal itself!

Setting config.xml for WebLogic in Oracle’s jDeveloper

Wednesday, March 24th, 2010

This post is a two-fer.  For those of you that are drinking the Oracle KoolAid, you’ve no doubt been using Oracle’s JDeveloper lately, especially since WebCenter Spaces and Services require it to do anything substantive with them.  In the 10.x line, Oracle incorporated WebLogic (bloatware, IMO, but that’s another post entirely) as the default Application Server for debugging your apps.

The first tip here is that by default WebLogic Server looks at the Authentication Header, and even if you’re your code and app is set to allow anonymous access, if there’s any HTTP Authentication header, WebLogic fails to handle the requests and throws up a browser login dialog:

This has caused me headaches with PublisherEditor, which uses the ALUI Publisher Web Service to run.  The Publisher web service by default uses authentication headers, so the Publisher authentication headers get sent to my portlet code.  Fortunately, the fix for this is pretty straight-forward and documented: add the following to your config.xml file:

<enforce-valid-basic-auth-credentials>
false
</enforce-valid-basic-auth-credentials>

(more…)