1 package net.sf.openrocket.startup;
3 import java.io.PrintStream;
4 import java.util.Locale;
5 import java.util.prefs.Preferences;
7 import net.sf.openrocket.database.ComponentPresetDatabase;
8 import net.sf.openrocket.gui.util.SwingPreferences;
9 import net.sf.openrocket.l10n.DebugTranslator;
10 import net.sf.openrocket.l10n.L10N;
11 import net.sf.openrocket.l10n.ResourceBundleTranslator;
12 import net.sf.openrocket.l10n.Translator;
13 import net.sf.openrocket.logging.DelegatorLogger;
14 import net.sf.openrocket.logging.LogHelper;
15 import net.sf.openrocket.logging.LogLevel;
16 import net.sf.openrocket.logging.LogLevelBufferLogger;
17 import net.sf.openrocket.logging.PrintStreamLogger;
21 * The first class in the OpenRocket startup sequence. This class is responsible
22 * for setting up the Application class with the statically used subsystems
23 * (logging and translation) and then delegating to Startup2 class.
25 * This class must be very cautious about what classes it calls. This is because
26 * the loggers/translators for classes are initialized as static final members during
27 * class initialization. For example, this class MUST NOT use the Prefs class, because
28 * using it will cause LineStyle to be initialized, which then receives an invalid
29 * (not-yet-initialized) translator.
31 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
33 public class Startup {
37 private static final String LOG_STDERR_PROPERTY = "openrocket.log.stderr";
38 private static final String LOG_STDOUT_PROPERTY = "openrocket.log.stdout";
40 private static final int LOG_BUFFER_LENGTH = 50;
44 * OpenRocket startup main method.
46 public static void main(final String[] args) throws Exception {
48 // Check for "openrocket.debug" property before anything else
51 // Initialize logging first so we can use it
54 Application.setPreferences( new SwingPreferences() );
56 // Setup the translations
59 // Must be done after localization is initialized
60 ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase();
61 componentPresetDao.load("datafiles", ".*csv");
62 Application.setComponentPresetDao( componentPresetDao );
64 // Continue startup in Startup2 class (where Application is already set up)
65 Startup2.runMain(args);
72 * Set proper system properties if openrocket.debug is defined.
74 private static void checkDebugStatus() {
75 if (System.getProperty("openrocket.debug") != null) {
76 setPropertyIfNotSet("openrocket.log.stdout", "VBOSE");
77 setPropertyIfNotSet("openrocket.log.tracelevel", "VBOSE");
78 setPropertyIfNotSet("openrocket.debug.menu", "true");
79 setPropertyIfNotSet("openrocket.debug.mutexlocation", "true");
80 setPropertyIfNotSet("openrocket.debug.motordigest", "true");
84 private static void setPropertyIfNotSet(String key, String value) {
85 if (System.getProperty(key) == null) {
86 System.setProperty(key, value);
93 * Initializes the loggins system.
95 private static void initializeLogging() {
96 DelegatorLogger delegator = new DelegatorLogger();
99 LogLevelBufferLogger buffer = new LogLevelBufferLogger(LOG_BUFFER_LENGTH);
100 delegator.addLogger(buffer);
102 // Check whether to log to stdout/stderr
103 PrintStreamLogger printer = new PrintStreamLogger();
104 boolean logout = setLogOutput(printer, System.out, System.getProperty(LOG_STDOUT_PROPERTY), null);
105 boolean logerr = setLogOutput(printer, System.err, System.getProperty(LOG_STDERR_PROPERTY), LogLevel.ERROR);
106 if (logout || logerr) {
107 delegator.addLogger(printer);
111 Application.setLogger(delegator);
112 Application.setLogBuffer(buffer);
114 // Initialize the log for this class
115 log = Application.getLogger();
116 log.info("Logging subsystem initialized");
117 String str = "Console logging output:";
118 for (LogLevel l : LogLevel.values()) {
119 PrintStream ps = printer.getOutput(l);
120 str += " " + l.name() + ":";
121 if (ps == System.err) {
123 } else if (ps == System.out) {
129 str += " (" + LOG_STDOUT_PROPERTY + "=" + System.getProperty(LOG_STDOUT_PROPERTY) +
130 " " + LOG_STDERR_PROPERTY + "=" + System.getProperty(LOG_STDERR_PROPERTY) + ")";
134 private static boolean setLogOutput(PrintStreamLogger logger, PrintStream stream, String level, LogLevel defaultLevel) {
135 LogLevel minLevel = LogLevel.fromString(level, defaultLevel);
136 if (minLevel == null) {
140 for (LogLevel l : LogLevel.values()) {
141 if (l.atLeast(minLevel)) {
142 logger.setOutput(l, stream);
152 * Initializes the localization system.
154 private static void initializeL10n() {
156 // Check for locale propery
157 String langcode = System.getProperty("openrocket.locale");
159 if (langcode != null) {
161 Locale l = L10N.toLocale(langcode);
162 log.info("Setting custom locale " + l);
163 Locale.setDefault(l);
167 // Check user-configured locale
168 Locale l = getUserLocale();
170 log.info("Setting user-selected locale " + l);
171 Locale.setDefault(l);
173 log.info("Using default locale " + Locale.getDefault());
178 // Setup the translator
180 t = new ResourceBundleTranslator("l10n.messages");
181 if (Locale.getDefault().getLanguage().equals("xx")) {
182 t = new DebugTranslator(t);
185 log.info("Set up translation for locale " + Locale.getDefault() +
186 ", debug.currentFile=" + t.get("debug.currentFile"));
188 Application.setBaseTranslator(t);
194 private static Locale getUserLocale() {
196 * This method MUST NOT use the Prefs class, since is causes a multitude
197 * of classes to be initialized. Therefore this duplicates the functionality
198 * of the Prefs class locally.
201 if (System.getProperty("openrocket.debug.prefs") != null) {
205 return L10N.toLocale(Preferences.userRoot().node("OpenRocket").get("locale", null));