/* * PrefManager.java * * Thread Dump Analysis Tool, parses Thread Dump input and displays it as tree * * This file is part of TDA - Thread Dump Analysis Tool. * * TDA is free software; you can redistribute it and/or modify * it under the terms of the Lesser GNU General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * TDA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Lesser GNU General Public License for more details. * * You should have received a copy of the Lesser GNU General Public License * along with TDA; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * $Id: PrefManager.java,v 1.28 2010-04-01 09:20:28 irockel Exp $ */ package com.pironet.tda.utils; import java.awt.Dimension; import java.awt.Point; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; import javax.swing.DefaultListModel; import javax.swing.ListModel; import com.pironet.tda.CustomCategory; import com.pironet.tda.filter.FilterChecker; import com.pironet.tda.filter.ThreadFilter; ; /** * Singleton class for accessing system preferences. * Window sizes, and positions are stored here and also the last accessed path * is stored here. * * @author irockel */ public class PrefManager { public static final String PARAM_DELIM = "\u00A7\u00A7\u00A7\u00A7"; public static final String FILTER_SEP = "\u00ac\u00ac\u00ac\u00ac"; private final static PrefManager prefManager = new PrefManager(); private final Preferences toolPrefs; /** Creates a new instance of PrefManager */ private PrefManager() { toolPrefs = Preferences.userNodeForPackage(this.getClass()); } public static PrefManager get() { return(prefManager); } public long getMaxLogfileSize() { return(toolPrefs.getInt("maxlogfilesize", 1024)); } public int getWindowState() { return(toolPrefs.getInt("windowState", -1)); } public void setWindowState(int windowState) { toolPrefs.putInt("windowState", windowState); } public File getSelectedPath() { return(new File(toolPrefs.get("selectedPath", ""))); } public void setSelectedPath(File directory) { toolPrefs.put("selectedPath", directory.getAbsolutePath()); } public Dimension getPreferredSize() { return(new Dimension(toolPrefs.getInt("windowWidth", 800), toolPrefs.getInt("windowHeight", 600))); } public void setPreferredSize(Dimension size) { toolPrefs.putInt("windowHeight", size.height); toolPrefs.putInt("windowWidth", size.width); } public Dimension getPreferredSizeFileChooser() { return(new Dimension(toolPrefs.getInt("fileChooser.windowWidth", 0), toolPrefs.getInt("fileChooser.windowHeight", 0))); } public void setPreferredSizeFileChooser(Dimension size) { toolPrefs.putInt("fileChooser.windowHeight", size.height); toolPrefs.putInt("fileChooser.windowWidth", size.width); } public void setMaxLogfileSize(int size) { toolPrefs.putInt("maxlogfilesize", size); } public Point getWindowPos() { Point point = new Point(toolPrefs.getInt("windowPosX", 0), toolPrefs.getInt("windowPosY", 0)); return(point); } public void setWindowPos(int x, int y) { toolPrefs.putInt("windowPosX", x); toolPrefs.putInt("windowPosY", y); } public int getMaxRows() { return(toolPrefs.getInt("maxRowsForChecking", 10)); } public void setMaxRows(int rows) { toolPrefs.putInt("maxRowsForChecking", rows); } //FIXME need to put a default dividerPos value public int getTopDividerPos() { return(toolPrefs.getInt("top.dividerPos", 0)); } public void setTopDividerPos(int pos) { toolPrefs.putInt("top.dividerPos", pos); } public int getDividerPos() { return(toolPrefs.getInt("dividerPos", 0)); } public void setDividerPos(int pos) { toolPrefs.putInt("dividerPos", pos); } public int getStreamResetBuffer() { return(toolPrefs.getInt("streamResetBuffer", 16384)); } public void setStreamResetBuffer(int buffer) { toolPrefs.putInt("streamResetBuffer", buffer); } public boolean getForceLoggcLoading() { return(toolPrefs.getBoolean("forceLoggcLoading", false)); } public void setForceLoggcLoading(boolean force) { toolPrefs.putBoolean("forceLoggcLoading", force); } public boolean getJDK16DefaultParsing() { return(toolPrefs.getBoolean("jdk16DefaultParsing", true)); } public void setJDK16DefaultParsing(boolean defaultParsing) { toolPrefs.putBoolean("jdk16DefaultParsing", defaultParsing); } public boolean getShowToolbar() { return(toolPrefs.getBoolean("showToolbar", true)); } public void setShowToolbar(boolean state) { toolPrefs.putBoolean("showToolbar", state); } public String getDateParsingRegex() { return(toolPrefs.get("dateParsingRegex", "(\\d\\d\\d\\d\\-\\d\\d\\-\\d\\d\\s\\d\\d:\\d\\d:\\d\\d).*")); } public void setDateParsingRegex(String dateRegex) { if(dateRegex == null) { // don't save null values. dateRegex = ""; } toolPrefs.put("dateParsingRegex", dateRegex); } public String[] getDateParsingRegexs() { String elems = toolPrefs.get("dateParsingRegexs", "(\\d\\d\\d\\d\\-\\d\\d\\-\\d\\d\\s\\d\\d:\\d\\d:\\d\\d).*"); if(elems.equals("")) { elems = getDateParsingRegex(); } return(elems.split(PARAM_DELIM)); } public void setDateParsingRegexs(ListModel regexs) { toolPrefs.put("dateParsingRegexs", regexsToString(regexs)); } private String regexsToString(ListModel regexs) { StringBuffer elems = new StringBuffer(); for(int i = 0; i < regexs.getSize(); i++) { elems.append(regexs.getElementAt(i)); if(i+1 < regexs.getSize()) { elems.append(PARAM_DELIM); } } return(elems.toString()); } public void addToRecentFiles(String file) { String[] currentFiles = getRecentFiles(); // only add files already in it if(!hasInRecentFiles(file, currentFiles)) { int start = currentFiles.length == 10 ? 1 : 0; StringBuffer recentFiles = new StringBuffer(); for(int i = start; i < currentFiles.length; i++) { recentFiles.append(currentFiles[i]); recentFiles.append(PARAM_DELIM); } // append new files recentFiles.append(file); toolPrefs.put("recentFiles", recentFiles.toString()); } } public String[] getRecentFiles() { return(toolPrefs.get("recentFiles", "").split(PARAM_DELIM)); } public void addToRecentSessions(String file) { String[] currentFiles = getRecentSessions(); // only add files already in it if(!hasInRecentFiles(file, currentFiles)) { int start = currentFiles.length == 10 ? 1 : 0; StringBuffer recentSessions = new StringBuffer(); for(int i = start; i < currentFiles.length; i++) { recentSessions.append(currentFiles[i]); recentSessions.append(PARAM_DELIM); } // append new files recentSessions.append(file); toolPrefs.put("recentSessions", recentSessions.toString()); } } public String[] getRecentSessions() { return(toolPrefs.get("recentSessions", "").split(PARAM_DELIM)); } public void setUseGTKLF(boolean value) { toolPrefs.putBoolean("useGTKLF", value); } public boolean isUseGTKLF() { return(toolPrefs.getBoolean("useGTKLF", System.getProperty("java.version").startsWith("1.6") && System.getProperty("os.name").startsWith("Linux") ? true : false)); } public void setMillisTimeStamp(boolean value) { toolPrefs.putBoolean("millisTimeStamp", value); } public boolean getMillisTimeStamp() { return(toolPrefs.getBoolean("millisTimeStamp", false)); } public void setShowHotspotClasses(boolean value) { toolPrefs.putBoolean("showHotspotClasses", value); } public boolean getShowHotspotClasses() { return(toolPrefs.getBoolean("showHotspotClasses", false)); } /** * temporary storage for filters to not to have them be parsed again */ private final java.util.List cachedFilters = new ArrayList(); public ListModel getFilters() { DefaultListModel filters = null; if(this.cachedFilters.isEmpty()) { String filterString = toolPrefs.get("filters", ""); if(filterString.length() > 0) { filters = new DefaultListModel(); String[] sFilters = filterString.split(PARAM_DELIM); filters.ensureCapacity(sFilters.length); try { for(int i = 0; i < sFilters.length; i++) { String[] filterData = sFilters[i].split(FILTER_SEP); ThreadFilter newFilter = new ThreadFilter(filterData[0], filterData[1], Integer.parseInt(filterData[2]), filterData[3].equals("true"), filterData[4].equals("true"), filterData[5].equals("true")); filters.add(i, newFilter); } } catch (ArrayIndexOutOfBoundsException aioob) { // fall back to default filters filters = getPredefinedFilters(); } // initialize cached filters setFilterCache(filters); } else { filters = getPredefinedFilters(); } } else { // populate filters from cache filters = getCachedFilters(); } return(filters); } /** * Populates a new DefaultModelList object with the current list of filters. * * @return populated DefaultModelList object */ private DefaultListModel getCachedFilters() { DefaultListModel modelFilters = new DefaultListModel(); Iterator it = this.cachedFilters.iterator(); while (it.hasNext()) { modelFilters.addElement(it.next()); } return modelFilters; } /** * Populates the cached filters using a new list of filters. * * @param filters updated list of filters */ private void setFilterCache(DefaultListModel filters) { // remove existing filters this.cachedFilters.clear(); for (int f = 0; f < filters.size(); f++) { this.cachedFilters.add(filters.get(f)); } } /** * temporary storage for categories to not to have them be parsed again */ private final java.util.List cachedCategories = new ArrayList(); /** * get custom categories. * @return list model with custom categories. */ public ListModel getCategories() { DefaultListModel categories = null; if (this.cachedCategories.isEmpty()) { String categoryString = toolPrefs.get("categories", ""); if (categoryString.length() > 0) { categories = new DefaultListModel(); String[] sCategories = categoryString.split(PARAM_DELIM); categories.ensureCapacity(sCategories.length); try { FilterChecker fc = FilterChecker.getFilterChecker(); for (int i = 0; i < sCategories.length; i++) { String[] catData = sCategories[i].split(FILTER_SEP); CustomCategory newCat = new CustomCategory(catData[0]); for(int j = 1; j < catData.length; j++) { ThreadFilter filter = getFromFilters(catData[j].trim()); if(filter != null) { newCat.addToFilters(filter); } } categories.add(i, newCat); } } catch (ArrayIndexOutOfBoundsException aioob) { System.out.println("couldn't parse categories, " + aioob.getMessage()); aioob.printStackTrace(); // fall back to default categories categories = new DefaultListModel(); } // initialize cache setCategoryCache(categories); } else { categories = new DefaultListModel(); } } else { // populate categories from cache categories = getCachedCategories(); } return (categories); } /** * Populates a new DefaultModelList object with the current list of * categories. * * @return populated DefaultModelList object */ private DefaultListModel getCachedCategories() { DefaultListModel modelFilters = new DefaultListModel(); Iterator it = this.cachedCategories.iterator(); while (it.hasNext()) { modelFilters.addElement(it.next()); } return modelFilters; } /** * Populates the cached categories using a new list of categories. * * @param categories * populated object of {@link CustomCategory} objects */ private void setCategoryCache(DefaultListModel categories) { // remove existing categories this.cachedCategories.clear(); for (int f = 0; f < categories.size(); f++) { this.cachedCategories.add(categories.get(f)); } } /** * get filter for given key from filters * @param key filter key to look up * @return filter, null otherwise. */ private ThreadFilter getFromFilters(String key) { ListModel filters = getFilters(); for(int i = 0; i < filters.getSize(); i++) { ThreadFilter filter = (ThreadFilter) filters.getElementAt(i); if(filter.getName().equals(key)) { return(filter); } } return(null); } /** * generate the default filter set. */ private DefaultListModel getPredefinedFilters() { ThreadFilter newFilter = new ThreadFilter("System Thread Exclusion Filter", ".*at\\s.*", ThreadFilter.HAS_IN_STACK_RULE, true, false, false); DefaultListModel filters = new DefaultListModel(); filters.ensureCapacity(2); filters.add(0, newFilter); newFilter = new ThreadFilter("Idle Threads Filter", "", ThreadFilter.SLEEPING_RULE, true, true, false); filters.add(1, newFilter); return(filters); } public void setFilters(DefaultListModel filters) { // store into cache StringBuffer filterString = new StringBuffer(); for(int i = 0; i < filters.getSize(); i++) { if(i > 0) { filterString.append(PARAM_DELIM); } filterString.append(((ThreadFilter)filters.getElementAt(i)).getName()); filterString.append(FILTER_SEP); filterString.append(((ThreadFilter)filters.getElementAt(i)).getFilterExpression()); filterString.append(FILTER_SEP); filterString.append(((ThreadFilter)filters.getElementAt(i)).getFilterRule()); filterString.append(FILTER_SEP); filterString.append(((ThreadFilter)filters.getElementAt(i)).isGeneralFilter()); filterString.append(FILTER_SEP); filterString.append(((ThreadFilter)filters.getElementAt(i)).isExclusionFilter()); filterString.append(FILTER_SEP); filterString.append(((ThreadFilter)filters.getElementAt(i)).isEnabled()); } toolPrefs.put("filters", filterString.toString()); setFilterCache(filters); setFilterLastChanged(); } /** * store categories * @param categories */ public void setCategories(DefaultListModel categories) { // store into cache StringBuffer catString = new StringBuffer(); for (int i = 0; i < categories.getSize(); i++) { if (i > 0) { catString.append(PARAM_DELIM); } CustomCategory cat = (CustomCategory) categories.getElementAt(i); catString.append(cat.getName()); catString.append(FILTER_SEP); Iterator catIter = cat.iterOfFilters(); while ((catIter != null) && (catIter.hasNext())) { ThreadFilter filter = (ThreadFilter) catIter.next(); catString.append(filter.getName()); catString.append(FILTER_SEP); } } toolPrefs.put("categories", catString.toString()); setCategoryCache(categories); } private long filterLastChanged = -1; /** * return time stamp of last change time stamp of filter settings */ public long getFiltersLastChanged(){ return(filterLastChanged); } private void setFilterLastChanged() { filterLastChanged = System.currentTimeMillis(); } public void flush() { try { toolPrefs.flush(); } catch (BackingStoreException ex) { ex.printStackTrace(); } } /** * check if new file is in given recent file list */ private boolean hasInRecentFiles(String file, String[] currentFiles) { boolean found = false; for (String currentFile : currentFiles) { if(file.equals(currentFile)) { found = true; break; } } return found; } }