dmose%mozilla.org ce50f7d151 updated license boilerplate to xPL 1.1, a=chofmann@netscape.com,r=endico@mozilla.org
git-svn-id: svn://10.0.0.236/trunk@52900 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 02:47:15 +00:00

716 lines
24 KiB
Java

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
* Core Application class for debugger (used both when app or applet)
*/
// when who what
// 06/27/97 jband added this header to my code
//
package com.netscape.jsdebugging.ifcui;
import java.io.*;
import java.awt.Dimension;
import netscape.application.*;
import netscape.util.*;
import com.netscape.jsdebugging.api.*;
import netscape.javascript.*;
import netscape.security.PrivilegeManager;
import com.netscape.jsdebugging.ifcui.palomar.widget.layout.*;
import com.netscape.jsdebugging.ifcui.palomar.widget.toolbar.*;
import com.netscape.jsdebugging.ifcui.palomar.widget.toolTip.*;
import com.netscape.jsdebugging.ifcui.palomar.widget.PopupButton;
import com.netscape.jsdebugging.ifcui.palomar.util.*;
import com.netscape.jsdebugging.ifcui.palomar.util.AssertFailureHandler;
public class JSDebuggerApp
extends Application
implements Target, AssertFailureHandler, EmperorOwner
{
private static final boolean WILL_EXPIRE = false;
private static final boolean IS_INTERNAL_RELEASE = true;
private static final boolean ALWAYS_SHOW_BUILD_DATE = true;
// "15 Sep 1997" -> 874306800000L // PR1 date
// "31 Oct 1997" -> 878284800000L // PR2 date
// "31 Mar 1998" -> 891331200000L // 1.1 PR1 Date (proposed)
private static final long _deathTime = 891331200000L;
public static final int MAJOR_VERSION = 1;
public static final int MINOR_VERSION = 2;
public static final int PREVIEW_VERSION = 1;
private static final String _mainTitleLocal = "Netscape JavaScript Debugger";
// private static final String _mainTitleLocal = "(CLIENT) Netscape JavaScript Debugger";
private static final String _mainTitleServer = "(SERVER) Netscape JavaScript Debugger";
private static final String _mainTitleRhino = "Netscape JavaScript for Java Debugger";
// this is usually the string literal version of Emperor 'modes'
// -- parsed below --
public void setMode(String s)
{
if(AS.S)ER.T(null==_emperor, "attempt to setMode while running", this);
_modeString = s;
}
public void setHost(String s)
{
if(AS.S)ER.T(null==_emperor, "attempt to setHost while running", this);
_host = s;
}
// override Application.init()
public void init()
{
super.init();
initForReal();
}
private void initForReal()
{
// System.out.println("++++ initForReal() start" );
// Let's ask for everything upfront to get this all out of the
// way (from the user's point of view)
try
{
PrivilegeManager.enablePrivilege("Debugger");
PrivilegeManager.enablePrivilege("UniversalFileRead");
// It doesn't really matter that much if the user says no to
// these (at this point)
try
{
PrivilegeManager.enablePrivilege("UniversalFileWrite");
PrivilegeManager.enablePrivilege("UniversalTopLevelWindow");
}
catch(Exception e)
{
// just eat these
}
}
catch(Exception e)
{
performCommandLater( this, LOAD_FAILED_CMD, null );
return;
}
if(AS.DEBUG)
{
Thread t = Thread.currentThread();
_uiThreadForAssertCheck = t;
ER.setFailureHandler(t,this);
}
// set some static globals...
Env.Init();
// we don't want to spit this info to the console if not an applet
if( isApplet() )
{
int platform = Env.getCoursePlatformType();
System.out.println("JSD platform is " +
(platform == Env.ENV_WIN ?
"Windows" :
platform == Env.ENV_MAC ?
"Mac" :
"Unix" ));
System.out.println("JSD install directory: " + Env.getCodebaseDir());
System.out.println("JSD prefs directory: " + Env.getPrefsDir());
}
// set mode
if(null == _modeString)
_modeString = parameterNamed( "DebugHostMode" );
if(null != _modeString)
{
if( _modeString.equals("LOCAL") )
_mode = Emperor.LOCAL;
else if( _modeString.equals("REMOTE_SERVER") )
_mode = Emperor.REMOTE_SERVER;
else if( _modeString.equals("RHINO") )
_mode = Emperor.RHINO;
else
_mode = Emperor.LOCAL;
}
else
_mode = Emperor.LOCAL;
// set host (this may be further massaged below...
if(null == _host)
_host = parameterNamed( "DebugHost" );
// init the system that will allow us access to the startup prefs file
// this needs to be done after our mode is established
_initStartupPrefs();
if(AS.DEBUG)
{
if( Emperor.LOCAL == _mode )
Log.setFilename("jsdclog.log", true);
else
Log.setFilename("jsdslog.log", true);
Log.setEnabled(true);
Log.setEnabledType(Log.ERROR, true);
Log.setEnabledType(Log.WARN, true);
Log.setEnabledType(Log.TRACE, false);
Log.setShowDate(true);
Log.setShowThreadName(true);
Log.setLogToFile(true);
Log.setLogToConsole(false);
Log.log(null, "+++++++++++++++ startup begin +++++++++++++++" );
// we don't want to spit this info to the console if not an applet
if( isApplet() )
System.out.println("JSD is using log file: " + Log.getFilename());
}
else
{
Log.setEnabled(false);
}
_mainWindow = new ToolTipExternalWindow();
Dimension res = AWTCompatibility.awtToolkit().getScreenSize();
_mainWindow.setBounds(0, 0, 525, res.height - 50);
if( Emperor.REMOTE_SERVER == _mode )
_mainWindow.setTitle(_mainTitleServer);
else if( Emperor.RHINO == _mode )
_mainWindow.setTitle(_mainTitleRhino);
else
_mainWindow.setTitle(_mainTitleLocal);
setMainRootView(_mainWindow.rootView());
_mainWindow.show();
setWaitCursor(true);
StatusWindow statusWindow = new StatusWindow();
statusWindow.setText("Loading...");
statusWindow.show();
if( WILL_EXPIRE && daysTillDeath() <= 0 )
{
setWaitCursor(false);
Alert.runAlertInternally( Alert.warningImage(),
"Error",
"This Preview copy of Netscape JavaScript Debugger has expired\n"
+ "Please go to the Netscape home site to get a new version\n"
+ "\n"
+ " The debugger will exit now...",
"OK", null, null );
performCommandLater( this, LOAD_FAILED_CMD, null );
return;
}
if( staleTwisterClassesFound() )
{
setWaitCursor(false);
Alert.runAlertInternally( Alert.warningImage(),
"Error",
"Conflict with obsolete Java classes detected.\n"
+ "\n"
+ "Netscape Visual JavaScript Preview Release 1 must be uninstalled\n"
+ "before the Netscape JavaScript Debugger can be run.\n"
+ "\n"
+ "Please see the Debugger release notes for additional information\n"
+ "\n"
+ " The debugger will exit now...",
"OK", null, null );
performCommandLater( this, LOAD_FAILED_CMD, null );
return;
}
// statusWindow.setText("Checking License...");
// if( ! userHasAgreedToLicense() )
// {
// performCommandLater( this, LOAD_FAILED_CMD, null );
// return;
// }
// statusWindow.setText("Loading...");
if( Emperor.REMOTE_SERVER == _mode && null == _host )
{
String hostname = _readHostName();
HostNameDialog dlg = new
HostNameDialog("Choose Server",
"Enter Hostname or ip address of Server",
hostname);
while(true)
{
statusWindow.hide();
setWaitCursor(false);
dlg.showModally();
setWaitCursor(true);
if( HostNameDialog.OK == dlg.getKeyPressed() )
{
statusWindow.show();
statusWindow.setText("Looking for Server...");
hostname = dlg.getHostName();
_host = "http://" + hostname;
if( isDebuggingSupported() )
break;
setWaitCursor(false);
if( Alert.DEFAULT_OPTION ==
Alert.runAlertInternally( Alert.warningImage(),
"Error",
"JavaScript Debugger support was not found in "+ _host+"\n"
+ "\n"
+ "Try a different Server?",
"Yes", "No", null ) )
{
setWaitCursor(true);
continue;
}
setWaitCursor(true);
_host = null;
break;
}
else if( HostNameDialog.LOCALHOST == dlg.getKeyPressed() )
{
statusWindow.show();
hostname = "127.0.0.1";
_host = "http://" + hostname;
break;
}
else // if( HostNameDialog.CANCEL == dlg.getKeyPressed() )
{
statusWindow.show();
_host = null;
break;
}
}
if( null == _host )
{
performCommandLater( this, LOAD_FAILED_CMD, null );
return;
}
statusWindow.setText("Looking for Server...");
_writeHostName(hostname);
}
if( ! isDebuggingSupported() )
{
String core_msg;
String suggestion;
if( Emperor.LOCAL == _mode )
{
core_msg = "JavaScript Debugger support was not found in this copy of Navigator";
suggestion = "";
}
else
{
core_msg = "JavaScript Debugger support was not found in "+ _host;
suggestion = "If the server has been restarted, then it may be necessary\n" +
"to restart Navigator in order to re-establish the connection\n\n";
}
setWaitCursor(false);
Alert.runAlertInternally( Alert.warningImage(),
"Error",
core_msg
+ "\n\n"
+ suggestion
+ "Please see the Debugger release notes for troubleshooting information\n"
+ "\n"
+ " The debugger will exit now...",
"OK", null, null );
performCommandLater( this, LOAD_FAILED_CMD, null );
return;
}
if( Emperor.REMOTE_SERVER == _mode )
statusWindow.setText("Found Server...");
Menu mainMenu = new Menu(true);
MenuView menuView = new MenuView(mainMenu);
MenuItem fileMenu = mainMenu.addItemWithSubmenu("File");
MenuItem item;
_emperor = new Emperor( this, _mainWindow, mainMenu, fileMenu,
menuView, _mode, _host, statusWindow );
addSeparator(fileMenu);
item = fileMenu.submenu().addItem("Exit", EXIT_APP_CMD, this);
MenuItem helpMenu = mainMenu.addItemWithSubmenu("Help");
item = helpMenu.submenu().addItem("About", SHOW_ABOUT_CMD, this);
menuView.sizeToMinSize();
_mainWindow.setMenuView(menuView);
_mainWindow.menuView().setDirty(true);
statusWindow.hide();
setWaitCursor(false);
if(AS.DEBUG)Log.log(null, "startup success" );
_signalInitSuccessToHTMLPage();
// System.out.println("++++ initForReal() end" );
}
/*
* Temporary method to add menu item separators until IFC gets a native one....
*/
private static void addSeparator(MenuItem item)
{
item.submenu().addSeparator();
// AWTCompatibility.awtMenuForMenu(item.submenu()).addSeparator();
}
// implement Target interface
public void performCommand( String cmd, Object theObject )
{
if( cmd.equals(EXIT_APP_CMD) )
{
if( null != _mainWindow )
_mainWindow.hide();
}
else if( cmd.equals(LOAD_FAILED_CMD) )
{
if( null != _mainWindow )
_mainWindow.hide();
// close the applet that owns us
try
{
JSObject jso = JSObject.getWindow( AWTCompatibility.awtApplet() );
if( null != jso )
jso.eval( "window.close()" );
}
catch(Throwable t){} // eat failure
}
else if( cmd.equals(SHOW_ABOUT_CMD) )
{
showAboutDialog();
}
}
// assumes that wait cursor is showing!!!
private boolean userHasAgreedToLicense()
{
if(AS.S)ER.T(_waitCount == 1,"hasUserAgreedToLicense() called when _waitCount != 1");
String baseDir = Env.getCodebaseDir();
if( null == baseDir )
{
System.err.println( "failed to get CodebaseDir, can't show license");
return false;
}
String acceptFilename = baseDir
+ "accept_"+MAJOR_VERSION+""+MINOR_VERSION
+ (PREVIEW_VERSION != 0 ? ("_pr"+PREVIEW_VERSION):"")
+ ".txt";
if( new java.io.File(acceptFilename).exists() )
return true;
String licenseHtmlFilename = baseDir+"license.html";
LicenseViewer v =
new LicenseViewer("Netscape JavaScript Debugger License", licenseHtmlFilename);
if( ! v.HtmlLoadedSuccesfully() )
{
setWaitCursor(false);
int answer = Alert.runAlertInternally( Alert.warningImage(),
"Error",
"Unable to load license text from\n"
+ licenseHtmlFilename
+ "\n"
+ "\n"
+ "license.html should be in the same directory as the debugger start page.\n"
+ "\n"
+ " Do you accept the terms of the license?",
"I Accept", "Cancel", null );
setWaitCursor(true);
return Alert.DEFAULT_OPTION == answer;
}
setWaitCursor(false);
v.showModally();
setWaitCursor(true);
if(v.userPressedAccept())
{
try
{
// write a zero length file
new FileOutputStream(acceptFilename).close();
// DataOutputStream dos =
// new DataOutputStream(new FileOutputStream(acceptFilename));
// dos.writeBytes("accepted");
// if( null != dos )
// dos.close();
}
catch(Exception e)
{
// eat it...
}
return true;
}
return false;
}
private void showAboutDialog()
{
String title = "About";
String msg;
msg = "Netscape JavaScript Debugger\n";
msg += "Version "+MAJOR_VERSION+"."+MINOR_VERSION;
if( PREVIEW_VERSION != 0 )
msg += " Preview Release "+PREVIEW_VERSION;
msg += "\n\n";
if(AS.DEBUG || IS_INTERNAL_RELEASE || ALWAYS_SHOW_BUILD_DATE)
msg += "Built: "+BuildDate.display()+"\n\n";
if( WILL_EXPIRE )
msg += "This software will expire in "+ daysTillDeath() +" days\n\n";
msg += "This software is subject to the terms\n";
msg += "of the accompanying license agreement.\n";
Alert.runAlertInternally( title, msg, "OK", null, null );
}
public boolean isDebuggingSupported()
{
return Emperor.isDebuggingSupported(_mode, _host);
}
private void _initStartupPrefs()
{
String prefsDir = Env.getPrefsDir();
if( null == prefsDir )
return;
String startupPrefsFullFilename;
if( Emperor.LOCAL == _mode )
startupPrefsFullFilename = prefsDir + _startupPrefsFilenameClient;
else
startupPrefsFullFilename = prefsDir + _startupPrefsFilenameServer;
_startupPrefsFile = new java.io.File(startupPrefsFullFilename);
}
// NOTE: this is destructive write of just this one key=value pair
// This system will have to be improved if further pairs are needed.
private void _writeHostName(String hostname)
{
if( null == _startupPrefsFile )
return;
try
{
DataOutputStream dos =
new DataOutputStream(new FileOutputStream(_startupPrefsFile));
dos.writeBytes(_LastServerHostNameKey+"="+hostname);
if( null != dos )
dos.close();
}
catch(Exception e)
{
// eat it...
}
}
private String _readHostName()
{
String retval = "127.0.0.1";
if( null == _startupPrefsFile )
return retval;
// any existing prefs?
if( ! _startupPrefsFile.exists() )
return retval;
try
{
DataInputStream dis =
new DataInputStream(new FileInputStream(_startupPrefsFile));
String line;
String key = _LastServerHostNameKey+"=";
while( null != (line = dis.readLine()) )
{
if( line.startsWith(key) )
{
retval = line.substring(key.length()).trim();
break;
}
}
if( null != dis )
dis.close();
}
catch(Exception e)
{
// eat it...
}
return retval;
}
/*
* The scheme is that if the applet tag has a PARAM called "AppletInitProp",
* then we will use it to get the name of the window property to be set.
* We then set that window property to "1".
*/
private void _signalInitSuccessToHTMLPage()
{
String initProp = parameterNamed( "AppletInitProp" );
if( null == initProp )
return;
String expression = "window."+initProp+"=1";
try
{
JSObject jso = JSObject.getWindow( AWTCompatibility.awtApplet() );
if( null != jso )
{
// System.out.println( "writing: " + expression );
jso.eval( expression );
}
}
catch(Throwable t){} // eat failure
}
private int daysTillDeath()
{
long millisecondsTillDeath = _deathTime - new java.util.Date().getTime();
return 1 + (int) (millisecondsTillDeath / (1000*60*60*24));
}
// this tries to run a method which was not present in Twister PR1 but
// is present in our jar. If this fails, then Twister PR1 is in the
// classpath (which is very bad for us).
private boolean staleTwisterClassesFound()
{
try
{
new com.netscape.jsdebugging.ifcui.palomar.widget.PopupButton(null,null,null,null,null).showLabel(false);
}
catch(Throwable t)
{
return true;
}
return false;
}
// override Application.cleanup
public void cleanup()
{
if( null != _emperor )
_emperor.IFC_cleanupCalled();
super.cleanup();
}
// implement AssertFailureHandler
public int assertFailed( String msgRaw, String msgCooked, Object ob )
{
if(AS.DEBUG)
{
// All these single use vars are here because the code
// used to allow for internal or external dlgs (and may again)
Image img = Alert.questionImage();
String title = "Assertion failed";
String msg = msgCooked + "\n\n" + "(set debugger to catch \"com.netscape.jsdebugging.ifcui.palomar.util.DebuggerCaughtException\")";
String opt1 = "Continue";
String opt2 = "Abort";
String opt3 = "Debug";
Log.error("Assertion failed", msgCooked );
int choice = Alert.runAlertExternally(img,title,msg,opt1,opt2,opt3);
switch(choice)
{
case Alert.DEFAULT_OPTION: return AssertFailureHandler.CONTINUE;
case Alert.SECOND_OPTION: return AssertFailureHandler.ABORT;
case Alert.THIRD_OPTION: return AssertFailureHandler.DEBUG;
}
}
return AssertFailureHandler.DEBUG;
}
// implement EmperorOwner
public void setWaitCursor(boolean set)
{
_waitCount += set ? 1 : -1;
if(AS.S)ER.T(_waitCount >= 0,"_waitCount went negative", this );
if(AS.S)ER.T(Thread.currentThread()==_uiThreadForAssertCheck,"setWaitCursor() called on non-UI thread",this);
if( (1 == _waitCount && set) || (0 == _waitCount && !set) )
{
Vector windows = externalWindows();
int size = windows.size();
for (int i= 0; i < size; i++)
{
ExternalWindow window = (ExternalWindow)windows.elementAt(i);
FoundationPanel panel = window.panel();
if (set)
panel.setCursor(View.WAIT_CURSOR);
else
panel.setCursor(View.ARROW_CURSOR);
}
}
}
/****************************************************/
// data...
private ToolTipExternalWindow _mainWindow;
private InternalWindow _toolBarWindow;
private Emperor _emperor;
private String _modeString;
private int _mode;
private String _host;
private Thread _uiThreadForAssertCheck = null;
private int _waitCount = 0;
private static final String _startupPrefsFilenameServer = "jsdsstrt.txt";
private static final String _startupPrefsFilenameClient = "jsdcstrt.txt";
private java.io.File _startupPrefsFile;
private static final String _LastServerHostNameKey = "LastHost0";
private static final String EXIT_APP_CMD = "EXIT_APP_CMD";
private static final String LOAD_FAILED_CMD = "LOAD_FAILED_CMD";
private static final String SHOW_ABOUT_CMD = "SHOW_ABOUT_CMD";
}