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.l10n.DebugTranslator;
8 import net.sf.openrocket.l10n.L10N;
9 import net.sf.openrocket.l10n.ResourceBundleTranslator;
10 import net.sf.openrocket.l10n.Translator;
11 import net.sf.openrocket.logging.DelegatorLogger;
12 import net.sf.openrocket.logging.LogHelper;
13 import net.sf.openrocket.logging.LogLevel;
14 import net.sf.openrocket.logging.LogLevelBufferLogger;
15 import net.sf.openrocket.logging.PrintStreamLogger;
19 * The first class in the OpenRocket startup sequence. This class is responsible
20 * for setting up the Application class with the statically used subsystems
21 * (logging and translation) and then delegating to Startup2 class.
23 * This class must be very cautious about what classes it calls. This is because
24 * the loggers/translators for classes are initialized as static final members during
25 * class initialization. For example, this class MUST NOT use the Prefs class, because
26 * using it will cause LineStyle to be initialized, which then receives an invalid
27 * (not-yet-initialized) translator.
29 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
31 public class Startup {
35 private static final String LOG_STDERR_PROPERTY = "openrocket.log.stderr";
36 private static final String LOG_STDOUT_PROPERTY = "openrocket.log.stdout";
38 private static final int LOG_BUFFER_LENGTH = 50;
42 * OpenRocket startup main method.
44 public static void main(final String[] args) throws Exception {
46 // Check for "openrocket.debug" property before anything else
49 // Initialize logging first so we can use it
52 // Setup the translations
55 // Continue startup in Startup2 class (where Application is already set up)
56 Startup2.runMain(args);
63 * Set proper system properties if openrocket.debug is defined.
65 private static void checkDebugStatus() {
66 if (System.getProperty("openrocket.debug") != null) {
67 setPropertyIfNotSet("openrocket.log.stdout", "VBOSE");
68 setPropertyIfNotSet("openrocket.log.tracelevel", "VBOSE");
69 setPropertyIfNotSet("openrocket.debug.menu", "true");
70 setPropertyIfNotSet("openrocket.debug.mutexlocation", "true");
71 setPropertyIfNotSet("openrocket.debug.motordigest", "true");
75 private static void setPropertyIfNotSet(String key, String value) {
76 if (System.getProperty(key) == null) {
77 System.setProperty(key, value);
84 * Initializes the loggins system.
86 private static void initializeLogging() {
87 DelegatorLogger delegator = new DelegatorLogger();
90 LogLevelBufferLogger buffer = new LogLevelBufferLogger(LOG_BUFFER_LENGTH);
91 delegator.addLogger(buffer);
93 // Check whether to log to stdout/stderr
94 PrintStreamLogger printer = new PrintStreamLogger();
95 boolean logout = setLogOutput(printer, System.out, System.getProperty(LOG_STDOUT_PROPERTY), null);
96 boolean logerr = setLogOutput(printer, System.err, System.getProperty(LOG_STDERR_PROPERTY), LogLevel.ERROR);
97 if (logout || logerr) {
98 delegator.addLogger(printer);
102 Application.setLogger(delegator);
103 Application.setLogBuffer(buffer);
105 // Initialize the log for this class
106 log = Application.getLogger();
107 log.info("Logging subsystem initialized");
108 String str = "Console logging output:";
109 for (LogLevel l : LogLevel.values()) {
110 PrintStream ps = printer.getOutput(l);
111 str += " " + l.name() + ":";
112 if (ps == System.err) {
114 } else if (ps == System.out) {
120 str += " (" + LOG_STDOUT_PROPERTY + "=" + System.getProperty(LOG_STDOUT_PROPERTY) +
121 " " + LOG_STDERR_PROPERTY + "=" + System.getProperty(LOG_STDERR_PROPERTY) + ")";
125 private static boolean setLogOutput(PrintStreamLogger logger, PrintStream stream, String level, LogLevel defaultLevel) {
126 LogLevel minLevel = LogLevel.fromString(level, defaultLevel);
127 if (minLevel == null) {
131 for (LogLevel l : LogLevel.values()) {
132 if (l.atLeast(minLevel)) {
133 logger.setOutput(l, stream);
143 * Initializes the localization system.
145 private static void initializeL10n() {
147 // Check for locale propery
148 String langcode = System.getProperty("openrocket.locale");
150 if (langcode != null) {
152 Locale l = L10N.toLocale(langcode);
153 log.info("Setting custom locale " + l);
154 Locale.setDefault(l);
158 // Check user-configured locale
159 Locale l = getUserLocale();
161 log.info("Setting user-selected locale " + l);
162 Locale.setDefault(l);
164 log.info("Using default locale " + Locale.getDefault());
169 // Setup the translator
171 t = new ResourceBundleTranslator("l10n.messages");
172 if (Locale.getDefault().getLanguage().equals("xx")) {
173 t = new DebugTranslator(t);
176 log.info("Set up translation for locale " + Locale.getDefault() +
177 ", debug.currentFile=" + t.get("debug.currentFile"));
179 Application.setBaseTranslator(t);
185 private static Locale getUserLocale() {
187 * This method MUST NOT use the Prefs class, since is causes a multitude
188 * of classes to be initialized. Therefore this duplicates the functionality
189 * of the Prefs class locally.
192 if (System.getProperty("openrocket.debug.prefs") != null) {
196 return L10N.toLocale(Preferences.userRoot().node("OpenRocket").get("locale", null));