package divconq.db.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import divconq.db.DataRequest;
import divconq.lang.stem.IndexInfo;
import divconq.lang.stem.IndexInfo.StemEntry;
import divconq.lang.stem.IndexUtility;
import divconq.struct.RecordStruct;
import divconq.util.StringUtil;
public class FullTextSearchRequest extends DataRequest {
// table,field
protected Map<String,SourceInfo> sources = new HashMap<String, SourceInfo>();
protected List<PhraseInfo> required = new ArrayList<PhraseInfo>();
protected List<PhraseInfo> allowed = new ArrayList<PhraseInfo>();
protected List<PhraseInfo> prohibited = new ArrayList<PhraseInfo>();
/**
*/
public FullTextSearchRequest() {
super("dcSearchText");
RecordStruct params = new RecordStruct();
this.parameters = params;
}
public void addSource(String table, String title, String body, String... extras) {
SourceInfo si = new SourceInfo(title, body);
for (String field : extras)
si.addExtra(field);
this.sources.put(table, si);
}
public void addRequired(String phrase) {
this.required.add(new PhraseInfo(phrase, false));
}
public void addRequired(String phrase, boolean exact) {
this.required.add(new PhraseInfo(phrase, exact));
}
public void addAllowed(String phrase) {
this.allowed.add(new PhraseInfo(phrase, false));
}
public void addAllowed(String phrase, boolean exact) {
this.allowed.add(new PhraseInfo(phrase, exact));
}
public void addProhibited(String phrase) {
this.prohibited.add(new PhraseInfo(phrase, false));
}
public void addProhibited(String phrase, boolean exact) {
this.prohibited.add(new PhraseInfo(phrase, exact));
}
public void filterField(String table, String field, String sid) {
SourceInfo si = this.sources.get(table);
if (si == null)
return;
si.addFilter(field, sid);
}
@Override
public RecordStruct buildParams() {
if (this.sources.size() > 0) {
RecordStruct stables = new RecordStruct();
RecordStruct ftables = new RecordStruct();
for (String table : this.sources.keySet()) {
SourceInfo sinfo = this.sources.get(table);
RecordStruct sects = new RecordStruct();
stables.setField(table, sects);
if (StringUtil.isNotEmpty(sinfo.title))
sects.setField("Title", sinfo.title);
if (StringUtil.isNotEmpty(sinfo.body))
sects.setField("Body", sinfo.body);
if (sinfo.extras.size() > 0) {
RecordStruct extras = new RecordStruct();
sects.setField("Extras", extras);
for (String extra : sinfo.extras)
extras.setField(extra, 1);
}
RecordStruct filters = new RecordStruct();
ftables.setField(table, filters);
for (String fld : sinfo.filter.keySet()) {
RecordStruct sids = new RecordStruct();
filters.setField(fld, sids);
Set<String> slist = sinfo.filter.get(fld);
for (String sid : slist)
sids.setField(sid, 1);
}
}
((RecordStruct) this.parameters).setField("Sources", stables);
((RecordStruct) this.parameters).setField("AllowedSids", ftables);
}
if (this.required.size() > 0) {
RecordStruct words = new RecordStruct();
for (PhraseInfo phrase : this.required) {
boolean eonce = true;
for (Entry<String, StemEntry> stem : phrase.info.entries.entrySet()) {
RecordStruct sects = new RecordStruct();
sects.setField("Term", 1);
if (eonce && StringUtil.isNotEmpty(phrase.exact)) {
sects.setField("Exact", phrase.exact);
eonce = false;
}
String term = stem.getKey();
words.setField(term, sects);
}
}
((RecordStruct) this.parameters).setField("RequiredWords", words);
}
if (this.allowed.size() > 0) {
RecordStruct words = new RecordStruct();
for (PhraseInfo phrase : this.allowed) {
boolean eonce = true;
for (Entry<String, StemEntry> stem : phrase.info.entries.entrySet()) {
RecordStruct sects = new RecordStruct();
sects.setField("Term", 1);
if (eonce && StringUtil.isNotEmpty(phrase.exact)) {
sects.setField("Exact", phrase.exact);
eonce = false;
}
String term = stem.getKey();
words.setField(term, sects);
}
}
((RecordStruct) this.parameters).setField("AllowedWords", words);
}
if (this.prohibited.size() > 0) {
RecordStruct words = new RecordStruct();
for (PhraseInfo phrase : this.prohibited) {
boolean eonce = true;
for (Entry<String, StemEntry> stem : phrase.info.entries.entrySet()) {
RecordStruct sects = new RecordStruct();
sects.setField("Term", 1);
if (eonce && StringUtil.isNotEmpty(phrase.exact)) {
sects.setField("Exact", phrase.exact);
eonce = false;
}
String term = stem.getKey();
words.setField(term, sects);
}
}
((RecordStruct) this.parameters).setField("ProhibitedWords", words);
}
return (RecordStruct)this.parameters;
}
public class PhraseInfo {
public String exact = null;
public IndexInfo info = null;
public PhraseInfo(String phrase, boolean exact) {
if (exact)
this.exact = phrase;
this.info = IndexUtility.stemEnglishPhrase(phrase, 0);
}
}
public class SourceInfo {
protected String title = null;
protected String body = null;
protected Set<String> extras = new HashSet<String>();
protected Map<String, Set<String>> filter = new HashMap<String, Set<String>>();
public SourceInfo(String title, String body) {
this.title = title;
this.body = body;
}
public void addFilter(String field, String sid) {
Set<String> f = this.filter.get(field);
if (f == null) {
f = new HashSet<String>();
this.filter.put(field, f);
}
f.add(sid);
}
public void addExtra(String field) {
this.extras.add(field);
}
}
}