package com.delcyon.capo.webapp.widgets;
import javax.jcr.Node;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import com.delcyon.capo.webapp.servlets.CapoWebApplication;
import eu.webtoolkit.jwt.AlignmentFlag;
import eu.webtoolkit.jwt.Utils;
import eu.webtoolkit.jwt.WAnchor;
import eu.webtoolkit.jwt.WApplication;
import eu.webtoolkit.jwt.WCompositeWidget;
import eu.webtoolkit.jwt.WContainerWidget;
import eu.webtoolkit.jwt.WDialog;
import eu.webtoolkit.jwt.WLength;
import eu.webtoolkit.jwt.WLength.Unit;
import eu.webtoolkit.jwt.WLineEdit;
import eu.webtoolkit.jwt.WLink;
import eu.webtoolkit.jwt.WLink.Type;
import eu.webtoolkit.jwt.WPushButton;
import eu.webtoolkit.jwt.WTable;
import eu.webtoolkit.jwt.WText;
/**
* This implements the main jcr search functionality. It will result in a dialog of matches,
* and links that will change the internal path accordingly. The dialog closes whenever the internal path changes
* @author jeremiah
*
*/
public class WCapoSearchControl extends WCompositeWidget
{
private WDialog searchResultsDialog;
private WLineEdit searchFieldTextEdit;
private WPushButton searchButton;
private WContainerWidget implementationWidget = new WContainerWidget();
public WCapoSearchControl()
{
setImplementation(implementationWidget);
setInline(true);
searchFieldTextEdit = new WLineEdit();
implementationWidget.addWidget(searchFieldTextEdit);
searchButton = new WPushButton("Search");
implementationWidget.addWidget(searchButton);
searchButton.clicked().addListener(this,this::search);
searchFieldTextEdit.enterPressed().addListener(this, this::search);
//try to close the dialog whenever the internal path changes
WApplication.getInstance().internalPathChanged().addListener(this, () -> getSearchResultsDialog().hide());
}
/**
* This needs a whole lot of work, and is mostly here as a place to mess around with jcr searching at the moment
*/
private void search()
{
Session jcrSession = ((CapoWebApplication)CapoWebApplication.getInstance()).getJcrSession();
try
{
//element(*, nt:unstructured)[jcr:contains(., 'foo')]
//Query query = jcrSession.getWorkspace().getQueryManager().createQuery("SELECT * FROM [nt:unstructured] where NAME([nt:unstructured]) = 'server:log' order by message", "JCR-SQL2");
String[] langs = jcrSession.getWorkspace().getQueryManager().getSupportedQueryLanguages();
for (String lang : langs)
{
System.out.println(lang+"--"+searchFieldTextEdit.getText());
}
//Query query = jcrSession.getWorkspace().getQueryManager().createQuery("//element(*, nt:unstructured)[jcr:contains(@content, '"+searchFieldTextEdit.getText()+"')/(@content)]", Query.XPATH);
Query query = jcrSession.getWorkspace().getQueryManager().createQuery("SELECT * FROM [nt:unstructured] as n WHERE CONTAINS(n.*, '"+searchFieldTextEdit.getText()+"')", Query.JCR_SQL2);
QueryResult result = query.execute();
for (String lang : result.getColumnNames())
{
System.out.println(lang);
}
// Iterate over the nodes in the results ...
int excerptWidth = 50;
RowIterator rows = result.getRows();
System.out.println("=============================");
WTable table = new WTable(getSearchResultsDialog().getContents());
//table.toggleStyleClass("table-hover", true);
table.toggleStyleClass("table-condensed", true);
table.toggleStyleClass("table-striped", true);
table.toggleStyleClass("table-full", true);
table.setHeaderCount(1);
table.getElementAt(0, 0).addWidget(new WText("Path"));
table.getElementAt(0, 1).addWidget(new WText("Excerpt"));
table.getElementAt(0, 2).addWidget(new WText("Score"));
table.getElementAt(0, 2).setContentAlignment(AlignmentFlag.AlignRight);
int rowNumber = 0;
while ( rows.hasNext() ) {
rowNumber++;
Row row = rows.nextRow();
Node _node = row.getNode();
String excerpt = _node.getProperty("content").getString().toLowerCase();
String searchField = searchFieldTextEdit.getText();
int excerptLocation = excerpt.indexOf(searchField.toLowerCase());
int startExcerptLocation = excerptLocation -excerptWidth;
if(startExcerptLocation < 0 )
{
startExcerptLocation = 0;
}
if(excerpt.substring(startExcerptLocation, excerptLocation).indexOf('\n') >= 0)
{
startExcerptLocation += excerpt.substring(startExcerptLocation, excerptLocation).indexOf('\n')+1;
}
int endExcerptLocation = excerptLocation+excerptWidth+searchField.length();
if(endExcerptLocation >= excerpt.length())
{
endExcerptLocation = excerpt.length()-1;
}
if(excerpt.substring(excerptLocation+searchField.length(), endExcerptLocation).indexOf('\n') >= 0)
{
int crDistance = excerpt.substring(excerptLocation+searchField.length(), endExcerptLocation).indexOf('\n');
endExcerptLocation -= (excerptWidth - crDistance);
}
excerpt = _node.getProperty("content").getString().substring(startExcerptLocation, endExcerptLocation);
System.out.println("===>"+_node.getPath()+" type:"+_node.getPrimaryNodeType().getName()+" score="+row.getScore()+" exrp = '"+excerpt+"'");
//dump(_node);new WLink(Type.InternalPath, "/legend")
table.getElementAt(rowNumber, 0).addWidget(new WAnchor(new WLink(Type.InternalPath, _node.getPath()),_node.getPath(),CapoWebApplication.getInstance().getRoot()));
table.getElementAt(rowNumber,1).addWidget(new WText(Utils.htmlEncode(excerpt)));
table.getElementAt(rowNumber,1).setAttributeValue("width", "80%");
table.getElementAt(rowNumber,1).setContentAlignment(AlignmentFlag.AlignCenter);
table.getElementAt(rowNumber, 2).addWidget(new WText(row.getScore()+""));
table.getElementAt(rowNumber,2).setContentAlignment(AlignmentFlag.AlignRight);
}
searchResultsDialog.show();
System.out.println("=============================");
} catch (Exception e)
{
e.printStackTrace();
}
}
private WDialog getSearchResultsDialog()
{
if(searchResultsDialog == null)
{
searchResultsDialog = new WDialog("Search Results");
searchResultsDialog.setWidth(new WLength(80d, Unit.Percentage));
searchResultsDialog.setClosable(true);
searchResultsDialog.rejectWhenEscapePressed(true);
}
return searchResultsDialog;
}
}