/*******************************************************************************
* Copyright (c) 2003-2005, 2013 Till Zoppke.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Till Zoppke - initial API and implementation
******************************************************************************/
package eniac;
import java.applet.Applet;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.InputStream;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import eniac.data.io.ConfigIO;
import eniac.data.model.parent.Configuration;
import eniac.data.type.TypeHandler;
import eniac.io.Progressor;
import eniac.lang.DictionaryIO;
import eniac.log.LogWindow;
import eniac.menu.action.gui.DialogPanel;
import eniac.skin.SkinIO;
import eniac.util.Status;
import eniac.window.EFrame;
/**
* The main class of this project and the one extending the JApplet. So on
* start-up the (empty) constructor is called by the browser, and then the
* methods init() and start(). If you start the program as an application, the
* main(String[]) method does this instead. <br>
* <br>
* The applet's property of participating in the java.awt.component-hierarchy is
* neglected. The applet doesn't display any content itself, but it opens an
* {@link eniac.window.EFrame} for this purpose. So the applet's size should be
* like 1x1 or 0x0 in order to hide its defaulty greyness. <br>
* <br>
* This class principally implements the singleton pattern (just the constructor
* is public because as an applet it has to), There is a couple of other
* singleton classes in this project. These classes implement the
* {@link eniac.LifecycleListener} interface. Their instances can be added as
* listeners to the Main-instance in order to be informed about the applet's
* lifecycle state. <br>
* <br>
* The applet's life cycles through 7 runlevels.
*
* @author zoppke
*/
public class Manager {
/*
* ========================= applet lifecycle states =======================
*/
public enum LifeCycle {
/**
* Default lifecycle state on startup
*/
DEFAULT,
/**
* Livecycle state indicating a successful initialization
*/
INITIALIZED,
/**
* Lifecycle state indicating that the application is running and the
* gui expects input.
*/
RUNNING,
/**
* Lifecycle state indicating that the application is running but the
* gui is blocked.
*/
BLOCKED,
/**
* Lifecycle state indicating that the application is stopped.
*/
STOPPED,
/**
* Lifecycle state indicating that the application is destroyed.
*/
DESTROYED,
}
/*
* =============================== fields ==================================
*/
// flag indicating, whether we have privileged local file access
private boolean _ioAccess;
// reference to the applet. Stays null, if started as application.
private Applet _applet = null;
/*
* ========================== singleton stuff ==============================
*/
private Manager() {
// empty constructor
}
// singleton self reference
private static Manager instance = null;
public static Manager getInstance() {
if (instance == null) {
instance = new Manager();
}
return instance;
}
/*
* =================== lifecycle state transitions =========================
*/
/**
* creates and initializes all instances
*/
public void init() {
Status.initValues();
DictionaryIO.loadDefaultLanguage();
SkinIO.loadDefaultSkin();
Status.LIFECYCLE.setValue(LifeCycle.INITIALIZED);
}
public void start() {
// loading the configuration may open an input dialog for the user.
// as the java-plugin may expect this method to return quickly,
// we start a new thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// load types
TypeHandler.loadTypes();
// load default configuration
ConfigIO.loadDefaultConfiguration();
// check, if we haven't been interrupted
if (Status.LIFECYCLE.getValue() == LifeCycle.INITIALIZED) {
// open eframe and adjust runlevel
EFrame.getInstance().toScreen();
LogWindow.getInstance();
Status.LIFECYCLE.setValue(LifeCycle.RUNNING);
}
}
});
}
public void stop() {
// TODO: check, if we need to block first
// dispose configuration
Configuration config = (Configuration) Status.CONFIGURATION.getValue();
if (config != null) {
config.dispose();
}
Status.CONFIGURATION.setValue(null);
// announce that applet is shutting down
Status.LIFECYCLE.setValue(LifeCycle.STOPPED);
}
public void destroy() {
// check that we haven't been destroyed before
if (Status.LIFECYCLE.getValue() != LifeCycle.STOPPED) {
return;
}
// run finalization.
// Though it probably has no effect, the purpose provides good fortune.
System.runFinalization();
// announce that applet is destroyed
Status.LIFECYCLE.setValue(LifeCycle.DESTROYED);
}
/*
* ============================== methods ==================================
*/
public void setApplet(Applet applet) {
_applet = applet;
}
public void makeDialog(DialogPanel content, String title) {
// create dialog. Add listener and set content pane
final JDialog dialog = new JDialog(Progressor.getInstance(), title, true);
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
((DialogPanel) dialog.getContentPane()).performCancelAction();
}
});
dialog.setContentPane(content);
// bring it to the screen.
dialog.pack();
dialog.setLocationRelativeTo(Progressor.getInstance());
content.setWindow(dialog);
dialog.setVisible(true);
}
/*
* public boolean isPrivileged() { // if we are started as an application,
* we have all privileges if (!isApplet()) { return true; } // check, if we
* already tried to set our SecurityManager if (_privileged != null) {
* return _privileged.booleanValue(); } // This is an applet. Ask for
* priviliges. try { // anonymous security manager granting any permission
* new SecurityManager() { public void checkPermission(Permission
* permission) { // grant any permission }
*
* public void checkPermission(Permission permission, Object obj) { // grant
* any permission } }; // user allowed the signed applet. Set flag.
* _privileged = new Boolean(true); return true; } catch
* (AccessControlException ace) { // User didn't allow the signed applet. //
* Reset flag and display message. // ace.printStackTrace();
* Log.log(LogWords.NO_PRIVILEGES_GRANTED, JOptionPane.INFORMATION_MESSAGE,
* ace.getMessage(), true); _privileged = new Boolean(false); return false;
* } }
*/
// indicates whether this program is started as applet or as application.
// private boolean isApplet() {
// return getAppletContext() == null;
// }
public void block() {
if (Status.LIFECYCLE.getValue() == LifeCycle.RUNNING) {
Status.LIFECYCLE.setValue(LifeCycle.BLOCKED);
}
}
public void unblock() {
if (Status.LIFECYCLE.getValue() == LifeCycle.BLOCKED) {
Status.LIFECYCLE.setValue(LifeCycle.RUNNING);
}
}
// ============================ io methods //===============================
/**
* Opens an <code>inputStream</code> to the specified resource.
*
* @param name
* a <code>string</code> specifying the resource to load
* @return an <code>inputStream</code> if the resource could be found, <br>
* or <code>null</code> otherwise
*/
public InputStream getResourceAsStream(String name) {
return Manager.class.getClassLoader().getResourceAsStream(name);
}
public void setIOAccess(boolean ioAccess) {
_ioAccess = ioAccess;
}
public boolean hasIOAccess() {
return _ioAccess;
}
}