package eu.jucy.ui.searchspy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import uc.ISearchReceivedListener;
import uc.crypto.HashValue;
import uihelpers.SUIJob;
import uihelpers.TableViewerAdministrator;
import eu.jucy.gui.ApplicationWorkbenchWindowAdvisor;
import eu.jucy.gui.UCEditor;
import eu.jucy.ui.searchspy.SearchSpyColumns.Count;
import eu.jucy.ui.searchspy.SearchSpyColumns.Hits;
import eu.jucy.ui.searchspy.SearchSpyColumns.SearchStringColumn;
import eu.jucy.ui.searchspy.SearchSpyColumns.Time;
public class SearchSpyEditor extends UCEditor implements ISearchReceivedListener {
public static final String ID = "eu.jucy.ui.searchspy.SearchSpyEditor" ;
private Label hitRatioLabel;
private Label hitsLabel;
private Label averageLabel;
private Label totalLabel;
private Table table;
private TableViewer tableViewer;
private TableViewerAdministrator<SearchInfo> tva;
private final Map<String,SearchInfo> info = new HashMap<String,SearchInfo>();
/**
*
*/
private final List<SearchInfo> lastSearchInfos = new LinkedList<SearchInfo>();
private long totalSearches = 0;
private long hits = 0;
public SearchSpyEditor() {
}
public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout());
tableViewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER);
tableViewer.setContentProvider(new SearchSpyContentProvider());
table = tableViewer.getTable();
table.setHeaderVisible(true);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Composite composite = new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
final GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 5;
composite.setLayout(gridLayout);
final Button ignoreTthSearchesButton = new Button(composite, SWT.CHECK);
ignoreTthSearchesButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
if (ignoreTthSearchesButton.getSelection()) {
tableViewer.addFilter(new ViewerFilter() {
public boolean select(Viewer viewer,
Object parentElement, Object element) {
return !((SearchInfo)element).tthSearch;
}
});
} else {
tableViewer.setFilters(new ViewerFilter[]{});
}
}
});
ignoreTthSearchesButton.setSelection(false);
ignoreTthSearchesButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
ignoreTthSearchesButton.setText(Lang.SPYHideTTHSearches);
totalLabel = new Label(composite, SWT.BORDER);
totalLabel.setLayoutData(new GridData(100, SWT.DEFAULT));
averageLabel = new Label(composite, SWT.BORDER);
averageLabel.setLayoutData(new GridData(100, SWT.DEFAULT));
hitsLabel = new Label(composite, SWT.BORDER);
hitsLabel.setLayoutData(new GridData(100, SWT.DEFAULT));
hitRatioLabel = new Label(composite, SWT.BORDER);
hitRatioLabel.setLayoutData(new GridData(100, SWT.DEFAULT));
tva = new TableViewerAdministrator<SearchInfo>(tableViewer,
Arrays.asList(new SearchStringColumn(),new Count(),new Time(),new Hits()),
ID,TableViewerAdministrator.NoSorting);
tva.apply();
tableViewer.setInput(this);
ApplicationWorkbenchWindowAdvisor.get().registerSRL(this);
setControlsForFontAndColour(tableViewer.getTable());
getSite().setSelectionProvider(tableViewer);
}
public void searchReceived(Set<String> searchStrings, Object source,
final int nrOfFoundResults) {
final String shown =concat(searchStrings);
new SUIJob(table) {
public void run() {
hits += nrOfFoundResults;
totalSearches++;
SearchInfo found = info.get(shown);
if (found == null) {
found = new SearchInfo(shown,nrOfFoundResults);
info.put(shown, found);
tableViewer.add(found);
}
found.update(nrOfFoundResults);
tableViewer.update(found, null);
lastSearchInfos.add(found);
if (lastSearchInfos.size() > 5 ) {
lastSearchInfos.remove(0);
}
updateLabels();
}
}.schedule();
}
private void updateLabels() {
totalLabel.setText(String.format(Lang.SPYTotal,totalSearches));
averageLabel.setText(String.format(Lang.SPYAverage,Float.valueOf(getAverage())));
hitsLabel.setText(String.format(Lang.SPYHitsFormatted,hits));
hitRatioLabel.setText(String.format(Lang.SPYHitRatio,(float)hits/(float)totalSearches));
}
private float getAverage() {
if (lastSearchInfos.isEmpty() ) {
return 0f;
}
long timedif = lastSearchInfos.get(lastSearchInfos.size()-1 ).date-lastSearchInfos.get(0).date;
if (timedif == 0) {
return 0f;
}
return (1000f*(float)lastSearchInfos.size())/(float)timedif ;
}
private static String concat(Set<String> searchStrings) {
if (searchStrings.size() == 1) {
return ((String)searchStrings.toArray()[0]).intern();
} else {
String s = null;
for (String part: searchStrings) {
if (s == null) {
s = part;
} else {
s += " "+part;
}
}
if (s == null) {
return "";
} else {
return s.intern();
}
}
}
public void setFocus() {
table.setFocus();
}
public void dispose() {;
ApplicationWorkbenchWindowAdvisor.get().unregisterSRL(this);
super.dispose();
}
public static class SearchInfo {
private final String searchString;
private final boolean tthSearch;
private int results;
private int count = 0;
private long date;
public SearchInfo(String searchString, int results) {
this.searchString = searchString;
this.results = results;
tthSearch = HashValue.isHash(searchString);
}
void update(int searchresults) {
results = searchresults;
count++;
date = System.currentTimeMillis();
}
public String getSearchString() {
return searchString;
}
public int getResults() {
return results;
}
public int getCount() {
return count;
}
public long getDate() {
return date;
}
public String toString() {
return searchString;
}
}
class SearchSpyContentProvider implements IStructuredContentProvider {
public Object[] getElements(Object inputElement) {
if (inputElement instanceof SearchSpyEditor) {
return info.values().toArray();
}
return new Object[]{};
}
public void dispose() {}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
}
}