package us.deathmarine.luyten; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.prefs.Preferences; import com.strobel.decompiler.DecompilerSettings; import com.strobel.decompiler.languages.Language; import com.strobel.decompiler.languages.Languages; import com.strobel.decompiler.languages.java.JavaFormattingOptions; public class ConfigSaver { private static final String FLATTEN_SWITCH_BLOCKS_ID = "flattenSwitchBlocks"; private static final String FORCE_EXPLICIT_IMPORTS_ID = "forceExplicitImports"; private static final String SHOW_SYNTHETIC_MEMBERS_ID = "showSyntheticMembers"; private static final String EXCLUDE_NESTED_TYPES_ID = "excludeNestedTypes"; private static final String FORCE_EXPLICIT_TYPE_ARGUMENTS_ID = "forceExplicitTypeArguments"; private static final String RETAIN_REDUNDANT_CASTS_ID = "retainRedundantCasts"; private static final String INCLUDE_ERROR_DIAGNOSTICS_ID = "includeErrorDiagnostics"; private static final String UNICODE_REPLACE_ENABLED_ID = "unicodeReplaceEnabled"; private static final String LANGUAGE_NAME_ID = "languageName"; private static final String MAIN_WINDOW_ID_PREFIX = "main"; private static final String FIND_WINDOW_ID_PREFIX = "find"; private static final String WINDOW_IS_FULL_SCREEN_ID = "WindowIsFullScreen"; private static final String WINDOW_WIDTH_ID = "WindowWidth"; private static final String WINDOW_HEIGHT_ID = "WindowHeight"; private static final String WINDOW_X_ID = "WindowX"; private static final String WINDOW_Y_ID = "WindowY"; private DecompilerSettings decompilerSettings; private WindowPosition mainWindowPosition; private WindowPosition findWindowPosition; private LuytenPreferences luytenPreferences; private static ConfigSaver theLoadedInstance; /** * Do not instantiate, get the loaded instance */ private ConfigSaver() { } public static ConfigSaver getLoadedInstance() { if (theLoadedInstance == null) { synchronized (ConfigSaver.class) { if (theLoadedInstance == null) { theLoadedInstance = new ConfigSaver(); theLoadedInstance.loadConfig(); } } } return theLoadedInstance; } /** * Do not load, get the loaded instance */ private void loadConfig() { decompilerSettings = new DecompilerSettings(); if (decompilerSettings.getJavaFormattingOptions() == null) { decompilerSettings.setJavaFormattingOptions(JavaFormattingOptions.createDefault()); } luytenPreferences = new LuytenPreferences(); mainWindowPosition = new WindowPosition(); findWindowPosition = new WindowPosition(); try { Preferences prefs = Preferences.userNodeForPackage(ConfigSaver.class); if (!prefs.get(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()) .equals(decompilerSettings.getLanguage().getName())) prefs.put(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()); decompilerSettings.setFlattenSwitchBlocks( prefs.getBoolean(FLATTEN_SWITCH_BLOCKS_ID, decompilerSettings.getFlattenSwitchBlocks())); decompilerSettings.setForceExplicitImports( prefs.getBoolean(FORCE_EXPLICIT_IMPORTS_ID, decompilerSettings.getForceExplicitImports())); decompilerSettings.setShowSyntheticMembers( prefs.getBoolean(SHOW_SYNTHETIC_MEMBERS_ID, decompilerSettings.getShowSyntheticMembers())); decompilerSettings.setExcludeNestedTypes( prefs.getBoolean(EXCLUDE_NESTED_TYPES_ID, decompilerSettings.getExcludeNestedTypes())); decompilerSettings.setForceExplicitTypeArguments(prefs.getBoolean(FORCE_EXPLICIT_TYPE_ARGUMENTS_ID, decompilerSettings.getForceExplicitTypeArguments())); decompilerSettings.setRetainRedundantCasts( prefs.getBoolean(RETAIN_REDUNDANT_CASTS_ID, decompilerSettings.getRetainRedundantCasts())); decompilerSettings.setIncludeErrorDiagnostics( prefs.getBoolean(INCLUDE_ERROR_DIAGNOSTICS_ID, decompilerSettings.getIncludeErrorDiagnostics())); decompilerSettings.setLanguage( findLanguageByName(prefs.get(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()))); decompilerSettings.setUnicodeOutputEnabled(prefs.getBoolean(UNICODE_REPLACE_ENABLED_ID, false)); mainWindowPosition = loadWindowPosition(prefs, MAIN_WINDOW_ID_PREFIX); findWindowPosition = loadWindowPosition(prefs, FIND_WINDOW_ID_PREFIX); luytenPreferences = loadLuytenPreferences(prefs); } catch (Exception e) { Luyten.showExceptionDialog("Exception!", e); } } private WindowPosition loadWindowPosition(Preferences prefs, String windowIdPrefix) { WindowPosition windowPosition = new WindowPosition(); windowPosition.setFullScreen(prefs.getBoolean(windowIdPrefix + WINDOW_IS_FULL_SCREEN_ID, false)); windowPosition.setWindowWidth(prefs.getInt(windowIdPrefix + WINDOW_WIDTH_ID, 0)); windowPosition.setWindowHeight(prefs.getInt(windowIdPrefix + WINDOW_HEIGHT_ID, 0)); windowPosition.setWindowX(prefs.getInt(windowIdPrefix + WINDOW_X_ID, 0)); windowPosition.setWindowY(prefs.getInt(windowIdPrefix + WINDOW_Y_ID, 0)); return windowPosition; } // load preferences by their java variable names private LuytenPreferences loadLuytenPreferences(Preferences prefs) throws Exception { LuytenPreferences newLuytenPrefs = new LuytenPreferences(); for (Field field : LuytenPreferences.class.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; field.setAccessible(true); String prefId = field.getName(); Object defaultVal = field.get(newLuytenPrefs); if (field.getType() == String.class) { String defaultStr = (String) (defaultVal == null ? "" : defaultVal); field.set(newLuytenPrefs, prefs.get(prefId, defaultStr)); } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { Boolean defaultBool = (Boolean) (defaultVal == null ? new Boolean(false) : defaultVal); field.setBoolean(newLuytenPrefs, prefs.getBoolean(prefId, defaultBool)); } else if (field.getType() == Integer.class || field.getType() == int.class) { Integer defaultInt = (Integer) (defaultVal == null ? new Integer(0) : defaultVal); field.setInt(newLuytenPrefs, prefs.getInt(prefId, defaultInt)); } } return newLuytenPrefs; } public void saveConfig() { // Registry path on Windows Xp: // HKEY_CURRENT_USER/Software/JavaSoft/Prefs/us/deathmarine/luyten try { Preferences prefs = Preferences.userNodeForPackage(ConfigSaver.class); prefs.putBoolean(FLATTEN_SWITCH_BLOCKS_ID, decompilerSettings.getFlattenSwitchBlocks()); prefs.putBoolean(FORCE_EXPLICIT_IMPORTS_ID, decompilerSettings.getForceExplicitImports()); prefs.putBoolean(SHOW_SYNTHETIC_MEMBERS_ID, decompilerSettings.getShowSyntheticMembers()); prefs.putBoolean(EXCLUDE_NESTED_TYPES_ID, decompilerSettings.getExcludeNestedTypes()); prefs.putBoolean(FORCE_EXPLICIT_TYPE_ARGUMENTS_ID, decompilerSettings.getForceExplicitTypeArguments()); prefs.putBoolean(RETAIN_REDUNDANT_CASTS_ID, decompilerSettings.getRetainRedundantCasts()); prefs.putBoolean(INCLUDE_ERROR_DIAGNOSTICS_ID, decompilerSettings.getIncludeErrorDiagnostics()); prefs.putBoolean(UNICODE_REPLACE_ENABLED_ID, decompilerSettings.isUnicodeOutputEnabled()); prefs.put(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()); saveWindowPosition(prefs, MAIN_WINDOW_ID_PREFIX, mainWindowPosition); saveWindowPosition(prefs, FIND_WINDOW_ID_PREFIX, findWindowPosition); saveLuytenPreferences(prefs); } catch (Exception e) { Luyten.showExceptionDialog("Exception!", e); } } private void saveWindowPosition(Preferences prefs, String windowIdPrefix, WindowPosition windowPosition) { prefs.putBoolean(windowIdPrefix + WINDOW_IS_FULL_SCREEN_ID, windowPosition.isFullScreen()); prefs.putInt(windowIdPrefix + WINDOW_WIDTH_ID, windowPosition.getWindowWidth()); prefs.putInt(windowIdPrefix + WINDOW_HEIGHT_ID, windowPosition.getWindowHeight()); prefs.putInt(windowIdPrefix + WINDOW_X_ID, windowPosition.getWindowX()); prefs.putInt(windowIdPrefix + WINDOW_Y_ID, windowPosition.getWindowY()); } // save preferences by their java variable names private void saveLuytenPreferences(Preferences prefs) throws Exception { for (Field field : LuytenPreferences.class.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; field.setAccessible(true); String prefId = field.getName(); Object value = field.get(luytenPreferences); if (field.getType() == String.class) { prefs.put(prefId, (String) (value == null ? "" : value)); } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { prefs.putBoolean(prefId, (Boolean) (value == null ? new Boolean(false) : value)); } else if (field.getType() == Integer.class || field.getType() == int.class) { prefs.putInt(prefId, (Integer) (value == null ? new Integer(0) : value)); } } } private Language findLanguageByName(String languageName) { if (languageName != null) { if (languageName.equals(Languages.java().getName())) { return Languages.java(); } else if (languageName.equals(Languages.bytecode().getName())) { return Languages.bytecode(); } else if (languageName.equals(Languages.bytecodeAst().getName())) { return Languages.bytecodeAst(); } for (Language language : Languages.debug()) { if (languageName.equals(language.getName())) { return language; } } } return Languages.java(); } public DecompilerSettings getDecompilerSettings() { return decompilerSettings; } public WindowPosition getMainWindowPosition() { return mainWindowPosition; } public WindowPosition getFindWindowPosition() { return findWindowPosition; } public LuytenPreferences getLuytenPreferences() { return luytenPreferences; } }