/*
** This file is part of Filius, a network construction and simulation software.
**
** Originally created at the University of Siegen, Institute "Didactics of
** Informatics and E-Learning" by a students' project group:
** members (2006-2007):
** André Asschoff, Johannes Bade, Carsten Dittich, Thomas Gerding,
** Nadja Haßler, Ernst Johannes Klebert, Michell Weyer
** supervisors:
** Stefan Freischlad (maintainer until 2009), Peer Stechert
** Project is maintained since 2010 by Christian Eibl <filius@c.fameibl.de>
** and Stefan Freischlad
** Filius is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or
** (at your option) version 3.
**
** Filius is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
** PURPOSE. See the GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Filius. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Main.java
*
* Created on 28. April 2006, 18:30
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package filius;
import java.awt.Rectangle;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Locale;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import filius.gui.GUIContainer;
import filius.gui.GUIMainMenu;
import filius.gui.JMainFrame;
import filius.gui.SplashScreen;
import filius.rahmenprogramm.I18n;
import filius.rahmenprogramm.Information;
import filius.rahmenprogramm.SzenarioVerwaltung;
import filius.rahmenprogramm.TeeOutputStream;
/**
* In dieser Klasse wird die Anwendung gestartet und beendet. Das wird in den
* entsprechenden statischen Methoden implementiert.
*/
public class Main implements I18n {
/**
* ueber diesen Stream werden Nachrichten ausgegeben, die fuer die
* Fehlersuche nuetzlich sind. NOTE: in loggen(..) gesetzt
*/
public static PrintStream debug = System.out;
/**
* Der Start laeuft folgendermassen ab:
* <ol>
* <li>Anzeigen eines Startfensters</li>
* <li>Initialisierung des Programm-Hauptfensters</li>
* <li>Laden eines Szenarios, entweder
* <ul>
* <li>ein mit dem Programmstart uebergebene Szenariodatei oder</li>
* <li>das zuletzt geoeffnete bzw. gespeicherte Szenario</li>
* </ul>
* </li>
* <li>Ausblenden des Startfensters</li>
* </ol>
*/
public static void starten(String szenarioDatei) {
Main.debug.println("INVOKED (static) filius.Main, starten(" + szenarioDatei + ")");
SplashScreen splashScreen;
XMLDecoder xmldec;
String konfigPfad;
Object[] programmKonfig;
konfigPfad = Information.getInformation().getArbeitsbereichPfad() + "konfig.xml";
if (!(new File(konfigPfad)).exists()) {
Object[] possibleValues = { "Deutsch", "English" };
Object selectedValue = JOptionPane.showInputDialog(null, "", "Language", JOptionPane.INFORMATION_MESSAGE,
null, possibleValues, possibleValues[0]);
if (selectedValue != null && selectedValue.equals(possibleValues[0]))
Information.getInformation().setLocale(new Locale("de", "DE"));
else
Information.getInformation().setLocale(new Locale("en", "GB"));
} else {
try {
xmldec = new XMLDecoder(new BufferedInputStream(new FileInputStream(konfigPfad)));
programmKonfig = (Object[]) xmldec.readObject();
if (programmKonfig != null && programmKonfig.length == 4) {
JMainFrame.getJMainFrame().setBounds((Rectangle) programmKonfig[0]);
if (szenarioDatei == null)
szenarioDatei = (String) programmKonfig[1];
if (programmKonfig[2] != null && programmKonfig[3] != null)
Information.getInformation().setLocale(
new Locale((String) programmKonfig[2], (String) programmKonfig[3]));
}
} catch (Exception e) {
e.printStackTrace(Main.debug);
}
}
// adapt dialog buttons to current language, since Java does not do this
// automatically
UIManager.put("OptionPane.cancelButtonText", messages.getString("main_dlg_CANCEL"));
UIManager.put("OptionPane.noButtonText", messages.getString("main_dlg_NO"));
UIManager.put("OptionPane.okButtonText", messages.getString("main_dlg_OK"));
UIManager.put("OptionPane.yesButtonText", messages.getString("main_dlg_YES"));
splashScreen = new SplashScreen("gfx/allgemein/splashscreen.png", null);
splashScreen.setVisible(true);
splashScreen.setAlwaysOnTop(true);
GUIContainer.getGUIContainer().initialisieren();
long splashTime = new Long(System.currentTimeMillis());
if (szenarioDatei != null) {
try {
SzenarioVerwaltung.getInstance().laden(szenarioDatei,
GUIContainer.getGUIContainer().getGUIKnotenItemList(),
GUIContainer.getGUIContainer().getCablelist());
} catch (Exception e) {
e.printStackTrace(Main.debug);
}
} else {
SzenarioVerwaltung.getInstance().laden(GUIContainer.getGUIContainer().getGUIKnotenItemList(),
GUIContainer.getGUIContainer().getCablelist());
}
GUIContainer.getGUIContainer().setProperty(null);
GUIContainer.getGUIContainer().updateViewport();
try {
Thread.sleep(10);
} catch (Exception e) {
}
GUIContainer.getGUIContainer().updateCables();
splashTime = System.currentTimeMillis() - splashTime; // time difference
// since
// Splashscreen
// made visible
Main.debug.println("Splash Screen shown for " + splashTime + " ms");
if (splashTime < 1000) {
try {
Thread.sleep(1000 - splashTime);
} catch (Exception e) {
}
} // sleep until 1s is over
splashScreen.setAlwaysOnTop(false);
splashScreen.setVisible(false);
}
/**
* Das Beenden des Programms laeuft folgendermassen ab:
* <ol>
* <li>Wechsel in den Entwurfsmodus (und damit beenden der virtuellen
* Software und der damit verbundenen Threads</li>
* <li>Pruefung, ob eine Aenderung am Szenario vorgenommen wurde
* <ul>
* <li>wenn Szenario geaendert wurde, wird gefragt, ob die Datei noch
* gespeichert werden soll</li>
* <li>wenn das Szenario nicht gespeichert werden soll, werden die
* Aenderungen verworfen</li>
* <li>wenn die Abfrage abgebrochen wird, wird Filius nicht beendet</li>
* </ul>
* </li>
* <li>Programmkonfiguration wird gespeichert</li>
* <li>das Verzeichnis fuer temporaere Dateien wird geloescht</li>
* </ol>
*/
public static void beenden() {
Main.debug.println("INVOKED (static) filius.Main, beenden()");
Object[] programmKonfig;
XMLEncoder encoder = null;
FileOutputStream fos = null;
int entscheidung;
boolean abbruch = false;
GUIContainer.getGUIContainer().getMenu().selectMode(GUIMainMenu.MODUS_ENTWURF);
if (SzenarioVerwaltung.getInstance().istGeaendert()) {
entscheidung = JOptionPane.showConfirmDialog(JMainFrame.getJMainFrame(), messages.getString("main_msg1"),
messages.getString("main_msg2"), JOptionPane.YES_NO_OPTION);
if (entscheidung == JOptionPane.YES_OPTION) {
abbruch = false;
} else {
abbruch = true;
}
}
if (!abbruch) {
programmKonfig = new Object[4];
programmKonfig[0] = JMainFrame.getJMainFrame().getBounds();
programmKonfig[1] = SzenarioVerwaltung.getInstance().holePfad();
programmKonfig[2] = Information.getInformation().getLocale().getLanguage();
programmKonfig[3] = Information.getInformation().getLocale().getCountry();
try {
fos = new FileOutputStream(Information.getInformation().getArbeitsbereichPfad() + "konfig.xml");
encoder = new XMLEncoder(new BufferedOutputStream(fos));
encoder.writeObject(programmKonfig);
} catch (Exception e) {
e.printStackTrace(Main.debug);
} finally {
if (encoder != null)
encoder.close();
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
}
SzenarioVerwaltung.loescheVerzeichnisInhalt(Information.getInformation().getTempPfad());
System.exit(0);
}
}
private static boolean loggen(String logDateiPfad) {
if (logDateiPfad != null) {
try {
Main.debug = new PrintStream(new TeeOutputStream(new FileOutputStream(logDateiPfad), null)); // sonst:
// System.out
// für
// Screen
System.out.println("Ausgaben werden in Datei '" + logDateiPfad + "' protokolliert.");
System.setErr(Main.debug);
} catch (FileNotFoundException e) {
System.err.println("Error: logging could not be realised due to FileNotFoundException:\n\t'"
+ e.toString() + "'");
Main.debug = new PrintStream(new TeeOutputStream(null, null)); // do
// not
// log;
} catch (Exception e) {
System.err.println("Error: logging could not be realised; reason not specified:\n\t'" + e.toString()
+ "'");
Main.debug = new PrintStream(new TeeOutputStream(null, null)); // do
// not
// log;
}
} else {
Main.debug = new PrintStream(new TeeOutputStream(null, null)); // do
// not
// log
System.out
.println("Es werden keine Ausgaben zur Fehlersuche protokolliert!\nSollte dies gewuenscht sein, so starten Sie Filius bitte mit der Option '-l':\n\tFilius.exe -l\nbzw.\tjava -jar filius.jar -l");
}
return true;
}
/**
* Hier wird das Programm Filius gestartet! Wenn ein Parameter uebergeben
* wird, wird geprueft, ob es sich um eine existierende Datei handelt. Dann
* wird der Pfad an die Methode zum Starten uebergeben als eine
* Szenario-Datei, die zum Start geladen werden soll.
*/
public static void main(String[] args) {
String currWD = filius.rahmenprogramm.Information.initArbeitsbereichPfad;
File file;
boolean log = false;
boolean setWD = false; // auxiliary flag to reset working directory
String newWD = null;
String argsString = "";
boolean nativeLookAndFeel = false;
boolean verbose = false;
if (args != null && args.length >= 1) {
for (int i = 0; i < args.length; i++) {
argsString += args[i] + " ";
if (setWD) {
if (!args[i].startsWith("-")) {
newWD = args[i].trim();
currWD = newWD; // set working directory (not yet set in
// Information class, otherwise an
// Exception would emerge!)
// filius.rahmenprogramm.Information.getInformation().setArbeitsbereichPfad(newWD);
} else {
System.err
.println("Parameter '-wd' ohne Argument verwendet! Korrekte Verwendung (Beispiel): '-wd /home/user'\n");
System.err
.println("Parameter '-wd' without content! Correct usage (example): '-wd /home/user'\n");
System.exit(1);
}
setWD = false;
continue;
}
// Protokollieren in Datei?
if (args[i].startsWith("-l")) {
log = true;
continue;
}
if (args[i].startsWith("-wd")) {
setWD = true;
}
if (args[i].startsWith("-n")) {
nativeLookAndFeel = true;
}
if (args[i].startsWith("-v")) {
verbose = true;
}
}
if (currWD.isEmpty()
|| (!currWD.substring(currWD.length() - 1).equals(System.getProperty("file.separator")))) {
// check, whether working directory is
// usable... else provide dialog for correct
// paths
if (filius.rahmenprogramm.Information.getInformation(currWD + System.getProperty("file.separator")) == null)
System.exit(6);
else if (filius.rahmenprogramm.Information.getInformation(currWD) == null)
System.exit(6);
}
// if no logging specified on command line or logging to file
// fails, then set logging to null
if (log) {
log = loggen(filius.rahmenprogramm.Information.getInformation().getArbeitsbereichPfad() + "filius.log");
}
if (!log && !verbose) {
loggen(null);
}
} else {
if (filius.rahmenprogramm.Information.getInformation(currWD) == null)
System.exit(6);
loggen(null);
}
Main.debug.println("------------------------------------------------------");
Main.debug.println("\tJava Version: " + System.getProperty("java.version"));
Main.debug.println("\tJava Directory: " + System.getProperty("java.home"));
Main.debug.println("\tFILIUS Version: " + filius.rahmenprogramm.Information.getVersion());
Main.debug.println("\tParameters: '" + argsString.trim() + "'");
// +"\n\tWD Base: "+newWD
Main.debug.println("\tFILIUS Installation: "
+ filius.rahmenprogramm.Information.getInformation().getProgrammPfad());
Main.debug.println("\tFILIUS Working Directory: "
+ filius.rahmenprogramm.Information.getInformation().getArbeitsbereichPfad());
Main.debug.println("\tFILIUS Temp Directory: "
+ filius.rahmenprogramm.Information.getInformation().getTempPfad());
Main.debug.println("------------------------------------------------------\n");
if (nativeLookAndFeel) {
try {
// Set System L&F
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException e) {
// handle exception
} catch (ClassNotFoundException e) {
// handle exception
} catch (InstantiationException e) {
// handle exception
} catch (IllegalAccessException e) {
// handle exception
}
}
if (args != null && ((args.length >= 1 && !log) || (args.length >= 2 && log))) {
// Projekt-Datei als letztes Argument uebergeben?
try {
file = new File(args[args.length - 1]);
if (file.exists()) {
starten(file.getAbsolutePath());
} else
starten(null);
} catch (Exception e) {
e.printStackTrace();
starten(null);
}
} else {
starten(null);
}
}
}