package org.rr.jeborker.app.preferences; import static org.rr.commons.utils.BooleanUtils.not; import static org.rr.commons.utils.StringUtil.EMPTY; import java.awt.Dimension; import java.awt.Point; import java.awt.Toolkit; import java.awt.Window; import java.io.File; import java.util.Arrays; import java.util.List; import org.apache.commons.lang.math.NumberUtils; import org.rr.commons.collection.ListenerList; import org.rr.commons.mufs.IResourceHandler; import org.rr.commons.utils.BooleanUtils; import org.rr.commons.utils.CommonUtils; import org.rr.commons.utils.ListUtils; import org.rr.commons.utils.StringUtil; import org.rr.jeborker.app.BasePathList; import org.rr.jeborker.app.preferences.PreferenceStoreFactory.PREFERENCE_KEYS; import org.rr.jeborker.gui.MainMenuBarController; public abstract class APreferenceStore { private final ListenerList<JeboorkerPreferenceListener> preferenceChangeListener = new ListenerList<>(); /** * Fetch a previously stored string value with it's key from the DB. * @param key The key to access the value. * @return The desired value or <code>null</code> if the value wasn't stored. */ protected abstract String getEntryFromImpl(String key); protected abstract void addEntryToImpl(String key, String value); protected abstract void deleteEntryFromImpl(String key); public void addBasePath(String path) { throw new IllegalArgumentException("Base path action are not supported."); } /** * Removes one entry from the base path list. * @param path The path entry to be removed. */ public void removeBasePath(String path) { throw new IllegalArgumentException("Base path action are not supported."); } /** * Get all base path entries from the preference store. * @return The stored base path entries. never returns <code>null</code>. */ public BasePathList getBasePath() { throw new IllegalArgumentException("Base path action are not supported."); } /** * Tests if the given path is visible. */ public boolean isBasePathVisible(String path) { return MainMenuBarController.getController().isShowHideBasePathStatusShow(path); } /** * Get the base path for the given {@link IResourceHandler}. * @return the desired {@link IResourceHandler} or <code>null</code> if no base path exists * for the given {@link IResourceHandler}. */ public String getBasePathFor(IResourceHandler resource) { if(resource != null) { String resourceString = resource.toString(); List<String> basePaths = getBasePath(); for(String basePath : basePaths) { if(resourceString.startsWith(basePath)) { return basePath; } } } return null; } /** * Just stores the given string value under the given key. * @param key The key to access the given value. * @param value The value which can be accessed with the given key. */ public void addGenericEntryAsString(String key, String value) { addEntryToImpl(key, value); } public void addEntryAsString(PREFERENCE_KEYS key, String value) { addGenericEntryAsString(key.getKey(), value); } /** * Fetch a previously stored string value with it's key. * @param key The key to access the value. * @return The desired value or <code>null</code> if the value wasn't stored. */ public String getGenericEntryAsString(String key, String defaultValue) { if(key != null) { String result; if((result = getEntryFromImpl(key)) != null) { return result; } } return defaultValue; } /** * Fetch a previously stored string value with it's key. * @param key The key to access the value. * @return The desired value or <code>null</code> if the value wasn't stored. */ public String getGenericEntryAsString(String key) { return getGenericEntryAsString(key, EMPTY); } /** * Just stores the given string value under the given key. * @param key The key to access the given value. * @param value The value which can be accessed with the given key. */ public void addGenericEntryAsNumber(String key, Number value) { addEntryToImpl(key, String.valueOf(value.doubleValue())); } /** * Fetch a previously stored string value with it's key. * @param key The key to access the value. * @return The desired value or <code>null</code> if the value wasn't stored. */ public Number getGenericEntryAsNumber(String key) { String result = getEntryFromImpl(key); if(result != null && result.length() > 0) { return Double.valueOf(result); } else { return null; } } public Number getGenericEntryAsNumber(String key, Number defaultValue) { Number result = getGenericEntryAsNumber(key); return result != null ? result : defaultValue; } public void addEntryAsBoolean(PREFERENCE_KEYS key, Boolean b) { addGenericEntryBoolean(key.getKey(), b); } private void addGenericEntryBoolean(String key, Boolean b) { addGenericEntryAsNumber(key, b.booleanValue() ? Integer.valueOf(1) : Integer.valueOf(0)); } /** * Get the given {@link PREFERENCE_KEYS} as string value. * @return The desired value. Never returns <code>null</code>. */ public String getEntryAsString(PREFERENCE_KEYS key) { final String preferenceEntry = getGenericEntryAsString(key.getKey(), null); if(preferenceEntry != null) { return preferenceEntry; } else { return key.getDefaultValue(); } } /** * Get the given {@link PREFERENCE_KEYS} as boolean value. * @return The desired value. Never returns <code>null</code>. */ public Boolean getEntryAsBoolean(PREFERENCE_KEYS key) { String defaultValueString = key.getDefaultValue(); Boolean defaultValue = BooleanUtils.toBoolean(defaultValueString); return getEntryAsBoolean(key.getKey(), defaultValue); } private Boolean getEntryAsBoolean(final String key, Boolean defaultValue) { Number entryAsNumber = getGenericEntryAsNumber(key); if(entryAsNumber != null && entryAsNumber.intValue() == 1) { return Boolean.TRUE; } else if(entryAsNumber != null && entryAsNumber.intValue() == 0) { return Boolean.FALSE; } return defaultValue; } /** * Get the point of a window where a window should be shown. * @param xKey The key for the x value * @param yKey The key for the y value * @return The point where the window should be shown or <code>null</code> if * there is no previously stored location point or if the window is not located at the screen. */ public Point getGenericEntryAsScreenLocation(String xKey, String yKey) { String widthValue = getGenericEntryAsString(xKey); String heightValue = getGenericEntryAsString(yKey); Point location = new Point(); if(widthValue!=null && widthValue.length()>0) { location.x = CommonUtils.toNumber(widthValue).intValue(); } else { return null; } if(heightValue!=null && heightValue.length()>0) { location.y = CommonUtils.toNumber(heightValue).intValue(); } else { return null; } if(!intersectsScreen(location)) { return null; } return location; } private boolean intersectsScreen(Point location) { Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); if(location.x +150 > screen.width || location.y +150 > screen.height) { //don't restore and use the default values. return false; } return true; } /** * Gets the default configuration directory. The path have a trailing '/'. The config * file directory is something like <code>user.home/.jeboorker/</code>. * * @return The config file directory. */ public static String getConfigDirectory() { String configDir = System.getProperties().getProperty("user.home"); String suffix = System.getProperties().getProperty("application.suffix"); configDir += File.separator + ".jeboorker" + (StringUtil.isNotEmpty(suffix) ? "." + suffix : EMPTY) + File.separator; makeConfigDirIfNotExists(configDir); return configDir; } private static void makeConfigDirIfNotExists(String configDir) { File configDirFile = new File(configDir); if(not(configDirFile.exists())) { configDirFile.mkdirs(); } } /** * Stores location and size of the given windows under the given key. * @param key The unique key where the window location adn size are stored. * @param window The window which location and size should be stored. */ public void storeWindowLocationAndSize(String key, Window window) { Point location = window.getLocation(); Dimension size = window.getSize(); List<Integer> values = Arrays.asList(new Integer[] { Integer.valueOf(location.x), Integer.valueOf(location.y), Integer.valueOf(size.width), Integer.valueOf(size.height) }); addGenericEntryAsString(key, ListUtils.join(values, ";")); } /** * Restores the size and location previously stored with the {@link #storeWindowLocationAndSize(String, Window)} method. * @param key The key where the location and size was previously stored * @param window The window where the location and size should be applied to. */ public void restoreWindowLocationAndSize(String key, Window window) { String sizeAndLocation = getGenericEntryAsString(key); if(StringUtil.isNotEmpty(sizeAndLocation)) { List<String> s = ListUtils.split(sizeAndLocation, ";"); window.setLocation(new Point(NumberUtils.toInt(s.get(0)), NumberUtils.toInt(s.get(1)))); window.setSize(NumberUtils.toInt(s.get(2)), NumberUtils.toInt(s.get(3))); } } /** * Adds a preference change listener that is always invoked if a preference is changed. */ public void addPreferenceChangeListener(final JeboorkerPreferenceListener listener) { preferenceChangeListener.addListener(listener); } /** * Removes the given {@link JeboorkerPreferenceListener} from the listener list. */ public void removePreferenceChangeListener(final JeboorkerPreferenceListener listener) { preferenceChangeListener.removeListener(listener); } /** * Tells if the auto scrolling the the trees is enabled. */ public boolean isTreeAutoScrollingEnabled() { return getEntryAsBoolean(PREFERENCE_KEYS.TREE_AUTO_SCROLLING_ENABLED); } /** * Sets the value for enable / disable the auto scrolling the the trees */ public void setTreeAutoScrollingEnabled(final boolean value) { addEntryAsBoolean(PREFERENCE_KEYS.TREE_AUTO_SCROLLING_ENABLED, Boolean.valueOf(value)); //listener for enable the auto scroll function in the tree component. for(JeboorkerPreferenceListener listener : preferenceChangeListener) { listener.treeAutoScrollingChanged(value); } } }