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 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.getFormattingOptions() == null) {
decompilerSettings.setFormattingOptions(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())));
mainWindowPosition = loadWindowPosition(prefs, MAIN_WINDOW_ID_PREFIX);
findWindowPosition = loadWindowPosition(prefs, FIND_WINDOW_ID_PREFIX);
luytenPreferences = loadLuytenPreferences(prefs);
} catch (Exception e) {
e.printStackTrace();
}
}
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\com\modcrafting\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.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) {
e.printStackTrace();
}
}
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;
}
}