In Part 1 we talked about the overall objective, and how we store the JavaScript code in a database. In Java we open a ResultSet on a statement something like this:

SELECT EventName, MimeType, Action FROM OrderEntryEventHandlers ORDER BY EventName, MimeType;

If you recall from Part 1, we use a naming convention to assign JavaScript code to events in the Java order-taking program. For example, any JavaScript whose EventName begins with AfterInsertPart gets executed whenever a new part is added to the order. Any JavaScript whose EventName starts with AfterInsertNote gets executed whenever a new note is added to the order. And so forth.

As we read the JavaScript from the database, we assemble the scripts in a HashMap whose key is the prefix from the naming convention. Then later we retrieve the JavaScript from the HashMap, using the appropriate key, and execute it.

The code to store the JavaScript looks something like this (I’ve removed some code that is irrelevant to this discussion, and revised some of the remaining code- we’re able to do a little more here that I won’t get into):

HashMap<String, String> standardActions = new java.util.HashMap<String, String>(4);
standardActions.put("BeforeSaveOrder", "");
standardActions.put("AfterInsertNote", "");
standardActions.put("AfterInsertPart", "");
standardActions.put("AfterRetrieveCustomer", "");
ResultSet rs = stmt.executeQuery("SELECT EventName, MimeType, Action FROM OrderEntryEventHandlers ORDER BY EventName, MimeType");
while ( {
String eventName = rs.getString("EventName").trim();
mimeType = rs.getString("MimeType").trim();
String action = rs.getString("Action").trim();
if (action.length() > 0) {
String std = "";
for (String key : standardActions.keySet())
if (eventName.length() >= key.length() && eventName.substring(0, key.length()).equalsIgnoreCase(key))
std = key;
if (std.length() > 0) {
String val = standardActions.get(std);
if (mimeType.equalsIgnoreCase("application/javascript")) {
val += "\ntry {" + action + "} catch (e) {util.alert(\"Exception in " + eventName + ": \" + e);}\n";
standardActions.put(std, val);
for (String key : standardActions.keySet()) {
String val = standardActions.get(key);
if (val.length() > 0) {
am.put(key, new RunScript(val, new javax.activation.MimeType("application/javascript"), mainForm));

In the above code we read each script from the database, match its name to one of our conventional prefixes, enclose it in a try-catch black, and append it to any other scripts we’ve previously found for the same prefix. Then in the last loop above we make a RunScript object for each of our standard prefixes. So, for example, we’ve got a RunScript object that encompasses all of our AfterInsertPart scripts, another that encompasses all of our AfterInsertNote scripts, etc. The ActionMap is bound to our main form. The mainForm object in the ActionMap.put() invocation is a reference to our main form, which we store in the RunScript object so the JavaScript has access to it. The RunScript object itself implements the javax.swing.Action interface.

The util.alert call that you see in the above catch block just displays a standard alert box to show the indicated error message.

So much for run time initialization. How about execution? That looks something like this:

javax.swing.Action act = mainForm.getActionMap().get("AfterInsertPart");
if (act != null)
act.actionPerformed(new java.awt.event.ActionEvent(this, 0, "AfterInsertPart"));

In the next installment we’ll take a closer look at the RunScript object.

Leave a Reply

Your email address will not be published. Required fields are marked *

 characters available