Skip to content

Instantly share code, notes, and snippets.

@0x6675636b796f75676974687562
Created February 14, 2023 10:21
Show Gist options
  • Save 0x6675636b796f75676974687562/9e20f4c2ceeb02d257dd74cc04307c8b to your computer and use it in GitHub Desktop.
Save 0x6675636b796f75676974687562/9e20f4c2ceeb02d257dd74cc04307c8b to your computer and use it in GitHub Desktop.
/*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* deployJava.js
*
* This file is part of the Deployment Toolkit. It provides functions for web
* pages to detect the presence of a JRE and easily run
* applets or Web Start programs. More Information on usage of the
* Deployment Toolkit can be found in the Deployment Guide at:
* https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/
*
* The "live" copy of this file may be found at :
* http://java.com/js/deployJava.js.
* For web pages provisioned using https, you may want to access the copy at:
* https://java.com/js/deployJava.js.
*
* You are encouraged to link directly to the live copies.
* The above files are stripped of comments and whitespace for performance,
* You can access this file w/o the whitespace and comments removed at:
* https://java.com/js/deployJava.txt.
*
*/
/* The following regular expression is used as the base for the parsing
* of the version string. The version string could be either in the old format
* (1.7.0_65, 1.7.0, 1.7) or in the new format (9.1.2.3, 9.1.2, 9.1, 9)
* and must include only VNUM parts of the version string (the full
* version string format is $VNUM(-$PRE)?(\+$BUILD)?(-$OPT)?, see JEP 223 for more details)
*
* ^ - Beginning of the string
* ( - Capturing group 1
* \\d+ - Match any digit one or more times
* ) - Match once
* (?: - Non capturing group
* \\. - Match '.' character
* ( - Capturing group 2
* \\d+ - Match any digit one or more times
* ) - Match once
* (?: - Non capturing group
* \\. - Match '.' character
* ( - Capturing group 3
* \\d+ - Match any digit one or more times
* ) - Match once
* (?: - Non capturing group
* [_\\.] - Math '_' (old version format) or '.' (new version format)
* ( - Capturing group 4
* \\d+ - Match any digit one or more times
* ) - Match once
* )? - Match zero or one time
* )? - Match zero or one time
* )? - Match zero or one time
*
*
*
*/
var version_regex_base = "^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:[_\\.](\\d+))?)?)?";
/*
* version_regex_base - see version_regex_base comment above
* $ - End of the string
*
*/
var version_regex_strict = version_regex_base + "$";
/*
* version_regex_base - see version_regex_base comment above
* ( - Capturing group 5
* \\* - Match '*'
* | - OR
* \\+ - Match '+'
* )? - Match zero or one time
* $ - End of string
*
*/
var version_regex_with_family_modifier = version_regex_base + "(\\*|\\+)?$";
var deployJava = function() {
/** HTML attribute filter implementation */
var hattrs = {
core: [ 'id', 'class', 'title', 'style' ],
i18n: [ 'lang', 'dir' ],
events: [ 'onclick', 'ondblclick', 'onmousedown', 'onmouseup',
'onmouseover', 'onmousemove', 'onmouseout', 'onkeypress',
'onkeydown', 'onkeyup' ],
applet: [ 'codebase', 'code', 'name', 'archive', 'object',
'width', 'height', 'alt', 'align', 'hspace', 'vspace' ],
object: [ 'classid', 'codebase', 'codetype', 'data', 'type',
'archive', 'declare', 'standby', 'height', 'width', 'usemap',
'name', 'tabindex', 'align', 'border', 'hspace', 'vspace' ]
};
var object_valid_attrs = hattrs.object.concat(hattrs.core, hattrs.i18n,
hattrs.events);
var applet_valid_attrs = hattrs.applet.concat(hattrs.core);
// startsWith() is not supported by IE
if(typeof String.prototype.startsWith !== 'function') {
String.prototype.startsWith = function(searchString, position) {
position = position || 0;
return this.indexOf(searchString, position) === position;
}
}
// generic log function, use console.log unless it isn't available
// then revert to alert()
function log(message) {
if ( ! rv.debug ) {return};
if (console.log) {
console.log(message);
} else {
alert(message);
}
}
function showMessageBox() {
var message = 'Java Plug-in is not supported by this browser. <a href="https://java.com/dt-redirect">More info</a>';
var mbStyle = 'background-color: #ffffce;text-align: left;border: solid 1px #f0c000; padding: 1.65em 1.65em .75em 0.5em; font-family: Helvetica, Arial, sans-serif; font-size: 75%; bottom:0; left:0; right:0; position:fixed; margin:auto; opacity:0.9; width:400px;';
var messageStyle = "border: .85px; margin:-2.2em 0 0.55em 2.5em;";
var closeButtonStyle = "margin-left:10px;font-weight:bold;float:right;font-size:22px;line-height:20px;cursor:pointer;color:red;"
var messageBox = '<span style="'+ closeButtonStyle +'" onclick="this.parentElement.style.display=\'none\';">&times;</span><img src="https://java.com/js/alert_16.png"><div style="'+ messageStyle +'"><p>'+ message + '</p>';
var divTag = document.createElement("div");
divTag.id = "messagebox";
divTag.setAttribute('style', mbStyle);
divTag.innerHTML = messageBox;
document.body.appendChild(divTag);
}
//checks where given version string matches query
//
//NB: assume format is correct. Can add format check later if needed
// from dtjava.js
function versionCheckEx(query, version) {
if (query == null || query.length == 0) return true;
var c = query.charAt(query.length - 1);
//if it is not explicit pattern but does not have update version then need to append *
if (c != '+' && c != '*' && (query.indexOf('_') != -1 && c != '_')) {
query = query + "*";
c = '*';
}
query = query.substring(0, query.length - 1);
//if query ends with ".", "_" then we want to strip it to allow match of "1.6.*" to shorter form such as "1.6"
//TODO: add support for match of "1.7.0*" to "1.7"?
if (query.length > 0) {
var z = query.charAt(query.length - 1);
if (z == '.' || z == '_') {
query = query.substring(0, query.length - 1);
}
}
if (c == '*') {
//it is match if version starts from it
return (version.indexOf(query) == 0);
} else if (c == '+') {
//match if query string is lexicographically smaller
return query <= version;
}
return false;
}
function doVersionCheck(versionPattern, noplugin)
{
var index = 0;
var matchData = versionPattern.match(version_regex_with_family_modifier);
if (matchData != null) {
if(noplugin) {
return true;
}
// default is exact version match
// examples:
// local machine has 1.7.0_04 only installed
// exact match request is "1.7.0_05": return false
// family match request is "1.7.0*": return true
// minimum match request is "1.6+": return true
var familyMatch = false;
var minMatch = false;
var patternArray = new Array();
for (var i = 1; i < matchData.length; ++i) {
// browser dependency here.
// Fx sets 'undefined', IE sets '' string for unmatched groups
if ((typeof matchData[i] == 'string') && (matchData[i] != '')) {
patternArray[index] = matchData[i];
index++;
}
}
if (patternArray[patternArray.length-1] == '+') {
// + specified in request - doing a minimum match
minMatch = true;
familyMatch = false;
patternArray.length--;
} else if (patternArray[patternArray.length-1] == '*') {
// * specified in request - doing a family match
minMatch = false;
familyMatch = true;
patternArray.length--;
} else if (patternArray.length < 4) {
// versionPattern does not include all four version components
// and does not end with a star or plus, it will be treated as
// if it ended with a star. (family match)
minMatch = false;
familyMatch = true;
}
var list = deployJava.getJREs();
for (var i = 0; i < list.length; ++i) {
if (deployJava.compareVersionToPattern(list[i], patternArray,
familyMatch, minMatch)) {
return true;
}
}
return false;
} else {
var msg = 'Invalid versionPattern passed to versionCheck: ' +
versionPattern;
log('[versionCheck()] ' + msg);
alert(msg);
return false;
}
}
function isWebStartFound () {
return doVersionCheck('1.7.0+', false);
}
function isAbsoluteUrl(url) {
var protocols = ["http://", "https://", "file://"];
for (var i=0; i < protocols.length; i++) {
if(url.toLowerCase().startsWith(protocols[i])) {
return true;;
}
}
return false;
}
function getAbsoluteUrl(jnlp){
var absoluteUrl;
if(isAbsoluteUrl(jnlp)) {
absoluteUrl = jnlp;
} else {
var location = window.location.href;
var pos = location.lastIndexOf('/');
var docbase = pos > -1 ? location.substring(0, pos + 1) : location + '/';
absoluteUrl = docbase + jnlp;
}
return absoluteUrl;
}
function launchWithJnlpProtocol(jnlp) {
document.location="jnlp:"+ getAbsoluteUrl(jnlp);
}
function isNoPluginWebBrowser() {
var browser = deployJava.getBrowser();
if (browser == "Edge" || deployJava.browserName2 == 'Chrome' ||
(deployJava.browserName2 == 'FirefoxNoPlugin' && !doVersionCheck("1.8*", false)) ||
deployJava.browserName2 == 'NoActiveX') {
return true;
}
return false;
}
function getWebStartLaunchIconURL() {
var imageUrl = '//java.com/js/webstart.png';
try {
// for http/https; use protocol less url; use http for all other protocol
return document.location.protocol.indexOf('http') != -1 ?
imageUrl : 'https:' + imageUrl;
} catch (err) {
return 'https:' + imageUrl;
}
}
// GetJava page
function constructGetJavaURL(query) {
var getJavaURL = 'https://java.com/dt-redirect';
if (query == null || query.length == 0) return getJavaURL;
if(query.charAt(0) == '&')
{
query = query.substring(1, query.length);
}
return getJavaURL + '?'+ query;
}
function arHas(ar, attr) {
var len = ar.length;
for (var i = 0; i < len; i++) {
if (ar[i] === attr) return true;
}
return false;
}
function isValidAppletAttr(attr) {
return arHas(applet_valid_attrs, attr.toLowerCase());
}
function isValidObjectAttr(attr) {
return arHas(object_valid_attrs, attr.toLowerCase());
}
/**
* returns true if we can enable DT plugin auto-install without chance of
* deadlock on cert mismatch dialog
*
* requestedJREVersion param is optional - if null, it will be
* treated as installing any JRE version
*
* DT plugin for 6uX only knows about JRE installer signed by SUN cert.
* If it encounter Oracle signed JRE installer, it will have chance of
* deadlock when running with IE. This function is to guard against this.
*/
function enableWithoutCertMisMatchWorkaround(requestedJREVersion) {
// Non-IE browser are okay
if ('MSIE' != deployJava.browserName) return true;
// if DT plugin is 10.0.0 or above, return true
// This is because they are aware of both SUN and Oracle signature and
// will not show cert mismatch dialog that might cause deadlock
if (deployJava.compareVersionToPattern(deployJava.getPlugin().version,
["10", "0", "0"], false, true)) {
return true;
}
// If we got there, DT plugin is 6uX
if (requestedJREVersion == null) {
// if requestedJREVersion is not defined - it means ANY.
// can not guarantee it is safe to install ANY version because 6uX
// DT does not know about Oracle certificates and may deadlock
return false;
}
// 6u32 or earlier JRE installer used Sun certificate
// 6u33+ uses Oracle's certificate
// DT in JRE6 does not know about Oracle certificate => can only
// install 6u32 or earlier without risk of deadlock
return !versionCheckEx("1.6.0_33+", requestedJREVersion);
}
/* HTML attribute filters */
var rv = {
debug: null,
/* version of deployJava.js */
version: "20120801",
firefoxJavaVersion: null,
useStaticMimeType: false,
myInterval: null,
preInstallJREList: null,
brand: null,
locale: null,
installType: null,
EAInstallEnabled: false,
EarlyAccessURL: null,
// mime-type of the DeployToolkit plugin object
oldMimeType: 'application/npruntime-scriptable-plugin;DeploymentToolkit',
mimeType: 'application/java-deployment-toolkit',
/* location of the Java Web Start launch button graphic is right next to
* deployJava.js at:
* https://java.com/js/webstart.png
*
* Use protocol less url here for http/https support
*/
launchButtonPNG: getWebStartLaunchIconURL(),
browserName: null,
browserName2: null,
/**
* Returns an array of currently-installed JRE version strings.
* Version strings are of the form #.#[.#[_#]], with the function returning
* as much version information as it can determine, from just family
* versions ("1.4.2", "1.5") through the full version ("1.5.0_06").
*
* Detection is done on a best-effort basis. Under some circumstances
* only the highest installed JRE version will be detected, and
* JREs older than 1.4.2 will not always be detected.
*/
getJREs: function() {
var list = new Array();
if (this.isPluginInstalled()) {
var plugin = this.getPlugin();
var VMs = plugin.jvms;
for (var i = 0; i < VMs.getLength(); i++) {
list[i] = VMs.get(i).version;
}
} else {
var browser = this.getBrowser();
if (browser == 'MSIE') {
if (this.testUsingActiveX('9')) {
list[0] = '9';
} else if (this.testUsingActiveX('1.8.0')) {
list[0] = '1.8.0';
} else if (this.testUsingActiveX('1.7.0')) {
list[0] = '1.7.0';
} else if (this.testUsingActiveX('1.6.0')) {
list[0] = '1.6.0';
} else if (this.testUsingActiveX('1.5.0')) {
list[0] = '1.5.0';
} else if (this.testUsingActiveX('1.4.2')) {
list[0] = '1.4.2';
} else if (this.testForMSVM()) {
list[0] = '1.1';
}
} else if (browser == 'Netscape Family') {
this.getJPIVersionUsingMimeType();
if (this.firefoxJavaVersion != null) {
list[0] = this.firefoxJavaVersion;
} else if (this.testUsingMimeTypes('9')) {
list[0] = '9';
} else if (this.testUsingMimeTypes('1.8')) {
list[0] = '1.8.0';
} else if (this.testUsingMimeTypes('1.7')) {
list[0] = '1.7.0';
} else if (this.testUsingMimeTypes('1.6')) {
list[0] = '1.6.0';
} else if (this.testUsingMimeTypes('1.5')) {
list[0] = '1.5.0';
} else if (this.testUsingMimeTypes('1.4.2')) {
list[0] = '1.4.2';
} else if (this.browserName2 == 'Safari') {
if (this.testUsingPluginsArray('9')) {
list[0] = '9';
} else if (this.testUsingPluginsArray('1.8')) {
list[0] = '1.8.0';
} else if (this.testUsingPluginsArray('1.7')) {
list[0] = '1.7.0';
} else if (this.testUsingPluginsArray('1.6')) {
list[0] = '1.6.0';
} else if (this.testUsingPluginsArray('1.5')) {
list[0] = '1.5.0';
} else if (this.testUsingPluginsArray('1.4.2')) {
list[0] = '1.4.2';
}
}
}
}
if (this.debug) {
for (var i = 0; i < list.length; ++i) {
log('[getJREs()] We claim to have detected Java SE ' + list[i]);
}
}
return list;
},
/**
* Calls this.installLatestJRE() if the requested version of JRE is not installed.
*
* The requestVersion string is of the form #[.#[.#[_#]]][+|*],
* which includes strings such as "1.4", "1.5.0*", and "1.6.0_02+".
* A star (*) means "any version starting within this family" and
* a plus (+) means "any version greater or equal to this".
* "1.5.0*" * matches 1.5.0_06 but not 1.6.0_01, whereas
* "1.5.0+" matches both.
*
*/
installJRE: function(requestVersion) {
log ("The Deployment Toolkit installJRE() method no longer installs JRE. It just checks " +
"if the requested version of JRE is installed and calls installLatestJRE() otherwise. " +
"More Information on usage of the Deployment Toolkit can be found in the "+
"Deployment Guide at https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/");
if (requestVersion == 'undefined' || requestVersion == null) {
requestVersion = '1.1';
}
var matchData = requestVersion.match(version_regex_with_family_modifier);
if (matchData == null){
log('Invalid requestVersion argument to installJRE(): ' + requestVersion);
requestVersion="1.6";
}
if(!this.versionCheck(requestVersion)){
return this.installLatestJRE();
}
return true;
},
/**
* returns true if jre auto install for the requestedJREVersion is enabled
* for the local system; false otherwise
*
* requestedJREVersion param is optional - if not specified, it will be
* treated as installing any JRE version
*
* DT plugin for 6uX only knows about JRE installer signed by SUN cert.
* If it encounter Oracle signed JRE installer, it will have chance of
* deadlock when running with IE. This function is to guard against this.
*/
isAutoInstallEnabled: function(requestedJREVersion) {
// if no DT plugin, return false
if (!this.isPluginInstalled()) return false;
if (typeof requestedJREVersion == 'undefined') {
requestedJREVersion = null;
}
return enableWithoutCertMisMatchWorkaround(requestedJREVersion);
},
/**
* returns true if jre install callback is supported
* callback support is added since dt plugin version 10.2.0 or above
*/
isCallbackSupported: function() {
return this.isPluginInstalled() &&
this.compareVersionToPattern(this.getPlugin().version,
["10", "2", "0"], false, true);
},
/**
* Redirects the browser window to the java.com JRE installation page,
* and (if possible) redirects back to the current URL upon successful
* installation, if the installed version of JRE is below the security
* baseline or Deployment Toolkit plugin is not installed or disabled.
*
*/
installLatestJRE: function() {
log ("The Deployment Toolkit installLatestJRE() method no longer installs JRE. If user's version of "+
"Java is below the security baseline it redirects user to java.com to get an updated JRE. " +
"More Information on usage of the Deployment Toolkit can be found in the Deployment Guide at " +
"://docs.oracle.com/javase/8/docs/technotes/guides/deploy/");
if (!this.isPluginInstalled() || !this.getPlugin().installLatestJRE()) {
var browser = this.getBrowser();
var platform = navigator.platform.toLowerCase();
if (browser == 'MSIE') {
return this.IEInstall();
} else if ((browser == 'Netscape Family') &&
(platform.indexOf('win32') != -1)) {
return this.FFInstall();
} else {
location.href = constructGetJavaURL(
((this.locale != null) ?
('&locale=' + this.locale) : '') +
((this.brand != null) ?
('&brand=' + this.brand) : ''));
}
// we have to return false although there may be an install
// in progress now, when complete it may go to return page
return false;
}
return true;
},
/**
* Ensures that an appropriate JRE is installed and then runs an applet.
* minimumVersion is of the form #[.#[.#[_#]]], and is the minimum
* JRE version necessary to run this applet. minimumVersion is optional,
* defaulting to the value "1.1" (which matches any JRE).
* If an equal or greater JRE is detected, runApplet() will call
* writeAppletTag(attributes, parameters) to output the applet tag,
* otherwise it will call installJRE(minimumVersion + '+').
*
* After installJRE() is called, the script will attempt to detect that the
* JRE installation has completed and begin running the applet, but there
* are circumstances (such as when the JRE installation requires a browser
* restart) when this cannot be fulfilled.
*
* As with writeAppletTag(), this function should only be called prior to
* the web page being completely rendered. Note that version wildcards
* (star (*) and plus (+)) are not supported, and including them in the
* minimumVersion will result in an error message.
*/
runApplet: function(attributes, parameters, minimumVersion) {
if (minimumVersion == 'undefined' || minimumVersion == null) {
minimumVersion = '1.1';
}
var matchData = minimumVersion.match(version_regex_strict);
if (matchData != null) {
var browser = this.getBrowser();
if (browser != '?') {
if(isNoPluginWebBrowser()){
var readyStateCheck = setInterval(function() {
if(document.readyState == "complete"){
clearInterval(readyStateCheck);
showMessageBox();
}
}, 15);
log('[runApplet()] Java Plug-in is not supported by this browser');
return;
}
if (this.versionCheck(minimumVersion + '+')) {
this.writeAppletTag(attributes, parameters);
} else if (this.installJRE(minimumVersion + '+')) {
this.writeAppletTag(attributes, parameters);
}
} else {
// for unknown or Safari - just try to show applet
this.writeAppletTag(attributes, parameters);
}
} else {
log('[runApplet()] Invalid minimumVersion argument to runApplet():' +
minimumVersion);
}
},
/**
* Outputs an applet tag with the specified attributes and parameters, where
* both attributes and parameters are associative arrays. Each key/value
* pair in attributes becomes an attribute of the applet tag itself, while
* key/value pairs in parameters become <PARAM> tags. No version checking
* or other special behaviors are performed; the tag is simply written to
* the page using document.writeln().
*
* As document.writeln() is generally only safe to use while the page is
* being rendered, you should never call this function after the page
* has been completed.
*/
writeAppletTag: function(attributes, parameters) {
var startApplet = '<' + 'applet ';
var params = '';
var endApplet = '<' + '/' + 'applet' + '>';
var addCodeAttribute = true;
if (null == parameters || typeof parameters != 'object') {
parameters = new Object();
}
for (var attribute in attributes) {
if (! isValidAppletAttr(attribute)) {
parameters[attribute] = attributes[attribute];
} else {
startApplet += (' ' +attribute+ '="' +attributes[attribute] + '"');
if (attribute == 'code') {
addCodeAttribute = false;
}
}
}
var codebaseParam = false;
for (var parameter in parameters) {
if (parameter == 'codebase_lookup') {
codebaseParam = true;
}
// Originally, parameter 'object' was used for serialized
// applets, later, to avoid confusion with object tag in IE
// the 'java_object' was added. Plugin supports both.
if (parameter == 'object' || parameter == 'java_object' ||
parameter == 'java_code' ) {
addCodeAttribute = false;
}
params += '<param name="' + parameter + '" value="' +
parameters[parameter] + '"/>';
}
if (!codebaseParam) {
params += '<param name="codebase_lookup" value="false"/>';
}
if (addCodeAttribute) {
startApplet += (' code="dummy"');
}
startApplet += '>';
document.write(startApplet + '\n' + params + '\n' + endApplet);
},
/**
* Returns true if there is a matching JRE version currently installed
* (among those detected by getJREs()). The versionPattern string is
* of the form #[.#[.#[_#]]][+|*], which includes strings such as "1.4",
* "1.5.0*", and "1.6.0_02+".
* A star (*) means "any version within this family" and a plus (+) means
* "any version greater or equal to the specified version". "1.5.0*"
* matches 1.5.0_06 but not 1.6.0_01, whereas "1.5.0+" matches both.
*
* If the versionPattern does not include all four version components
* but does not end with a star or plus, it will be treated as if it
* ended with a star. "1.5" is exactly equivalent to "1.5*", and will
* match any version number beginning with "1.5".
*
* If getJREs() is unable to detect the precise version number, a match
* could be ambiguous. For example if getJREs() detects "1.5", there is
* no way to know whether the JRE matches "1.5.0_06+". versionCheck()
* compares only as much of the version information as could be detected,
* so versionCheck("1.5.0_06+") would return true in in this case.
*
* Invalid versionPattern will result in a JavaScript error alert.
* versionPatterns which are valid but do not match any existing JRE
* release (e.g. "32.65+") will always return false.
*/
versionCheck: function(versionPattern)
{
return doVersionCheck(versionPattern, isNoPluginWebBrowser());
},
/**
* Returns true if an installation of Java Web Start of the specified
* minimumVersion can be detected. minimumVersion is optional, and
* if not specified, '1.4.2' will be used.
* (Versions earlier than 1.4.2 may not be detected.)
*/
isWebStartInstalled: function(minimumVersion) {
if(isNoPluginWebBrowser()) {
return true;
}
var browser = this.getBrowser();
if (browser == '?') {
// we really don't know - better to try to use it than reinstall
return true;
}
if (minimumVersion == 'undefined' || minimumVersion == null) {
minimumVersion = '1.4.2';
}
var retval = false;
var matchData = minimumVersion.match(version_regex_strict);
if (matchData != null) {
retval = this.versionCheck(minimumVersion + '+');
} else {
log('[isWebStartInstaller()] Invalid minimumVersion argument to isWebStartInstalled(): ' + minimumVersion);
retval = this.versionCheck('1.4.2+');
}
return retval;
},
// obtain JPI version using navigator.mimeTypes array
// if found, set the version to this.firefoxJavaVersion
getJPIVersionUsingMimeType: function() {
// Walk through the full list of mime types.
// Try static MIME type first (for JRE versions earlier than JRE 9)
for (var i = 0; i < navigator.mimeTypes.length; ++i) {
var s = navigator.mimeTypes[i].type;
var m = s.match(/^application\/x-java-applet;jpi-version=(.*)$/);
if (m != null) {
this.firefoxJavaVersion = m[1];
this.useStaticMimeType = true;
return;
}
}
for (var i = 0; i < navigator.mimeTypes.length; ++i) {
var s = navigator.mimeTypes[i].type;
var m = s.match(/^application\/x-java-applet;version=(.*)$/);
if (m != null) {
if (this.firefoxJavaVersion == null || this.compareVersions(m[1], this.firefoxJavaVersion)) {
this.firefoxJavaVersion = m[1];
}
}
}
},
// launch the specified JNLP application using the passed in jnlp file
// the jnlp file does not need to have a codebase
// this requires JRE 7 or above to work
// if machine has no JRE 7 or above, we will try to auto-install and then launch
// (function will return false if JRE auto-install failed)
launchWebStartApplication: function(jnlp) {
var uaString = navigator.userAgent.toLowerCase();
this.getJPIVersionUsingMimeType();
// make sure we are JRE 7 or above
if (isWebStartFound() == false) {
if(isNoPluginWebBrowser()) {
launchWithJnlpProtocol(jnlp);
} else if ((this.installJRE('1.7.0+') == false) ||
((this.isWebStartInstalled('1.7.0') == false))) {
return false;
}
}
var jnlpDocbase = null;
// use document.documentURI for docbase
if (document.documentURI) {
jnlpDocbase = document.documentURI;
}
// fallback to document.URL if documentURI not available
if (jnlpDocbase == null) {
jnlpDocbase = document.URL;
}
var browser = this.getBrowser();
var launchTag;
if (browser == 'MSIE') {
launchTag = '<' +
'object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ' +
'width="0" height="0">' +
'<' + 'PARAM name="launchjnlp" value="' + jnlp + '"' + '>' +
'<' + 'PARAM name="docbase" value="' + encodeURIComponent(jnlpDocbase) + '"' + '>' +
'<' + '/' + 'object' + '>';
} else if (browser == 'Netscape Family') {
launchTag = '<embed type="' +
(this.useStaticMimeType ? 'application/x-java-applet;jpi-version='
: 'application/x-java-applet;version=') +
this.firefoxJavaVersion + '" ' +
'width="0" height="0" ' +
'launchjnlp="' + jnlp + '"' +
'docbase="' + encodeURIComponent(jnlpDocbase) + '"' +
' />';
}
if (document.body == 'undefined' || document.body == null) {
document.write(launchTag);
// go back to original page, otherwise current page becomes blank
document.location = jnlpDocbase;
} else {
var divTag = document.createElement("div");
divTag.id = "div1";
divTag.style.position = "relative";
divTag.style.left = "-10000px";
divTag.style.margin = "0px auto";
divTag.className ="dynamicDiv";
divTag.innerHTML = launchTag;
document.body.appendChild(divTag);
}
},
createWebStartLaunchButtonEx: function(jnlp, minimumVersion) {
var url = 'javascript:deployJava.launchWebStartApplication(\'' + jnlp +
'\');';
document.write('<' + 'a href="' + url +
'" onMouseOver="window.status=\'\'; ' +
'return true;"><' + 'img ' +
'src="' + this.launchButtonPNG + '" ' +
'border="0" /><' + '/' + 'a' + '>');
},
/**
* Outputs a launch button for the specified JNLP URL. When clicked, the
* button will ensure that an appropriate JRE is installed and then launch
* the JNLP application. minimumVersion is of the form #[.#[.#[_#]]], and
* is the minimum JRE version necessary to run this JNLP application.
* minimumVersion is optional, and if it is not specified, '1.4.2'
* will be used.
* If an appropriate JRE or Web Start installation is detected,
* the JNLP application will be launched, otherwise installLatestJRE()
* will be called.
*
* After installLatestJRE() is called, the script will attempt to detect
* that the JRE installation has completed and launch the JNLP application,
* but there are circumstances (such as when the JRE installation
* requires a browser restart) when this cannot be fulfilled.
*/
createWebStartLaunchButton: function(jnlp, minimumVersion) {
var url = 'javascript:' +
'if (!deployJava.isWebStartInstalled(&quot;' +
minimumVersion + '&quot;)) {' +
'if (deployJava.installLatestJRE()) {' +
'if (deployJava.launch(&quot;' + jnlp + '&quot;)) {}' +
'}' +
'} else {' +
'if (deployJava.launch(&quot;' + jnlp + '&quot;)) {}' +
'}';
document.write('<' + 'a href="' + url +
'" onMouseOver="window.status=\'\'; ' +
'return true;"><' + 'img ' +
'src="' + this.launchButtonPNG + '" ' +
'border="0" /><' + '/' + 'a' + '>');
},
/**
* Launch a JNLP application, (using the plugin if available)
*/
launch: function(jnlp) {
/*
* Using the plugin to launch Java Web Start is disabled for the time being
*/
document.location=jnlp;
return true;
},
/**
* Launch a JNLP application, using JNLP protocol handler
*/
launchEx: function(jnlp) {
launchWithJnlpProtocol(jnlp);
return true;
},
/*
* returns true if the ActiveX or XPI plugin is installed
*/
isPluginInstalled: function() {
var plugin = this.getPlugin();
if (plugin && plugin.jvms) {
return true;
} else {
return false;
}
},
/*
* returns true if the plugin is installed and AutoUpdate is enabled
*/
isAutoUpdateEnabled: function() {
if (this.isPluginInstalled()) {
return this.getPlugin().isAutoUpdateEnabled();
}
return false;
},
/*
* sets AutoUpdate on if plugin is installed
*/
setAutoUpdateEnabled: function() {
if (this.isPluginInstalled()) {
return this.getPlugin().setAutoUpdateEnabled();
}
return false;
},
/*
* sets the preferred install type : null, online, kernel
*/
setInstallerType: function(type) {
log ("The Deployment Toolkit no longer installs JRE. Method setInstallerType() is no-op. " +
"More Information on usage of the Deployment Toolkit can be found in the Deployment Guide at " +
"://docs.oracle.com/javase/8/docs/technotes/guides/deploy/");
return false;
},
/*
* sets additional package list - to be used by kernel installer
*/
setAdditionalPackages: function(packageList) {
log ("The Deployment Toolkit no longer installs JRE. Method setAdditionalPackages() is no-op. " +
"More Information on usage of the Deployment Toolkit can be found in the Deployment Guide at " +
"://docs.oracle.com/javase/8/docs/technotes/guides/deploy/");
return false;
},
/*
* sets preference to install Early Access versions if available
*/
setEarlyAccess: function(enabled) {
this.EAInstallEnabled = enabled;
},
/*
* Determines if the next generation plugin (Plugin II) is default
*/
isPlugin2: function() {
if (this.isPluginInstalled()) {
if (this.versionCheck('1.6.0_10+')) {
try {
return this.getPlugin().isPlugin2();
} catch (err) {
// older plugin w/o isPlugin2() function -
}
}
}
return false;
},
//support native DT plugin?
allowPlugin: function() {
this.getBrowser();
// Safari and Opera browsers find the plugin but it
// doesn't work, so until we can get it to work - don't use it.
var ret = ('Safari' != this.browserName2 &&
'Opera' != this.browserName2);
return ret;
},
getPlugin: function() {
this.refresh();
var ret = null;
if (this.allowPlugin()) {
ret = document.getElementById('deployJavaPlugin');
}
return ret;
},
compareVersionToPattern: function(version, patternArray,
familyMatch, minMatch) {
if (version == undefined || patternArray == undefined) {
return false;
}
var matchData = version.match(version_regex_strict);
if (matchData != null) {
var index = 0;
var result = new Array();
for (var i = 1; i < matchData.length; ++i) {
if ((typeof matchData[i] == 'string') && (matchData[i] != ''))
{
result[index] = matchData[i];
index++;
}
}
var l = Math.min(result.length, patternArray.length);
// result contains what is installed in local machine
// patternArray is what is being requested by application
if (minMatch) {
// minimum version match, return true if what we have (installed)
// is greater or equal to what is requested. false otherwise.
for (var i = 0; i < l; ++i) {
var resultTemp = parseInt(result[i]);
var patternArrayTemp = parseInt(patternArray[i]);
if (resultTemp < patternArrayTemp) {
return false;
} else if (resultTemp > patternArrayTemp) {
return true;
}
}
return true;
} else {
for (var i = 0; i < l; ++i) {
if (result[i] != patternArray[i]) return false;
}
if (familyMatch) {
// family match - return true as long as what we have
// (installed) matches up to the request pattern
return true;
} else {
// exact match
// result and patternArray needs to have exact same content
return (result.length == patternArray.length);
}
}
} else {
return false;
}
},
getBrowser: function() {
if (this.browserName == null) {
var browser = navigator.userAgent.toLowerCase();
log('[getBrowser()] navigator.userAgent.toLowerCase() -> ' + browser);
// order is important here. Safari userAgent contains mozilla,
// IE 11 userAgent contains mozilla and netscape,
// and Chrome userAgent contains both mozilla and safari.
if (browser.indexOf('edge') != -1) {
this.browserName = 'Edge';
this.browserName2 = 'Edge';
} else if ((browser.indexOf('msie') != -1) && (browser.indexOf('opera') == -1)) {
this.browserName = 'MSIE';
this.browserName2 = 'MSIE';
} else if (browser.indexOf('trident') != -1 || browser.indexOf('Trident') != -1) {
this.browserName = 'MSIE';
this.browserName2 = 'MSIE';
// For Windows 8 and Windows 8.1 check for Metro mode
if (browser.indexOf('windows nt 6.3') != -1 || browser.indexOf('windows nt 6.2') != -1) {
try{
// try to create a known ActiveX object
new ActiveXObject("htmlfile");
} catch(e) {
// ActiveX is disabled
this.browserName2 = 'NoActiveX';
}
}
} else if (browser.indexOf('iphone') != -1) {
// this included both iPhone and iPad
this.browserName = 'Netscape Family';
this.browserName2 = 'iPhone';
} else if ((browser.indexOf('firefox') != -1) && (browser.indexOf('opera') == -1)) {
this.browserName = 'Netscape Family';
if(this.isPluginInstalled()) {
this.browserName2 = 'Firefox';
} else {
this.browserName2 = 'FirefoxNoPlugin';
}
} else if (browser.indexOf('chrome') != -1) {
this.browserName = 'Netscape Family';
this.browserName2 = 'Chrome';
} else if (browser.indexOf('safari') != -1) {
this.browserName = 'Netscape Family';
this.browserName2 = 'Safari';
} else if ((browser.indexOf('mozilla') != -1) && (browser.indexOf('opera') == -1)) {
this.browserName = 'Netscape Family';
this.browserName2 = 'Other';
} else if (browser.indexOf('opera') != -1) {
this.browserName = 'Netscape Family';
this.browserName2 = 'Opera';
} else {
this.browserName = '?';
this.browserName2 = 'unknown';
}
log('[getBrowser()] Detected browser name:'+ this.browserName +
', ' + this.browserName2);
}
return this.browserName;
},
testUsingActiveX: function(version) {
var objectName = 'JavaWebStart.isInstalled.' + version + '.0';
// we need the typeof check here for this to run on FF/Chrome
// the check needs to be in place here - cannot even pass ActiveXObject
// as arg to another function
if (typeof ActiveXObject == 'undefined' || !ActiveXObject) {
log('[testUsingActiveX()] Browser claims to be IE, but no ActiveXObject object?');
return false;
}
try {
return (new ActiveXObject(objectName) != null);
} catch (exception) {
return false;
}
},
testForMSVM: function() {
var clsid = '{08B0E5C0-4FCB-11CF-AAA5-00401C608500}';
if (typeof oClientCaps != 'undefined') {
var v = oClientCaps.getComponentVersion(clsid, "ComponentID");
if ((v == '') || (v == '5,0,5000,0')) {
return false;
} else {
return true;
}
} else {
return false;
}
},
testUsingMimeTypes: function(version) {
if (!navigator.mimeTypes) {
log ('[testUsingMimeTypes()] Browser claims to be Netscape family, but no mimeTypes[] array?');
return false;
}
for (var i = 0; i < navigator.mimeTypes.length; ++i) {
s = navigator.mimeTypes[i].type;
var m = s.match(/^application\/x-java-applet\x3Bversion=(1\.8|1\.7|1\.6|1\.5|1\.4\.2)$/);
if (m != null) {
if (this.compareVersions(m[1], version)) {
return true;
}
}
}
return false;
},
testUsingPluginsArray: function(version) {
if ((!navigator.plugins) || (!navigator.plugins.length)) {
return false;
}
var platform = navigator.platform.toLowerCase();
for (var i = 0; i < navigator.plugins.length; ++i) {
s = navigator.plugins[i].description;
if (s.search(/^Java Switchable Plug-in (Cocoa)/) != -1) {
// Safari on MAC
if (this.compareVersions("1.5.0", version)) {
return true;
}
} else if (s.search(/^Java/) != -1) {
if (platform.indexOf('win') != -1) {
// still can't tell - opera, safari on windows
// return true for 1.5.0 and 1.6.0
if (this.compareVersions("1.5.0", version) ||
this.compareVersions("1.6.0", version)) {
return true;
}
}
}
}
// if above dosn't work on Apple or Windows, just allow 1.5.0
if (this.compareVersions("1.5.0", version)) {
return true;
}
return false;
},
IEInstall: function() {
location.href = constructGetJavaURL(
((this.locale != null) ?
('&locale=' + this.locale) : '') +
((this.brand != null) ? ('&brand=' + this.brand) : ''));
// should not actually get here
return false;
},
done: function (name, result) {
},
FFInstall: function() {
location.href = constructGetJavaURL(
((this.locale != null) ?
('&locale=' + this.locale) : '') +
((this.brand != null) ? ('&brand=' + this.brand) : '') +
((this.installType != null) ?
('&type=' + this.installType) : ''));
// should not actually get here
return false;
},
// return true if 'installed' (considered as a JRE version string) is
// greater than or equal to 'required' (again, a JRE version string).
compareVersions: function(installed, required) {
var a = installed.split('.');
var b = required.split('.');
for (var i = 0; i < a.length; ++i) {
a[i] = Number(a[i]);
}
for (var i = 0; i < b.length; ++i) {
b[i] = Number(b[i]);
}
if (a.length == 2) {
a[2] = 0;
}
if (a[0] > b[0]) return true;
if (a[0] < b[0]) return false;
if (a[1] > b[1]) return true;
if (a[1] < b[1]) return false;
if (a[2] > b[2]) return true;
if (a[2] < b[2]) return false;
return true;
},
enableAlerts: function() {
// reset this so we can show the browser detection
this.browserName = null;
this.debug = true;
},
poll: function() {
this.refresh();
var postInstallJREList = this.getJREs();
if ((this.preInstallJREList.length == 0) &&
(postInstallJREList.length != 0)) {
clearInterval(this.myInterval);
}
if ((this.preInstallJREList.length != 0) &&
(postInstallJREList.length != 0) &&
(this.preInstallJREList[0] != postInstallJREList[0])) {
clearInterval(this.myInterval);
}
},
writePluginTag: function() {
var browser = this.getBrowser();
if (browser == 'MSIE') {
document.write('<' +
'object classid="clsid:CAFEEFAC-DEC7-0000-0001-ABCDEFFEDCBA" ' +
'id="deployJavaPlugin" width="0" height="0">' +
'<' + '/' + 'object' + '>');
} else if (browser == 'Netscape Family' && this.allowPlugin()) {
this.writeEmbedTag();
}
},
refresh: function() {
navigator.plugins.refresh(false);
var browser = this.getBrowser();
if (browser == 'Netscape Family' && this.allowPlugin()) {
var plugin = document.getElementById('deployJavaPlugin');
// only do this again if no plugin
if (plugin == null) {
this.writeEmbedTag();
}
}
},
writeEmbedTag: function() {
var written = false;
if (navigator.mimeTypes != null) {
for (var i=0; i < navigator.mimeTypes.length; i++) {
if (navigator.mimeTypes[i].type == this.mimeType) {
if (navigator.mimeTypes[i].enabledPlugin) {
document.write('<' +
'embed id="deployJavaPlugin" type="' +
this.mimeType + '" hidden="true" />');
written = true;
}
}
}
// if we ddn't find new mimeType, look for old mimeType
if (!written) for (var i=0; i < navigator.mimeTypes.length; i++) {
if (navigator.mimeTypes[i].type == this.oldMimeType) {
if (navigator.mimeTypes[i].enabledPlugin) {
document.write('<' +
'embed id="deployJavaPlugin" type="' +
this.oldMimeType + '" hidden="true" />');
}
}
}
}
}
}; // deployJava object
rv.writePluginTag();
if (rv.locale == null) {
var loc = null;
if (loc == null) try {
loc = navigator.userLanguage;
} catch (err) { }
if (loc == null) try {
loc = navigator.systemLanguage;
} catch (err) { }
if (loc == null) try {
loc = navigator.language;
} catch (err) { }
if (loc != null) {
loc.replace("-","_")
rv.locale = loc;
}
}
return rv;
}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment