package org.docear.plugin.services.features.documentretrieval.documentsearch;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.core.MultivaluedMap;
import org.docear.plugin.core.DocearController;
import org.docear.plugin.core.logging.DocearLogger;
import org.docear.plugin.services.ServiceController;
import org.docear.plugin.services.features.documentretrieval.DocumentRetrievalController;
import org.docear.plugin.services.features.documentretrieval.documentsearch.actions.ShowDocumentSearchAction;
import org.docear.plugin.services.features.documentretrieval.model.DocumentsModel;
import org.docear.plugin.services.features.io.DocearConnectionProvider;
import org.docear.plugin.services.features.io.DocearServiceResponse;
import org.docear.plugin.services.features.io.DocearServiceResponse.Status;
import org.docear.plugin.services.features.user.DocearUser;
import org.docear.plugin.services.xml.DocearXmlBuilder;
import org.docear.plugin.services.xml.DocearXmlElement;
import org.docear.plugin.services.xml.DocearXmlRootElement;
import org.freeplane.core.util.LogUtils;
import org.freeplane.n3.nanoxml.IXMLParser;
import org.freeplane.n3.nanoxml.IXMLReader;
import org.freeplane.n3.nanoxml.StdXMLReader;
import org.freeplane.n3.nanoxml.XMLParserFactory;
import com.sun.jersey.core.util.StringKeyStringValueIgnoreCaseMultivaluedMap;
public class DocumentSearchController extends DocumentRetrievalController {
private String query = "";
private int page = 1;
private SearchModel searchModel = null;
public final static DocumentSearchController getController() {
if (controller == null) {
controller = new DocumentSearchController();
}
if (controller instanceof DocumentSearchController) {
return (DocumentSearchController) controller;
}
else {
controller.closeDocumentView();
new ShowDocumentSearchAction().actionPerformed(null);
return (DocumentSearchController) controller;
}
}
public void setQuery(String query) {
this.query = query;
}
@Override
protected DocearServiceResponse getRequestResponse(boolean userRequest) {
MultivaluedMap<String,String> params = new StringKeyStringValueIgnoreCaseMultivaluedMap();
if (searchModel != null) {
params.add("searchModelId", String.valueOf(searchModel.getId()));
}
if (getDocumentsSetId() != null) {
params.add("searchDocumentsSetId", String.valueOf(getDocumentsSetId()));
}
params.add("page", String.valueOf(page));
params.add("userName", ServiceController.getCurrentUser().getName());
params.add("number", "10");
if (this.query.trim().length() > 0) {
return ServiceController.getConnectionController().get("/documents/" + createLuceneSearchString(query) + "/", params);
}
else {
return null;
}
}
private String createLuceneSearchString(String query) {
query = query.toLowerCase().trim();
if (query.contains("and") || query.contains("or")) {
return query;
}
StringBuilder sb = new StringBuilder();
String[] terms = query.split(" ");
sb.append(terms[0]);
for (int i=1; i<terms.length; i++) {
sb.append(" AND ");
sb.append(terms[i]);
}
String queryString = sb.toString();
LogUtils.info("using query string: "+queryString);
return queryString;
}
@Override
public void refreshDocuments() {
initializeDocumentSearcher();
refreshDocuments(null);
}
public String getQuery() {
return query;
}
public SearchModel getSearchModel() {
if (searchModel != null) {
return searchModel;
}
final DocearUser user = ServiceController.getCurrentUser();
if (user == null) {
return null;
}
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<SearchModel> task = executor.submit(new Callable<SearchModel>() {
public SearchModel call() throws Exception {
try {
DocearServiceResponse response = ServiceController.getConnectionController().get("/user/"+user.getUsername()+"/searchmodel/");
if (response != null && response.getStatus() == Status.OK) {
DocearXmlBuilder xmlBuilder = new DocearXmlBuilder();
IXMLReader reader = new StdXMLReader(new InputStreamReader(response.getContent(), "UTF8"));
IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
parser.setBuilder(xmlBuilder);
parser.setReader(reader);
parser.parse();
DocearXmlRootElement result = (DocearXmlRootElement) xmlBuilder.getRoot();
DocearXmlElement element = result.find("searchmodel");
searchModel = new SearchModel(Long.valueOf(element.getAttributeValue("id")), element.getContent().trim());
if (searchModel != null) {
sendModelReceivedConfirmation();
}
return searchModel;
}
}
catch(NullPointerException ignore) {}
return null;
}
private void sendModelReceivedConfirmation() {
try {
MultivaluedMap<String,String> params = new StringKeyStringValueIgnoreCaseMultivaluedMap();
params.add("searchModelId", String.valueOf(searchModel.getId()));
DocearServiceResponse resp = ServiceController.getConnectionController().put("/user/"+ServiceController.getCurrentUser().getUsername()+"/searchmodel/", params);
if(resp.getStatus() != Status.OK) {
DocearLogger.info(resp.getContentAsString());
}
}
catch (Exception e) {
System.out.println("exception in DocumentSearchController.getSearchModel().new Callable() {...}.sendModelReceivedConfirmation(): "
+ e.getMessage());
}
}
});
try {
return task.get(DocearConnectionProvider.CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
}
catch(Exception e) {
LogUtils.warn(e);
}
return null;
}
public void search(String query) {
this.query = query;
if (query == null) {
return;
}
query = query.trim().toLowerCase();
if (query.length() == 0) {
return;
}
DocumentSearchController.getController().setQuery(query);
DocumentSearchController.getController().refreshDocuments();
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
@Override
public void shutdown() {
this.query = "";
this.searchModel = null;
}
@Override
public void sendReceiveConfirmation(final DocumentsModel model) {
DocearController.getController().getEventQueue().invoke(new Runnable() {
public void run() {
try {
MultivaluedMap<String,String> params = new StringKeyStringValueIgnoreCaseMultivaluedMap();
params.add("page", String.valueOf(page));
params.add("userName", ServiceController.getCurrentUser().getName());
params.add("searchDocumentsSetId", String.valueOf(getDocumentsSetId()));
DocearServiceResponse resp = ServiceController.getConnectionController().put("/documents/" + query + "/", params);
if(resp.getStatus() != Status.OK) {
DocearLogger.info(resp.getContentAsString());
}
}
catch (Exception e) {
LogUtils.warn("exception in DocumentSearchController.sendReceiveConfirmation(...).new Runnable() {...}.run(): " + e.getMessage());
}
}
});
}
}