001: package prefuse.data.search;
002:
003: import java.util.Iterator;
004: import java.util.LinkedHashMap;
005: import java.util.logging.Logger;
006: import java.util.regex.Pattern;
007:
008: import prefuse.data.Tuple;
009: import prefuse.data.tuple.DefaultTupleSet;
010: import prefuse.data.tuple.TupleSet;
011: import prefuse.util.StringLib;
012:
013: /**
014: * SearchTupleSet implementation that treats the query as a regular expression
015: * to match against all indexed Tuple data fields.
016: * The regular expression engine provided by the
017: * standard Java libraries
018: * ({@link java.util.regex.Pattern java.util.regex.Pattern}) is used; please
019: * refer to the documentation for that class for more about the regular
020: * expression syntax.
021: *
022: * @author <a href="http://jheer.org">jeffrey heer</a>
023: * @see prefuse.data.query.SearchQueryBinding
024: */
025: public class RegexSearchTupleSet extends SearchTupleSet {
026:
027: private String m_query = "";
028: private boolean m_caseSensitive;
029: private LinkedHashMap m_source = new LinkedHashMap();
030:
031: /**
032: * Create a new, case-insensitive regular expression search tuple set.
033: */
034: public RegexSearchTupleSet() {
035: this (false);
036: }
037:
038: /**
039: * Create a new regular expression search tuple set.
040: * @param caseSensitive true to make the indexing case sensitive, false
041: * otherwise.
042: */
043: public RegexSearchTupleSet(boolean caseSensitive) {
044: m_caseSensitive = caseSensitive;
045: }
046:
047: /**
048: * @see prefuse.data.search.SearchTupleSet#getQuery()
049: */
050: public String getQuery() {
051: return m_query;
052: }
053:
054: /**
055: * @see prefuse.data.search.SearchTupleSet#search(java.lang.String)
056: */
057: public void search(String query) {
058: if (query == null)
059: query = "";
060: if (!m_caseSensitive)
061: query = query.toLowerCase();
062: if (query.equals(m_query))
063: return;
064:
065: Pattern pattern = null;
066: try {
067: pattern = Pattern.compile(query);
068: } catch (Exception e) {
069: Logger logger = Logger.getLogger(this .getClass().getName());
070: logger.warning("Pattern compile failed." + "\n"
071: + StringLib.getStackTrace(e));
072: return;
073: }
074:
075: Tuple[] rem = clearInternal();
076: m_query = query;
077: Iterator fields = m_source.keySet().iterator();
078: while (fields.hasNext()) {
079: String field = (String) fields.next();
080: TupleSet ts = (TupleSet) m_source.get(field);
081:
082: Iterator tuples = ts.tuples();
083: while (tuples.hasNext()) {
084: Tuple t = (Tuple) tuples.next();
085: String text = t.getString(field);
086: if (!m_caseSensitive)
087: text = text.toLowerCase();
088:
089: if (pattern.matcher(text).matches())
090: addInternal(t);
091: }
092: }
093: Tuple[] add = getTupleCount() > 0 ? toArray() : null;
094: fireTupleEvent(add, rem);
095: }
096:
097: /**
098: * @see prefuse.data.search.SearchTupleSet#index(prefuse.data.Tuple, java.lang.String)
099: */
100: public void index(Tuple t, String field) {
101: TupleSet ts = (TupleSet) m_source.get(field);
102: if (ts == null) {
103: ts = new DefaultTupleSet();
104: m_source.put(field, ts);
105: }
106: ts.addTuple(t);
107: }
108:
109: /**
110: * @see prefuse.data.search.SearchTupleSet#unindex(prefuse.data.Tuple, java.lang.String)
111: */
112: public void unindex(Tuple t, String field) {
113: TupleSet ts = (TupleSet) m_source.get(field);
114: if (ts != null) {
115: ts.removeTuple(t);
116: }
117: }
118:
119: /**
120: * Returns true, as unidexing is supported by this class.
121: * @see prefuse.data.search.SearchTupleSet#isUnindexSupported()
122: */
123: public boolean isUnindexSupported() {
124: return true;
125: }
126:
127: /**
128: * Removes all search hits and clears out the index.
129: * @see prefuse.data.tuple.TupleSet#clear()
130: */
131: public void clear() {
132: m_source.clear();
133: super .clear();
134: }
135:
136: } // end of class RegexSearchTupleSet
|