Just following on from my response to John Cookson's Future of Programming
thread let me expand on my reference to the Tier3Client object class.
Basically, it creates the Applet's <object> tag for you on-the-fly, and has
the benefit of permitting the run-time discovery and inclusion of
Tier3Client functionality. Appended below is the complete definition (225
lines) but the parameters are as follows: -
application = The name of you've chosen for your Tier3 application
codeBase = The URL for locating the tier3Client.jar file (This must also be
the VMS server that is hosting your Tier3 Application Servers and that you
will be connecting back to)
port = The TCP/IP port number that your application is listening on
maxBuf = The maximum size of a single message in bytes
hostCharSet = The character set for encoding socket traffic
sslReqd = Do you need SSL on the socket (Requires STUNNEL on the server)
guiToolkit = GUI Toolkit for the Login dialog boxes. Currently only
Tier3Client.GUIAWT is available.
idleTimeout = Number of seconds to elapse before connection is closed due to
inactivity (0/null is infinite)
verbosity = Minimum level of messages to log to the JAVA Console
Anyway I'm guessing/hoping it might come in useful some time not too far
away. . .
Cheers Richard Maher
PS. If you find any circular references then please let me know :-)
/**
* Copyright (c) Richard Maher. All rights reserved.
*
* Tier3Client class bridges Javascript and Applet
* functionality.
*/
function Tier3Client(application,
codeBase,
port,
maxBuf,
hostCharSet,
sslReqd,
guiToolkit,
idleTimeout,
verbosity)
{
if (arguments.length < 4) {
throw new Error("Insufficient arguments for Tier3Client");
}
if (!navigator.javaEnabled()) {
alert("You must enable Java Applets in your browser\n" +
"before you can successfully access this page");
throw new Error("Java Applets are not enabled for browser");
}
this.application = application;
this.codeBase = codeBase;
this.port = port;
this.maxBuf = maxBuf;
this.hostCharSet = (hostCharSet == undefined) ? "ISO-8859-1" :
hostCharSet;
this.sslReqd = (sslReqd == undefined) ? "N" :
sslReqd;
this.guiToolkit = (guiToolkit == undefined) ? Tier3Client.GUIAWT :
guiToolkit;
this.idleTimeout = (idleTimeout == undefined) ? 0 :
idleTimeout;
this.verbosity = (verbosity == undefined) ? Tier3Client.WARNING :
verbosity;
var appletId = "Tier3__" + application + "_Applet";
try {
var idTaken = document.getElementById(appletId);
}
catch (err) {};
if (idTaken != null) {
throw new Error("Tier3 Client already registered for " +
this.application);
return;
}
var archiveName = "tier3Client.jar";
var className = "tier3Client/Tier3Application";
var appletParams = [{"name":"archive",
"value":archiveName },
{"name":"codebase",
"value":codeBase },
{"name":"code",
"value":className },
{"name":"java_version",
":"1.6+" },
{"name":"mayscript",
lue":"true" },
{"name":"scriptable",
ue":"true" },
{"name":"codebase_lookup",
"false" },
{"name":"APPLICATION",
"value":application },
{"name":"PORT",
"value":port },
{"name":"MAXBUF",
"value":maxBuf },
{"name":"HOSTCHARSET",
"value":this.hostCharSet},
{"name":"SSLREQD",
"value":this.sslReqd },
{"name":"GUITOOLKIT",
"value":this.guiToolkit },
{"name":"IDLETIMEOUT",
"value":this.idleTimeout},
{"name":"VERBOSITY",
"value":this.verbosity }];
var startParam = 0;
var objectTag = "<object classid=";
if (/Internet Explorer/.test(navigator.appName)) {
objectTag = objectTag +
'"clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ';
} else {
objectTag = objectTag +
'"java:' + className + '.class" type="application/x-java-applet"
' +
'archive="' + codeBase + archiveName + '" ';
startParam = 1;
}
objectTag = objectTag + ' width= "0" height= "0" id="' + appletId +
'">';
for (i=startParam; i<appletParams.length; i++){
objectTag = objectTag + '<param name ="' + appletParams[i].name +
'" ' +
'value ="' + appletParams[i].value +
'">';
}
objectTag = objectTag + "</object>";
var appletDiv = document.createElement("div");
appletDiv.innerHTML = objectTag;
try {
document.body.appendChild(appletDiv);
this.chan = document.getElementById(appletId);
}
catch(err) {
alert("Tier3 unable to load applet for " + this.application +
": -\n" + err.description);
this.chan = null;
};
if (this.chan == null) {
throw new Error("Tier3 was unable to initialize the applet for " +
this.application);
} else {
try {
if (!this.chan.isAuthorized()) {
throw new Error("Tier3 User Authentication unsuccessful for
" + this.application);
}
}
catch(err) {
this.chan.setAttribute("id",null);
this.chan = null;
throw new Error("Tier3 unable to load applet for " +
this.application + ": -\n" + err.description);
}
}
Tier3Client.applications[this.application] = this;
return this;
}
Tier3Client.FACPREFIX = "T3$";
Tier3Client.MAJVERS = 1;
Tier3Client.MINVERS = 0;
Tier3Client.GUIAWT = 1;
Tier3Client.DEBUG = 0;
Tier3Client.INFO = 1;
Tier3Client.WARNING = 2;
Tier3Client.ERROR = 3;
Tier3Client.FATAL = 4;
Tier3Client.errorPage = "Tier3Error.html";
Tier3Client.logoffPage = "Tier3Logoff.html";
Tier3Client.launder =
function(jsobject) {
return jsobject;
};
Tier3Client.prototype = {
send:
function(msgBody, callback, async)
{
if (arguments.length < 2) {
throw new Error("Insufficient arguments for send(msgBody,
callback)");
}
if (typeof callback != "function") {
throw new Error("The 'callback' parameter must be a
function");
}
var noWait = true;
if (arguments.length > 2) {
if (typeof async != "boolean") {
throw new Error("The 'async' parameter must be a
boolean");
}
noWait = async;
}
var chan = this.chan;
var callbackArgs = new Array();
var responseCnt = 0;
var i = 0;
var msgCandidate =
{
msgSlotId : -1,
msgSeqNum : -1,
chan : chan,
callback : callback,
callbackArgs : callbackArgs,
dispatcher :
function(responseMsg,
msgSlotId,
msgSeqNum)
{
this.responseCnt++;
this.msgSlotId = msgSlotId;
this.msgSeqNum = msgSeqNum;
callbackArgs[0] = responseMsg;
try {
callback.apply(this, callbackArgs);
}
catch (err) {
throw new Error("Error calling callback
routine: -\n" + err.description);
}
},
getMsgSeqNum :
function() {
return this.msgSeqNum;
},
getResponseCnt:
function() {
return this.responseCnt;
},
rendezvous :
function() {
return chan.rendezvous();
}
};
for (i=3; i<arguments.length; i++) {
callbackArgs[i - 2] = arguments[i];
}
return chan.send(msgCandidate, msgBody, noWait);
},
appendConsoleMsg:
function(msg)
{
this.chan.appendConsoleMsg(msg);
}
};
Tier3Client.applications = {};
Not that I expect it to interest the backward-looking nostalgia-junkies that
litter the shores of COV, but below is another 100 or so lines of Javascript
that I find very useful. The Event Listener registry was based on the one in
David Mark's library but if you are using a better cross-browser method to
dynamically and non-destructively attach multiple event listeners to an
element then please let me know.
Also, if you will be using Tier3Suggest (250 lines) to provide generic
predictive-text, list-of-values functionality for *any* of the Text (and
Select) fields on your HTML web-pages then you will need to include this
Tier3Common.js file.
Cheers Richard Maher
PS. Of course many of the HP/VMS high priests that you've so desperately and
vainly sought development assistance from in the past would prefer not to
empower you with such knowledge as you would become that much more difficult
to funnel into their little job-preservation schemes. "No, no! You need
Wrappers - You need BridgeWorks, Doh I mean WSIT - You need [g]SOAP - IFDL
is not that bad. Stay here and feed us with your license fees; there be
dragons out there!" Tell me again why Digital went broke?
/**
* Copyright (c) Richard Maher. All rights reserved.
*
* Bits & Bobs that help Tier3 Client Access.
*
* @author Richard Maher
* @version 1.0
*
*/
var listenerRegistry = function() {
var globalObj = this,
actionListeners = {},
targetId = 1,
listenerId = 1;
var checkIn = function(){
if (window.addEventListener)
return function(element, eventName, handler) {
element.addEventListener(eventName, handler, false);
};
if (window.attachEvent)
return function(element, eventName, handler) {
if (!handler._fnId)
handler._fnId = listenerId++;
if (!element._evtId)
element._evtId = targetId++;
else
if (actionListeners[element._evtId + eventName +
handler._fnId])
return;
var normalizedHandler =
function() {
handler.call(
actionListeners[element._evtId +
eventName + handler._fnId].el,
globalObj.window.event);
};
actionListeners[element._evtId + eventName + handler._fnId]
=
{el : element, fn : normalizedHandler};
if (!element.attachEvent('on' + eventName,
normalizedHandler))
throw new Error("Unable to attach listener");
};
throw new Error("Unsupported Browser");
}();
var checkOut = function(){
if (window.removeEventListener)
return function(element, eventName, handler) {
element.removeEventListener(eventName, handler, false);
};
if (window.detachEvent)
return function(element, eventName, handler) {
if (!element._evtId || !handler._fnId)
throw new Error("No such event registered on this
Object");
if (!actionListeners[element._evtId + eventName +
handler._fnId])
throw new Error("Unable to detach listener");
element.detachEvent('on' + eventName,
actionListeners[element._evtId +
eventName + handler._fnId].fn);
actionListeners[element._evtId + eventName +
handler._fnId].el = null;
actionListeners[element._evtId + eventName +
handler._fnId].fn = null;
actionListeners[element._evtId + eventName + handler._fnId]
= null;
};
throw new Error("Unsupported Browser");
}();
return {
checkIn : checkIn,
checkOut : checkOut
};
}();
var getStyle =
function()
{
if (window.getComputedStyle) {
return function(el) {
return window.getComputedStyle(el, null);
}
}
return function(el){
return el.currentStyle;
}
}();
String.prototype.lTrim =
function()
{
return (this+"").replace(/^\s+/,'');
}
String.prototype.rTrim =
function()
{
return (this+"").replace(/\s+$/,'');
}
String.prototype.trim =
function()
{
return (this+"").replace(/^\s+|\s+$/g,'');
}
String.prototype.preWS =
function()
{
return (this+"").replace(/ /g,'\xA0');
}
function reportError(txt)
{
var topWindow=window.top.document.open();
topWindow.write("<html><body style='height: 100%;'><hr><h1>Server
Communications Error</h1><hr>");
topWindow.write("<h2>Please contact Server Support for
assistance.</h2><br />");
topWindow.write('<p style="color:red">' + txt +
"</p></body></html>");
topWindow.close();
return;
}
function dclAST(astAddr)
{
setTimeout(astAddr,0);
return;
}