blob: 6b58e2830b69b5f3fd57814bd4bd24cbad44d50d [file] [log] [blame]
/*=========================================================================
* (c)Copyright 2002-2011, GemStone Systems, Inc. All Rights Reserved.
* 1260 NW Waterhouse Ave., Suite 200, Beaverton, OR 97006
* All Rights Reserved.
* =======================================================================*/
package com.gemstone.gemfire.mgmt.DataBrowser.ui;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import com.gemstone.gemfire.cache.query.CqStatistics;
import com.gemstone.gemfire.mgmt.DataBrowser.query.ColumnNotFoundException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.ColumnValueNotAvailableException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.IntrospectionResult;
import com.gemstone.gemfire.mgmt.DataBrowser.query.cq.CQQuery;
import com.gemstone.gemfire.mgmt.DataBrowser.query.cq.EventData;
import com.gemstone.gemfire.mgmt.DataBrowser.query.cq.event.ErrorEvent;
import com.gemstone.gemfire.mgmt.DataBrowser.query.cq.event.ICQEvent;
import com.gemstone.gemfire.mgmt.DataBrowser.query.cq.event.RowAdded;
import com.gemstone.gemfire.mgmt.DataBrowser.ui.model.CQueryResultsInput;
import com.gemstone.gemfire.mgmt.DataBrowser.ui.tree.ExploreAction;
import com.gemstone.gemfire.mgmt.DataBrowser.utils.LogUtil;
/**
* @author mjha
*
*/
public class CQResultsPanel extends Composite {
private static final int WIDTH = 100;
private List<TableViewer> tblResults_ = null;
private CTabFolder resultsContainer_;
private CQQuery query;
StatisticsPanel statsPanel;
private Text exceptions;
/**
* @param parent
* @param style
*/
public CQResultsPanel(Composite parent, int style) {
super(parent, style);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
this.setLayout(layout);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
SashForm sashForm= new SashForm(this, SWT.FLAT | SWT.VERTICAL);
layout = new GridLayout();
layout.numColumns = 1;
sashForm.setLayout(layout);
sashForm.setLayoutData(data);
Composite topComposite = new Composite(sashForm, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 1;
topComposite.setLayout(layout);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
topComposite.setLayoutData(data);
data = new GridData(SWT.FILL, SWT.FILL, true, false);
ScrolledComposite scrolledComposite = new ScrolledComposite(topComposite,SWT.H_SCROLL| SWT.V_SCROLL);
scrolledComposite.setLayoutData(data);
GridLayout gridLayout = new GridLayout();
scrolledComposite.setLayout(gridLayout);
scrolledComposite.setMinWidth(400);
scrolledComposite.setMinHeight(40);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);
data = new GridData(SWT.FILL, SWT.FILL, true, false);
statsPanel = new StatisticsPanel(scrolledComposite);
statsPanel.setLayoutData(data);
scrolledComposite.setContent(statsPanel);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
Composite subPanel = new Composite(topComposite, SWT.NONE);
subPanel.setLayoutData(data);
GridLayout fl = new GridLayout();
subPanel.setLayout(fl);
resultsContainer_ = new CTabFolder(subPanel, SWT.NONE);
resultsContainer_.setBorderVisible(true);
resultsContainer_.setSimple(false);
resultsContainer_.setUnselectedCloseVisible(true);
resultsContainer_.setUnselectedImageVisible(true);
// resultsContainer_.addControlListener(new
// ResultsTabFolderResizeHandler(this));
resultsContainer_
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
fl = new GridLayout();
resultsContainer_.setLayout(fl);
addDummyTabs();
subPanel.layout();
// subPanel.pack();
{
Group group = new Group(sashForm, SWT.SHADOW_ETCHED_IN);
group.setText("CQ Console");
group.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, true));
GridLayout lytGrpDisc = new GridLayout();
lytGrpDisc.numColumns = 1;
group.setLayout(lytGrpDisc);
exceptions = new Text(group, SWT.MULTI | SWT.READ_ONLY | SWT.LEFT
| SWT.BORDER | SWT.V_SCROLL);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
exceptions.setLayoutData(data);
}
sashForm.setWeights(new int[]{80,20});
this.layout();
this.pack();
}
private void addDummyTabs() {
int iStyle = SWT.NONE;
iStyle |= SWT.BORDER;
CTabItem ti = new CTabItem(resultsContainer_, iStyle, 0);
ti.setText("Results");
ti.setControl(getDummyTable());
resultsContainer_.setSelection(0);
}
private Composite getDummyTable() {
Composite tableComp = new Composite(resultsContainer_, SWT.NONE);
GridLayout layout = new GridLayout();
tableComp.setLayout(layout);
tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
TableViewer viewer = new TableViewer(tableComp, SWT.SINGLE
| SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL);
TableLayout lytTable = new TableLayout();
for (int i = 0; i < 2; i++) {
lytTable.addColumnData(new ColumnPixelData(WIDTH, true));
}
viewer.getTable().setLayout(lytTable);
viewer.getTable().setHeaderVisible(true);
viewer.getTable().setLinesVisible(true);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
viewer.getTable().setLayoutData(gd);
String colName = "Key";
TableColumn col = new TableColumn(viewer.getTable(), SWT.NONE, 0);
col.setText(colName);
col.setResizable(true);
colName = "Value";
col = new TableColumn(viewer.getTable(), SWT.NONE, 1);
col.setText(colName);
col.setResizable(true);
return tableComp;
}
public void setQuery(CQQuery qry) {
disposeOldResults();
addDummyTabs();
query = qry;
}
private void disposeOldResults() {
CTabItem[] items = resultsContainer_.getItems();
for (int i = 0; i < items.length; i++) {
items[i].getControl().dispose();
items[i].dispose();
}
if (tblResults_ != null) {
tblResults_.clear();
tblResults_ = null;
}
if (exceptions != null && !exceptions.isDisposed()) {
exceptions.setText("");
}
}
public void close() {
}
public void processCqEvent(ICQEvent cqEvent) {
if (cqEvent instanceof ErrorEvent) {
if (cqEvent.getThrowable() != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
cqEvent.getThrowable().printStackTrace(pw);
exceptions.append(sw.toString());
try {
pw.close();
sw.close();
} catch (IOException e) {
}
}
} else {
if (tblResults_ != null) {
for (int i = 0; i < tblResults_.size(); i++) {
TableViewer tableViewer = tblResults_.get(i);
synchronized (tableViewer) {
CQueryResultsInput input = (CQueryResultsInput) tableViewer
.getInput();
if( null != input ) {
input.processEvent(cqEvent);
}
}
}
}
}
statsPanel.update(query.getStatistics());
}
public void processNewTypeEvent(final IntrospectionResult result) {
if (tblResults_ == null)
disposeOldResults();
int iStyle = SWT.NONE;
iStyle |= SWT.BORDER;
int index = resultsContainer_.getItemCount();
// TODO FINDBUG MGH - false positive reported 'Dead store to local variable' on ti
CTabItem ti = new CTabItem(resultsContainer_, iStyle, index++);
CQDataTab dataTab = new CQDataTab(resultsContainer_, result);
dataTab.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
ti.setText(result.getJavaTypeName());
ti.setControl(dataTab);
CQResultsPanel.this.resultsContainer_.setSelection(0);
}
static private class ResultsTabFolderResizeHandler implements ControlListener {
CQResultsPanel parent_;
ResultsTabFolderResizeHandler(CQResultsPanel p) {
parent_ = p;
}
public void controlMoved(ControlEvent e) {
}
public void controlResized(ControlEvent e) {
Rectangle rcClntArea = parent_.getClientArea();
int clntWd = rcClntArea.width;
int clntHt = rcClntArea.height;
if (e.widget == parent_.resultsContainer_) {
parent_.resultsContainer_.setBounds(0, 0, clntWd, clntHt);
}
}
}
private static class StatisticsPanel extends Composite {
private Label numEvents;
private Label numInserts;
private Label numUpdates;
private Label numDeletes;
public StatisticsPanel(Composite parent) {
super(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 4;
layout.makeColumnsEqualWidth = false;
this.setLayout(layout);
Label temp = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
temp.setText("Number of Events :");
GridData gridData = new GridData(SWT.BEGINNING, SWT.FILL, false, false);
temp.setLayoutData(gridData);
numEvents = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
numEvents.setText("");
numEvents.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
temp = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
temp.setText("Number of Inserts : ");
temp.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));
numInserts = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
numInserts.setText("");
numInserts.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
temp = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
temp.setText("Number of Updates : ");
temp.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));
numUpdates = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
numUpdates.setText("");
numUpdates.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
temp = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
temp.setText("Number of Deletes : ");
temp.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));
numDeletes = new Label(this, SWT.HORIZONTAL | SWT.LEFT);
numDeletes.setText("");
numDeletes.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
this.layout();
// this.pack();
}
public void update(CqStatistics statistics) {
numEvents.setText(String.valueOf(statistics.numEvents()));
numInserts.setText(String.valueOf(statistics.numInserts()));
numUpdates.setText(String.valueOf(statistics.numUpdates()));
numDeletes.setText(String.valueOf(statistics.numDeletes()));
}
}
private class CQDataTab extends Composite {
private Combo columnSelection;
private TableViewer dataTable;
public CQDataTab(Composite parent, final IntrospectionResult metaInfo) {
super(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
this.setLayout(layout);
columnSelection = new Combo(this, SWT.DROP_DOWN);
columnSelection.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING,
false, false));
// TODO MGH - make this 'un-anonymous'
columnSelection.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
int index = columnSelection.getSelectionIndex();
int colIndex;
if (index == 0) {
colIndex = CQueryResultsInput.NO_PRIMARY_COL_SELECTED;
} else {
colIndex = index - 1;
}
CQueryResultsInput currentInput = (CQueryResultsInput) dataTable
.getInput();
if (currentInput.getPrimaryColIndex() != colIndex) {
CQueryResultsInput newInput = new CQueryResultsInput(dataTable,
query.getQueryResult(), metaInfo, colIndex);
synchronized (dataTable) {
dataTable.setInput(newInput);
}
Set<Object> keys = query.getQueryResult().getKeys();
Iterator<Object> iter = keys.iterator();
while (iter.hasNext()) {
Object key = iter.next();
EventData value = query.getQueryResult().getValueForKey(key);
if (value != null) {
newInput.processEvent(new RowAdded(value));
}
}
}
}
});
// Add data in Combo.
columnSelection.add("None");
int columnCount = metaInfo.getColumnCount();
for (int i = 0; i < columnCount; i++) {
try {
columnSelection.add(metaInfo.getColumnName(i));
} catch (ColumnNotFoundException e) {
LogUtil.error("Exception when adding column names in CQDataTab()", e );
}
}
columnSelection.select(0);
// Add columns in the table.
dataTable = new TableViewer(this, SWT.SINGLE | SWT.FULL_SELECTION
| SWT.H_SCROLL | SWT.V_SCROLL);
dataTable.getTable().setLayoutData(
new GridData(SWT.FILL, SWT.FILL, true, true));
TableLayout lytTable = new TableLayout();
columnCount = metaInfo.getColumnCount();
for (int i = 0; i < columnCount; i++) {
lytTable.addColumnData(new ColumnPixelData(WIDTH, true));
}
dataTable.getTable().setLayout(lytTable);
dataTable.getTable().setHeaderVisible(true);
dataTable.getTable().setLinesVisible(true);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
dataTable.getTable().setLayoutData(gd);
for (int i = 0; i < columnCount; i++) {
try {
String colName = metaInfo.getColumnName(i);
TableColumn col = new TableColumn(dataTable.getTable(), SWT.NONE, i);
col.setText(colName);
col.setResizable(true);
} catch (ColumnNotFoundException e) {
LogUtil.error( "Exception when adding column in CQDataTab()", e );
continue;
}
}
CQTableContentProvider prov = new CQTableContentProvider(dataTable);
dataTable.setContentProvider(prov);
dataTable.setLabelProvider(new ResultTableLabelProvider(dataTable));
CQueryResultsInput queryResultsInput = new CQueryResultsInput(dataTable,
query.getQueryResult(), metaInfo, -1);
dataTable.setInput(queryResultsInput);
ExploreAction exploreAction = new ExploreAction(this.getShell(), dataTable);
MenuManager manager = new MenuManager();
dataTable.getTable().setMenu(manager.createContextMenu(dataTable.getTable()));
manager.add(exploreAction);
if (tblResults_ == null)
tblResults_ = new ArrayList<TableViewer>();
tblResults_.add(dataTable);
}
}
public static class CQTableContentProvider implements IStructuredContentProvider {
private TableViewer viewer;
public CQTableContentProvider(TableViewer vwr) {
super();
viewer = vwr;
}
public Object[] getElements(Object inputElement) {
return new Object[0];
}
public void dispose() {
CQueryResultsInput input = (CQueryResultsInput) viewer.getInput();
input.dispose();
}
public void inputChanged(Viewer vwr, Object oldInput, Object newInput) {
}
}
private static class ResultTableLabelProvider implements ITableLabelProvider {
private TableViewer viewer_;
ResultTableLabelProvider(TableViewer viewer) {
viewer_ = viewer;
}
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
String res = "";
if (element == null)
return res;
EventData data = (EventData) element;
Object value = data.getValue();
CQueryResultsInput input = (CQueryResultsInput) viewer_.getInput();
try {
Object columnValue = input.getColumnValue(value, columnIndex);
if (columnValue != null)
res = columnValue.toString();
} catch (ColumnNotFoundException e) {
return "N/A";
} catch (ColumnValueNotAvailableException e) {
return "N/A";
}
return res;
}
public void addListener(ILabelProviderListener listener) {
}
public void dispose() {
}
public boolean isLabelProperty(Object element, String property) {
return false;
}
public void removeListener(ILabelProviderListener listener) {
}
}
}