package com.tubeonfire.search.admin;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import com.google.appengine.api.search.Document;
import com.google.appengine.api.search.Field;
import com.google.appengine.api.search.Index;
import com.google.appengine.api.search.IndexSpec;
import com.google.appengine.api.search.ListRequest;
import com.google.appengine.api.search.ListResponse;
import com.google.appengine.api.search.Query;
import com.google.appengine.api.search.Results;
import com.google.appengine.api.search.ScoredDocument;
import com.google.appengine.api.search.SearchServiceFactory;
import com.tubeonfire.entity.Tube;
import com.tubeonfire.model.admin.TubeModel;
import com.tubeonfire.util.DateHelper;
public class TubeSearchEngine {
private static Index INDEX = SearchServiceFactory.getSearchService()
.getIndex(IndexSpec.newBuilder().setName("tube"));
private static final Logger log = Logger.getLogger(TubeSearchEngine.class
.getName());
public static void index(Tube obj) {
try {
Document.Builder docBuilder = Document.newBuilder();
objectToSearchDocument(docBuilder, obj);
Document doc = docBuilder.build();
INDEX.add(doc);
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
}
}
public static void update(Tube obj) {
remove(obj.getId());
index(obj);
}
public static void updateSearchFirst(Tube obj) {
remove(obj.getId());
index(obj);
TubeModel.insertNoIndex(obj);
}
public static void remove(String id) {
try {
Query query = Query.newBuilder().build("id:\"" + id + "\"");
Results<ScoredDocument> docResult = INDEX.search(query);
if (docResult.getNumberFound() > 0) {
for (ScoredDocument scoredDocument : docResult) {
INDEX.remove(scoredDocument.getId());
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
}
}
public static void removeAllDocument() {
int count = 0;
while (true) {
List<String> docIds = new ArrayList<String>();
// Return a set of document IDs.
ListRequest request = ListRequest.newBuilder()
.setReturningIdsOnly(true).build();
ListResponse<Document> response = INDEX.listDocuments(request);
if (response.getResults().isEmpty()) {
break;
}
for (Document doc : response) {
docIds.add(doc.getId());
count++;
}
INDEX.remove(docIds);
}
System.out
.println("Remove " + count + " document from Index success !");
}
public static void reindex() {
int count = 0;
TubeModel tubeModel = new TubeModel();
tubeModel.setPage(1);
while (true) {
tubeModel.setLimit(488);
tubeModel.getTubes(false);
List<Tube> list = tubeModel.getListResult();
for (Tube tube : list) {
index(tube);
count++;
}
if (list.size() < 488) {
break;
}
tubeModel.setPage(tubeModel.getPage() + 1);
}
System.out.println("Index " + count
+ " document from Tube table success !");
}
@SuppressWarnings("unchecked")
public static Document.Builder objectToSearchDocument(
Document.Builder docBuilder, Object obj) {
for (java.lang.reflect.Field f : obj.getClass().getDeclaredFields()) {
f.setAccessible(true);
if (f.getType().getSimpleName().equals("String")) {
try {
docBuilder.addField(Field.newBuilder().setName(f.getName())
.setText((String) f.get(obj)));
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("int")) {
try {
docBuilder.addField(Field.newBuilder().setName(f.getName())
.setNumber(f.getInt(obj)));
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("Date")) {
try {
docBuilder.addField(Field
.newBuilder()
.setName(f.getName())
.setDate(
DateHelper.removeTimeFromDate((Date) f
.get(obj))));
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("boolean")) {
try {
docBuilder.addField(Field.newBuilder().setName(f.getName())
.setText((String) f.get(obj)));
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("long")) {
try {
docBuilder.addField(Field.newBuilder().setName(f.getName())
.setNumber(f.getLong(obj)));
} catch (Exception e) {
e.printStackTrace();
docBuilder.addField(Field.newBuilder().setName(f.getName())
.setNumber(1));
}
} else if (f.getType().getSimpleName().equals("List")) {
try {
List<String> list = (ArrayList<String>) f.get(obj);
StringBuilder stringBuilder = new StringBuilder();
for (String string : list) {
stringBuilder.append(string);
stringBuilder.append(",");
}
try {
docBuilder.addField(Field.newBuilder()
.setName(f.getName())
.setText(stringBuilder.toString()));
} catch (Exception e) {
}
} catch (Exception e) {
}
}
}
return docBuilder;
}
public static Tube documentToObjectByReflection(ScoredDocument doc) {
Tube obj = new Tube();
for (java.lang.reflect.Field f : obj.getClass().getDeclaredFields()) {
f.setAccessible(true);
if (f.getType().getSimpleName().equals("String")) {
try {
StringBuilder tmpString = new StringBuilder();
tmpString.append(doc.getOnlyField(f.getName()).getText());
f.set(obj, tmpString.toString());
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("int")) {
try {
f.set(obj, doc.getOnlyField(f.getName()).getNumber()
.intValue());
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("Date")) {
try {
f.set(obj, doc.getOnlyField(f.getName()).getDate());
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("boolean")) {
try {
f.set(obj,
doc.getOnlyField(f.getName()).getText()
.equals("true") ? true : false);
} catch (Exception e) {
}
} else if (f.getType().getSimpleName().equals("long")) {
try {
f.set(obj, doc.getOnlyField(f.getName()).getNumber()
.longValue());
} catch (Exception e) {
try {
f.set(obj, 1);
} catch (Exception e2) {
}
}
} else if (f.getType().getSimpleName().equals("List")) {
try {
List<String> list = new ArrayList<String>();
String[] tags = doc.getOnlyField(f.getName()).getText()
.split(",");
for (String string : tags) {
list.add(string);
}
f.set(obj, list);
} catch (Exception e) {
}
}
}
return obj;
}
}