package net.helipilot50.aerospike.views;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.citrusleaf.CitrusleafInfo;
import net.helipilot50.aerospike.Activator;
import net.helipilot50.aerospike.model.ClusterCoordinates;
import net.helipilot50.aerospike.model.NameValuePair;
import net.helipilot50.aerospike.wizards.NewDBCoordinatesWizard;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;
/**
* This sample class demonstrates how to plug-in a new
* workbench view. The view shows data obtained from the
* model. The sample creates a dummy model on the fly,
* but a real implementation would connect to the model
* available either in this or another plug-in (e.g. the workspace).
* The view is connected to the model using a content provider.
* <p>
* The view uses a label provider to define how model
* objects should be presented in the view. Each
* view can present the same model objects using
* different labels and icons, if needed. Alternatively,
* a single label provider can be shared between views
* in order to ensure that objects of the same type are
* presented in the same way everywhere.
* <p>
*/
public class DataBaseView extends ViewPart {
/**
* The ID of the view as specified by the extension.
*/
public static final String ID = "net.helipilot50.aerospike.views.DataBaseView";
private TableViewer viewer;
private Action addAction;
private Action refreshAction;
private Action dbCoordinates;
private Action doubleClickAction;
private ClusterCoordinates currentDB;
private IProject dbProject;
private TreeViewer serverTreeViewer;
private SashForm sashForm;
private int[] childWeights;
/*
* The content provider class is responsible for
* providing objects to the view. It can wrap
* existing objects in adapters or simply return
* objects as-is. These objects may be sensitive
* to the current input of the view, or ignore
* it and always show the same content
* (like Task List, for example).
*/
class ViewContentProvider implements IStructuredContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
}
public void dispose() {
}
public Object[] getElements(Object parent) {
if (currentDB != null && currentDB.getStats() != null){
return currentDB.getStats().toArray();
} else {
return new NameValuePair[0];
}
}
}
class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
public String getColumnText(Object obj, int index) {
if (obj instanceof NameValuePair){
switch (index){
case 0:
return ((NameValuePair)obj).name;
case 1:
return (((NameValuePair)obj).value != null) ? ((NameValuePair)obj).value.toString() : "";
default:
return obj.toString();
}
} else {
return obj.toString();
}
}
public Image getColumnImage(Object obj, int index) {
if (index == 0)
return getImage(obj);
else
return null;
}
public Image getImage(Object obj) {
// return PlatformUI.getWorkbench().
// getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
NameValuePair item = (NameValuePair)obj;
if (item.getName().equalsIgnoreCase("services")){
return Activator.getImage("icons/service.gif");
} else if (item.getName().equalsIgnoreCase("partition-generation")){
return Activator.getImage("icons/partition.gif");
} else {
return null;
}
}
}
class NameSorter extends ViewerSorter {
}
/**
* The constructor.
*/
public DataBaseView() {
}
/**
* This is a callback that will allow us
* to create the viewer and initialize it.
*/
public void createPartControl(Composite parent) {
sashForm = new SashForm(parent, SWT.NONE);
sashForm.setSashWidth(5);
serverTreeViewer = new TreeViewer(sashForm, SWT.BORDER);
serverTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
ITreeSelection selection = (ITreeSelection) event.getSelection();
ClusterCoordinates coordinates = (ClusterCoordinates) selection.getFirstElement();
currentDB = coordinates;
if (viewer != null && currentDB != null)
viewer.setInput(currentDB.getStats());
}
});
@SuppressWarnings("unused")
Tree tree = serverTreeViewer.getTree();
serverTreeViewer.setLabelProvider(new ServerListLabelProvider());
serverTreeViewer.setContentProvider(new ServerListContentProvider());
viewer = new TableViewer(sashForm, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
Table table = viewer.getTable();
table.setLinesVisible(true);
table.setHeaderVisible(true);
TableColumn nameColumn = new TableColumn(table, SWT.NONE);
nameColumn.setWidth(150);
nameColumn.setText("Name");
TableColumn valueColumn = new TableColumn(table, SWT.NONE);
valueColumn.setWidth(1000);
valueColumn.setText("Value");
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setSorter(new NameSorter());
viewer.setInput(getViewSite());
// Create the help context id for the viewer's control
PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(), "CitrusLeafInfo.viewer");
sashForm.setWeights(new int[] {1, 1});
makeActions();
hookContextMenu();
hookDoubleClickAction();
contributeToActionBars();
if (this.childWeights != null){
this.sashForm.setWeights(this.childWeights);
}
dbProject = Activator.getDBProject();
serverTreeViewer.setInput(dbProject);
// Make the refresh jobs
List<ClusterCoordinates> servers = Activator.getServerList();
for(ClusterCoordinates db : servers){
if (db.isRefresh()){
timeRefresh(db);
}
}
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
DataBaseView.this.fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(serverTreeViewer.getControl());
serverTreeViewer.getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, serverTreeViewer);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(addAction);
manager.add(new Separator());
//manager.add(dbCoordinates);
manager.add(refreshAction);
}
private void fillContextMenu(IMenuManager manager) {
manager.add(addAction);
//manager.add(dbCoordinates);
manager.add(refreshAction);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(addAction);
//manager.add(dbCoordinates);
manager.add(refreshAction);
}
private void makeActions() {
addAction = new Action() {
public void run() {
NewDBCoordinatesWizard wizard = new NewDBCoordinatesWizard();
WizardDialog wd = new WizardDialog(viewer.getControl().getShell(), wizard);
wd.setTitle(wizard.getWindowTitle());
wd.open();
serverTreeViewer.setInput(dbProject);
}
};
addAction.setText("New");
addAction.setToolTipText("New database coordinates");
addAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_ADD));
refreshAction = new Action() {
public void run() {
if (currentDB == null){
viewer.setInput(null);
return;
}
Map<String, String> info = CitrusleafInfo.get(currentDB.getHostName(), currentDB.getPort());
if (info != null){
getDBStats(currentDB);
viewer.setInput(currentDB.getStats());
}
}
};
refreshAction.setText("Refresh");
refreshAction.setToolTipText("Refresh database statistics");
refreshAction.setImageDescriptor(Activator.getImageDescriptor("icons/refresh.gif"));
// dbCoordinates = new Action() {
// public void run() {
// DBCoordinatesDialog dialog = new DBCoordinatesDialog(viewer.getControl().getShell(),
// hostName, port);
// if (dialog.open() == Window.OK){
// hostName = dialog.getHostName();
// port = dialog.getPort();
// }
//
// }
// };
// dbCoordinates.setText("Database coordinates");
// dbCoordinates.setToolTipText("Host name and port for the Database");
// dbCoordinates.setImageDescriptor(Activator.getImageDescriptor("icons/repository.gif"));
doubleClickAction = new Action() {
public void run() {
ISelection selection = serverTreeViewer.getSelection();
ClusterCoordinates obj = (ClusterCoordinates) ((IStructuredSelection)selection).getFirstElement();
NewDBCoordinatesWizard wizard = new NewDBCoordinatesWizard(obj);
WizardDialog wd = new WizardDialog(viewer.getControl().getShell(), wizard);
wd.setTitle(wizard.getWindowTitle());
wd.open();
}
};
}
private void hookDoubleClickAction() {
serverTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
doubleClickAction.run();
}
});
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
@Override
public void saveState(IMemento memento){
if (this.sashForm != null){
int[] childWeights = this.sashForm.getWeights();
memento.putInteger("leftChild", childWeights[0]);
memento.putInteger("rightChild", childWeights[1]);
}
}
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
if (memento == null)
return;
Integer leftValue = memento.getInteger("leftChild");
Integer rightValue = memento.getInteger("rightChild");
if (leftValue != null && rightValue != null) {
childWeights = new int[2];
childWeights[0] = leftValue;
childWeights[1] = rightValue;
}
}
protected void timeRefresh(final ClusterCoordinates target){
if (!target.isRefresh()){
target.setTimerJob(null);
return;
}
Job job = new Job("Update Aerospike DB statistics for "+ target.getName()) {
public IStatus run(IProgressMonitor monitor) {
while(true){
try {
Thread.sleep(target.getRefreshInterval());
if (getDBStats(target)){
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
viewer.setInput(target.getStats());
}
});
}
} catch (InterruptedException e) {
//Dont care;
break;
}
}
return Status.CANCEL_STATUS;
}
};
job.setUser(true);
target.setTimerJob(job);
if (target.isRefresh())
job.schedule();
}
protected boolean getDBStats(ClusterCoordinates target){
if (target == null)
return false;
Map<String, String> info = CitrusleafInfo.get(target.getHostName(), target.getPort());
parseAndUpdate(target, info);
return (info != null);
}
protected void parseAndUpdate(ClusterCoordinates target, Map<String, String> info){
if (info != null){
List<NameValuePair> dbInfo = new ArrayList<NameValuePair>();
String statistics = info.get("statistics");
String part[] = statistics.split(";");
for (String entry : part){
dbInfo.add(new NameValuePair(entry, "="));
}
target.setStats(dbInfo);
}
}
}