package com.limegroup.gnutella.gui.search;
import java.util.HashMap;
import java.util.Map;
import com.limegroup.gnutella.settings.AbstractSettings;
import com.limegroup.gnutella.settings.SettingsFactory;
import com.limegroup.gnutella.settings.StringSetting;
/**
* Maintains the settings of what selectors are associated with
* the various schema searches.
*/
class SelectorsHandler extends AbstractSettings {
/**
* The sole instance of this SelectorSettings class.
*/
private static final SelectorsHandler INSTANCE = new SelectorsHandler();
/**
* The factory for the SelectorSettings.
*/
private static final SettingsFactory FACTORY = INSTANCE.getFactory();
/**
* The mapping of active selectors.
*
* The key is the type of search + "_" + the number of the selector.
* The value is the actual selector.
*
* For example, if the default selectors for someone's "any type" searches
* are first "schema", then "audio/artist", then "audio/album", this would
* have:
* ANY_TYPE_1 -> Selector (of type schema) / StringSetting
* ANY_TYPE_2 -> Selector (of type field) / StringSetting
* ANY_TYPE_3 -> Selector (of type field) / StringSetting
*/
private static final Map /* String -> SelectorSettingPair */ FILTERS =
new HashMap();
/**
* Returns the instance of this class.
*/
public static SelectorsHandler instance() {
return INSTANCE;
}
/**
* Private constructor to ensure that nothing else can instantiate.
*/
private SelectorsHandler() {
super("filters.props", "LimeWire Filters File");
}
/**
* Retrieves the selector for the specified type at the specified depth.
*/
public static Selector getSelector(String type, int depth) {
String key = type + "_" + depth;
SelectorSettingPair pair = (SelectorSettingPair)FILTERS.get(key);
if(pair == null) {
pair = addDefault(type, depth);
}
return pair.selector;
}
/**
* Sets the new selector for the specified type/depth.
*/
public static void setSelector(String type, int depth, Selector selector) {
String key = type + "_" + depth;
SelectorSettingPair pair = (SelectorSettingPair)FILTERS.get(key);
StringSetting setting;
if(pair == null)
pair = addDefault(type, depth);
setting = pair.setting;
setting.setValue(selector.toString());
FILTERS.put(key, new SelectorSettingPair(selector, setting));
}
/**
* Adds the default selector for the specified type & depth.
*/
private static SelectorSettingPair addDefault(String type, int depth) {
String key = type + "_" + depth;
Selector selector = getDefaultSelector(type, depth);
StringSetting setting =
FACTORY.createStringSetting(key, selector.toString());
try {
selector = Selector.createFromString(setting.getValue());
} catch(IllegalArgumentException iae) {
// invalid data on disk, ignore.
}
SelectorSettingPair pair = new SelectorSettingPair(selector, setting);
FILTERS.put(key, pair);
return pair;
}
/**
* Creates default selectors for the specified types and depths.
*
* Default 'all' selectors are:
* 1: schema
* 2: artist
* 3: album
*
* Default audio selectors are:
* 1: schema
* 2: artist
* 3: album
*
* Default 'video' selectors are:
* 1: schema
* 2: type
* 3: rating
*
* Default selectors for everything else are:
* 1: schema
* 2: extension
* 3: quality
*/
private static Selector getDefaultSelector(String type, int depth) {
if("*".equals(type)) {
switch(depth) {
case 0: return Selector.createSchemaSelector();
case 1: return Selector.createFieldSelector("audio",
"audios__audio__artist__");
case 2: return Selector.createFieldSelector("audio",
"audios__audio__album__");
}
} else if("audio".equals(type)) {
switch(depth) {
case 0: return Selector.createFieldSelector("audio",
"audios__audio__genre__");
case 1: return Selector.createFieldSelector("audio",
"audios__audio__artist__");
case 2: return Selector.createFieldSelector("audio",
"audios__audio__album__");
}
} else if("video".equals(type)) {
switch(depth) {
case 0: return Selector.createPropertySelector("RESULT_PANEL_TYPE");
case 1: return Selector.createFieldSelector("video",
"videos__video__type__");
case 2: return Selector.createFieldSelector("video",
"videos__video__rating__");
}
} else {
switch(depth) {
case 0: return Selector.createSchemaSelector();
case 1: return Selector.createPropertySelector("RESULT_PANEL_TYPE");
case 2: return Selector.createPropertySelector("RESULT_PANEL_SPEED");
}
}
throw new IllegalArgumentException("invalid depth: " + depth);
}
/**
* A Pair of Selector/Setting.
*/
private static class SelectorSettingPair {
private final Selector selector;
private final StringSetting setting;
SelectorSettingPair(Selector selector, StringSetting setting) {
this.selector = selector;
this.setting = setting;
}
}
}