| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.hdt.ui.views; |
| |
| import java.util.Collection; |
| |
| import org.apache.hdt.core.cluster.HadoopCluster; |
| import org.apache.hdt.core.cluster.HadoopJob; |
| import org.apache.hdt.core.cluster.IJobListener; |
| import org.apache.hdt.core.cluster.utils.JarModule; |
| import org.apache.hdt.ui.ImageLibrary; |
| import org.apache.hdt.ui.actions.EditLocationAction; |
| import org.apache.hdt.ui.actions.NewLocationAction; |
| import org.apache.hdt.ui.cluster.IHadoopClusterListener; |
| import org.apache.hdt.ui.cluster.ServerRegistry; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuListener; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.ILabelProviderListener; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.ITreeSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.swt.widgets.TreeColumn; |
| import org.eclipse.ui.IViewSite; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.actions.ActionFactory; |
| import org.eclipse.ui.part.ViewPart; |
| |
| /** |
| * Map/Reduce locations view: displays all available Hadoop locations and the |
| * Jobs running/finished on these locations |
| */ |
| public class ClusterView extends ViewPart implements ITreeContentProvider, |
| ITableLabelProvider, IJobListener, IHadoopClusterListener { |
| |
| /** |
| * Deletion action: delete a Hadoop location, kill a running job or remove |
| * a finished job entry |
| */ |
| class DeleteAction extends Action { |
| |
| DeleteAction() { |
| setText("Delete"); |
| setImageDescriptor(ImageLibrary.get("server.view.action.delete")); |
| } |
| |
| /* @inheritDoc */ |
| @Override |
| public void run() { |
| ISelection selection = |
| getViewSite().getSelectionProvider().getSelection(); |
| if ((selection != null) && (selection instanceof IStructuredSelection)) { |
| Object selItem = |
| ((IStructuredSelection) selection).getFirstElement(); |
| |
| if (selItem instanceof HadoopCluster) { |
| HadoopCluster location = (HadoopCluster) selItem; |
| if (MessageDialog.openConfirm(Display.getDefault() |
| .getActiveShell(), "Confirm delete Hadoop location", |
| "Do you really want to remove the Hadoop location: " |
| + location.getLocationName())) { |
| ServerRegistry.getInstance().removeServer(location); |
| } |
| |
| } else if (selItem instanceof HadoopJob) { |
| |
| // kill the job |
| HadoopJob job = (HadoopJob) selItem; |
| if (job.isCompleted()) { |
| // Job already finished, remove the entry |
| job.getLocation().purgeJob(job); |
| |
| } else { |
| // Job is running, kill the job? |
| if (MessageDialog.openConfirm(Display.getDefault() |
| .getActiveShell(), "Confirm kill running Job", |
| "Do you really want to kill running Job: " + job.getJobID())) { |
| job.kill(); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * This object is the root content for this content provider |
| */ |
| private static final Object CONTENT_ROOT = new Object(); |
| |
| private final IAction deleteAction = new DeleteAction(); |
| |
| private final IAction editServerAction = new EditLocationAction(this); |
| |
| private final IAction newLocationAction = new NewLocationAction(); |
| |
| private TreeViewer viewer; |
| |
| public ClusterView() { |
| } |
| |
| /* @inheritDoc */ |
| @Override |
| public void init(IViewSite site) throws PartInitException { |
| super.init(site); |
| } |
| |
| /* @inheritDoc */ |
| @Override |
| public void dispose() { |
| ServerRegistry.getInstance().removeListener(this); |
| } |
| |
| /** |
| * Creates the columns for the view |
| */ |
| @Override |
| public void createPartControl(Composite parent) { |
| Tree main = |
| new Tree(parent, SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL |
| | SWT.V_SCROLL); |
| main.setHeaderVisible(true); |
| main.setLinesVisible(false); |
| main.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| |
| TreeColumn serverCol = new TreeColumn(main, SWT.SINGLE); |
| serverCol.setText("Location"); |
| serverCol.setWidth(300); |
| serverCol.setResizable(true); |
| |
| TreeColumn locationCol = new TreeColumn(main, SWT.SINGLE); |
| locationCol.setText("Master node"); |
| locationCol.setWidth(185); |
| locationCol.setResizable(true); |
| |
| TreeColumn stateCol = new TreeColumn(main, SWT.SINGLE); |
| stateCol.setText("State"); |
| stateCol.setWidth(95); |
| stateCol.setResizable(true); |
| |
| TreeColumn statusCol = new TreeColumn(main, SWT.SINGLE); |
| statusCol.setText("Status"); |
| statusCol.setWidth(300); |
| statusCol.setResizable(true); |
| |
| viewer = new TreeViewer(main); |
| viewer.setContentProvider(this); |
| viewer.setLabelProvider(this); |
| viewer.setInput(CONTENT_ROOT); // don't care |
| |
| getViewSite().setSelectionProvider(viewer); |
| |
| getViewSite().getActionBars().setGlobalActionHandler( |
| ActionFactory.DELETE.getId(), deleteAction); |
| getViewSite().getActionBars().getToolBarManager().add(editServerAction); |
| getViewSite().getActionBars().getToolBarManager().add(newLocationAction); |
| |
| createActions(); |
| createContextMenu(); |
| } |
| |
| /** |
| * Actions |
| */ |
| private void createActions() { |
| /* |
| * addItemAction = new Action("Add...") { public void run() { addItem(); } }; |
| * addItemAction.setImageDescriptor(ImageLibrary |
| * .get("server.view.location.new")); |
| */ |
| /* |
| * deleteItemAction = new Action("Delete") { public void run() { |
| * deleteItem(); } }; |
| * deleteItemAction.setImageDescriptor(getImageDescriptor("delete.gif")); |
| * |
| * selectAllAction = new Action("Select All") { public void run() { |
| * selectAll(); } }; |
| */ |
| // Add selection listener. |
| viewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| updateActionEnablement(); |
| } |
| }); |
| } |
| |
| private void addItem() { |
| System.out.printf("ADD ITEM\n"); |
| } |
| |
| private void updateActionEnablement() { |
| IStructuredSelection sel = (IStructuredSelection) viewer.getSelection(); |
| // deleteItemAction.setEnabled(sel.size() > 0); |
| } |
| |
| /** |
| * Contextual menu |
| */ |
| private void createContextMenu() { |
| // Create menu manager. |
| MenuManager menuMgr = new MenuManager(); |
| menuMgr.setRemoveAllWhenShown(true); |
| menuMgr.addMenuListener(new IMenuListener() { |
| public void menuAboutToShow(IMenuManager mgr) { |
| fillContextMenu(mgr); |
| } |
| }); |
| |
| // Create menu. |
| Menu menu = menuMgr.createContextMenu(viewer.getControl()); |
| viewer.getControl().setMenu(menu); |
| |
| // Register menu for extension. |
| getSite().registerContextMenu(menuMgr, viewer); |
| } |
| |
| private void fillContextMenu(IMenuManager mgr) { |
| mgr.add(newLocationAction); |
| mgr.add(editServerAction); |
| mgr.add(deleteAction); |
| /* |
| * mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); |
| * mgr.add(deleteItemAction); mgr.add(new Separator()); |
| * mgr.add(selectAllAction); |
| */ |
| } |
| |
| /* @inheritDoc */ |
| @Override |
| public void setFocus() { |
| |
| } |
| |
| /* |
| * IHadoopServerListener implementation |
| */ |
| |
| /* @inheritDoc */ |
| public void serverChanged(HadoopCluster location, int type) { |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| ClusterView.this.viewer.refresh(); |
| } |
| }); |
| } |
| |
| /* |
| * IStructuredContentProvider implementation |
| */ |
| |
| /* @inheritDoc */ |
| public void inputChanged(final Viewer viewer, Object oldInput, |
| Object newInput) { |
| if (oldInput == CONTENT_ROOT) |
| ServerRegistry.getInstance().removeListener(this); |
| if (newInput == CONTENT_ROOT) |
| ServerRegistry.getInstance().addListener(this); |
| } |
| |
| /** |
| * The root elements displayed by this view are the existing Hadoop |
| * locations |
| */ |
| /* @inheritDoc */ |
| public Object[] getElements(Object inputElement) { |
| return ServerRegistry.getInstance().getServers().toArray(); |
| } |
| |
| /* |
| * ITreeStructuredContentProvider implementation |
| */ |
| |
| /** |
| * Each location contains a child entry for each job it runs. |
| */ |
| /* @inheritDoc */ |
| public Object[] getChildren(Object parent) { |
| |
| if (parent instanceof HadoopCluster) { |
| HadoopCluster location = (HadoopCluster) parent; |
| location.addJobListener(this); |
| Collection<HadoopJob> jobs = location.getJobs(); |
| return jobs.toArray(); |
| } |
| |
| return null; |
| } |
| |
| /* @inheritDoc */ |
| public Object getParent(Object element) { |
| if (element instanceof HadoopCluster) { |
| return CONTENT_ROOT; |
| |
| } else if (element instanceof HadoopJob) { |
| return ((HadoopJob) element).getLocation(); |
| } |
| |
| return null; |
| } |
| |
| /* @inheritDoc */ |
| public boolean hasChildren(Object element) { |
| /* Only server entries have children */ |
| return (element instanceof HadoopCluster); |
| } |
| |
| /* |
| * ITableLabelProvider implementation |
| */ |
| |
| /* @inheritDoc */ |
| public void addListener(ILabelProviderListener listener) { |
| // no listeners handling |
| } |
| |
| public boolean isLabelProperty(Object element, String property) { |
| return false; |
| } |
| |
| /* @inheritDoc */ |
| public void removeListener(ILabelProviderListener listener) { |
| // no listener handling |
| } |
| |
| /* @inheritDoc */ |
| public Image getColumnImage(Object element, int columnIndex) { |
| if ((columnIndex == 0) && (element instanceof HadoopCluster)) { |
| return ImageLibrary.getImage("server.view.location.entry"); |
| |
| } else if ((columnIndex == 0) && (element instanceof HadoopJob)) { |
| return ImageLibrary.getImage("server.view.job.entry"); |
| } |
| return null; |
| } |
| |
| /* @inheritDoc */ |
| public String getColumnText(Object element, int columnIndex) { |
| if (element instanceof HadoopCluster) { |
| HadoopCluster server = (HadoopCluster) element; |
| |
| switch (columnIndex) { |
| case 0: |
| return server.getLocationName(); |
| case 1: |
| return server.getMasterHostName().toString(); |
| case 2: |
| return server.getState(); |
| case 3: |
| return ""; |
| } |
| } else if (element instanceof HadoopJob) { |
| HadoopJob job = (HadoopJob) element; |
| |
| switch (columnIndex) { |
| case 0: |
| return job.getJobID().toString(); |
| case 1: |
| return ""; |
| case 2: |
| return job.getState().toString(); |
| case 3: |
| return job.getStatus(); |
| } |
| } else if (element instanceof JarModule) { |
| JarModule jar = (JarModule) element; |
| |
| switch (columnIndex) { |
| case 0: |
| return jar.toString(); |
| case 1: |
| return "Publishing jar to server.."; |
| case 2: |
| return ""; |
| } |
| } |
| |
| return null; |
| } |
| |
| /* |
| * IJobListener (Map/Reduce Jobs listener) implementation |
| */ |
| |
| /* @inheritDoc */ |
| public void jobAdded(HadoopJob job) { |
| viewer.refresh(); |
| } |
| |
| /* @inheritDoc */ |
| public void jobRemoved(HadoopJob job) { |
| viewer.refresh(); |
| } |
| |
| /* @inheritDoc */ |
| public void jobChanged(HadoopJob job) { |
| viewer.refresh(job); |
| } |
| |
| /* @inheritDoc */ |
| public void publishDone(JarModule jar) { |
| viewer.refresh(); |
| } |
| |
| /* @inheritDoc */ |
| public void publishStart(JarModule jar) { |
| viewer.refresh(); |
| } |
| |
| /* |
| * Miscellaneous |
| */ |
| |
| /** |
| * Return the currently selected server (null if there is no selection or |
| * if the selection is not a server) |
| * |
| * @return the currently selected server entry |
| */ |
| public HadoopCluster getSelectedServer() { |
| ITreeSelection selection = (ITreeSelection) viewer.getSelection(); |
| Object first = selection.getFirstElement(); |
| if (first instanceof HadoopCluster) { |
| return (HadoopCluster) first; |
| } |
| return null; |
| } |
| |
| } |