package com.gorillalogic.monkeyconsole.cloudview.ui; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.gorillalogic.cloud.ideversion.CloudConstants; import com.gorillalogic.cloud.ideversion.Message; import com.gorillalogic.monkeyconsole.editors.utils.CloudServiceException; import com.gorillalogic.monkeyconsole.editors.utils.CloudServices; import com.gorillalogic.monkeyconsole.editors.utils.MonkeyTalkImagesEnum; import com.gorillalogic.monkeyconsole.editors.utils.MonkeyTalkUtils; import com.gorillalogic.monkeyconsole.plugin.FoneMonkeyPlugin; import com.gorillalogic.monkeyconsole.preferences.PreferenceConstants; /** * Insert the type's description here. * * @see ViewPart */ @SuppressWarnings("restriction") public class UICloudView extends ViewPart { TableViewer tableViewer; protected Text text; protected UICloudLableProvider labelProvider; protected JobRow root; public final int JOB_LIST_PAUSE_TIME = 5000; // milliseconds protected Thread tableRefreshThread = null; /** * The constructor. */ public UICloudView() { startTableRefreshThread(5000); } private TableViewerColumn createTableViewerColumn(String title, int bound, final int colNumber) { final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE); final TableColumn column = viewerColumn.getColumn(); column.setText(title); column.setWidth(bound); column.setResizable(true); return viewerColumn; } /* * @see IWorkbenchPart#createPartControl(Composite) */ public void createPartControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(1, false)); // Add the TableViewer tableViewer = new TableViewer(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); tableViewer.setContentProvider(new UICloudContentProvider()); // tableViewer.setInput(this.getInitalInput()); // ---- don't do this in UI thread, let // RefreshThread take care of it. Table table = tableViewer.getTable(); table.setLayoutData(new GridData(GridData.FILL_BOTH)); TableColumnLayout layoutt = new TableColumnLayout(); composite.setLayout(layoutt); // / TableViewerColumn idColumn = this.createTableViewerColumn("ID", 15, 0); idColumn.setLabelProvider(new CloudLableProviderID(tableViewer.getTable())); layoutt.setColumnData(idColumn.getColumn(), new ColumnWeightData(5)); TableViewerColumn jobNamColumn = this.createTableViewerColumn("Job Name", 100, 1); jobNamColumn.setLabelProvider(new CloudLableProviderJobName(tableViewer.getTable())); layoutt.setColumnData(jobNamColumn.getColumn(), new ColumnWeightData(30)); TableViewerColumn startDateColumn = this.createTableViewerColumn("Submitted", 300, 2); startDateColumn.setLabelProvider(new CloudLableProviderStartDate(tableViewer.getTable())); layoutt.setColumnData(startDateColumn.getColumn(), new ColumnWeightData(20)); TableViewerColumn statusColumn = this.createTableViewerColumn("Status", 100, 3); statusColumn.setLabelProvider(new CloudLableProviderStatus(tableViewer.getTable())); layoutt.setColumnData(statusColumn.getColumn(), new ColumnWeightData(10)); TableViewerColumn messageColumn = this.createTableViewerColumn("Message", 100, 3); messageColumn.setLabelProvider(new CloudLableProviderMessage(tableViewer.getTable())); layoutt.setColumnData(messageColumn.getColumn(), new ColumnWeightData(50)); // TableViewerColumn linkColumn = this.createTableViewerColumn("Actions", 100, 4); // linkColumn.setLabelProvider( new ActionLabelProvider( tableViewer.getTable() )); // linkColumn.getColumn().addListener(SWT.Selection, new Listener() { // public void handleEvent(Event event) { // System.out.println("You have selected: "+event.text); // } // }); // layoutt.setColumnData(linkColumn.getColumn(), new ColumnWeightData(20)); tableViewer.getTable().setHeaderVisible(true); tableViewer.getTable().setLinesVisible(true); // Create menu, toolbars, filters, sorters. createActions(); createMenus(); createToolbar(); hookListeners(); } /* * @see IWorkbenchPart#dispose() */ public void dispose() { System.out.println("UICloudView: stopping job status refresh thread"); this.stopTableRefreshThread(); super.dispose(); } protected boolean isError(JSONObject jo, boolean showMessageToUser) { try { if (jo.getString("message").equalsIgnoreCase(Message.ERROR)) { if (!showMessageToUser) return true; MessageBox dialog2 = new MessageBox(getSite().getShell(), SWT.ICON_ERROR | SWT.OK); dialog2.setText("Cloud Service"); try { dialog2.setMessage(jo.getString("data")); } catch (JSONException e1) { e1.printStackTrace(); } dialog2.open(); return true; } } catch (JSONException e2) { return true; } return false; } protected void hookListeners() { tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { // if the selection is empty clear the label if (event.getSelection().isEmpty()) { // text.setText(""); return; } if (event.getSelection() instanceof IStructuredSelection) { IStructuredSelection selection = (IStructuredSelection) event.getSelection(); for (Iterator<?> iterator = selection.iterator(); iterator.hasNext();) { JobRow domain = (JobRow) iterator.next(); try { String name = "Job " + domain.getId(); if (!domain.getStatus().equalsIgnoreCase("done")) { MonkeyTalkUtils.openBrowser( name, "http://" + CloudServices.getControllerHost() + ":" + CloudServices.getControllerPort() + CloudConstants.JOB_STATUS + "?username=" + FoneMonkeyPlugin.getDefault() .getPreferenceStore() .getString(PreferenceConstants.P_CLOUDUSR) + "&token=" + CloudServices.getToken() + "&id=" + domain.getId(), UICloudView.this.getSite()); } else { JSONObject jo = CloudServices.getJobResults("" + domain.getId()); if (!isError(jo, true)) { MonkeyTalkUtils.openBrowser(name, jo.getJSONObject("data") .getString("summary"), UICloudView.this.getSite()); } } } catch (PartInitException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } catch (CloudServiceException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }); } Action refreshButton = null; protected void createActions() { refreshButton = new Action() { @SuppressWarnings("deprecation") public void run() { long start = System.currentTimeMillis(); try { refreshButton.setEnabled(false); if (tableRefreshThread.isAlive()) { tableRefreshThread.interrupt(); } try { tableRefreshThread.join(5000L); } catch (InterruptedException e) { return; } if (tableRefreshThread.isAlive()) { System.out.println("cannot stop tableRefreshThread, killing it..."); tableRefreshThread.stop(); } System.out.println(new Date() + " UICloudView: refreshButton.run(): restarting tableRefreshThread" + (System.currentTimeMillis() - start) + "ms"); startTableRefreshThread(0); } finally { refreshButton.setEnabled(true); } } }; refreshButton.setText("Refresh"); refreshButton.setToolTipText("Refresh all items in this list"); refreshButton.setImageDescriptor(MonkeyTalkImagesEnum.REFRESH.image); refreshButton.setId("refresh"); } protected void createMenus() { IMenuManager rootMenuManager = getViewSite().getActionBars().getMenuManager(); rootMenuManager.setRemoveAllWhenShown(true); } protected void createToolbar() { IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager(); toolbarManager.add(refreshButton); } private void startTableRefreshThread(long pauseBeforeStarting) { if (pauseBeforeStarting > 0) { try { Thread.sleep(pauseBeforeStarting); } catch (InterruptedException e) { return; } } tableRefreshThread = new Thread(new Runnable() { public void run() { while (true) { final List<JobRow> data = getInitalInput(); if (Thread.currentThread().isInterrupted()) { break; } Display.getDefault().asyncExec(new Runnable() { public void run() { try { tableViewer.setInput(data); tableViewer.refresh(); } catch (Exception e) { e.printStackTrace(); } } }); // System.out.println(new Date() // + " UICloudView: tableRefresh.run() completed, elapsed=" // + (System.currentTimeMillis() - start) + "ms"); if (Thread.currentThread().isInterrupted()) { break; } try { Thread.sleep(JOB_LIST_PAUSE_TIME); } catch (InterruptedException e) { break; } } } }); tableRefreshThread.start(); } private void stopTableRefreshThread() { tableRefreshThread.interrupt(); } public List<JobRow> getInitalInput() { JSONObject jo = new JSONObject(); try { jo = CloudServices.getJobHistory(); } catch (CloudServiceException cse) { try { jo.put("message", "error"); jo.put("data", cse.getMessage()); } catch (JSONException e) { e.printStackTrace(); } } if (Thread.currentThread().isInterrupted()) { return null; } List<JobRow> jobs = new ArrayList<JobRow>(); if (jo == null || isError(jo, false)) { try { if (jo.has("data")) jobs.add(new JobRow(1, "error", new Date(), jo.getString("data"), " view the monkey talk prefs to set username and pass", "")); else jobs.add(new JobRow(1, "error", new Date(), "Unable to Connect", " Can not connect to the cloud.gorillalogic.com servers", "")); } catch (JSONException e) { e.printStackTrace(); } return jobs; } try { JSONArray ja = jo.getJSONObject("data").getJSONArray("jobs"); for (int i = 0; i < ja.length(); i++) { JSONObject joo = ja.getJSONObject(i); String jobName = joo.getString("name"); if (jobName == null || jobName.equalsIgnoreCase("null")) { jobName = "Job " + joo.getInt("id"); } String jobMessage = createJobMessage(joo); jobs.add(new JobRow(joo.getInt("id"), jobName, new Date(joo.getLong("created")), joo.getString("status"), jobMessage, "view")); } return jobs; } catch (JSONException e) { return new ArrayList<JobRow>(); } catch (CloudServiceException e) { return new ArrayList<JobRow>(); } } protected String createJobMessage(JSONObject job) throws JSONException, CloudServiceException { String jobMessage = job.getString("msg"); if (jobMessage != null && jobMessage.length() > 0 && !jobMessage.equals("null")) { return jobMessage; } String jobStatus = job.getString("status"); if (jobStatus == null || jobStatus.length() == 0 || jobStatus.equals("done")) { return ""; } // check for cancel if (Thread.currentThread().isInterrupted()) { return ""; } StringBuilder sb = new StringBuilder(); job = CloudServices.getJobStatus(job.getString("id")); JSONArray tasks; try { job = job.getJSONObject("data"); tasks = job.getJSONArray("tasks"); } catch (JSONException e) { return ""; } int depth = 0; if (tasks != null && tasks.length() > 0) { SortedMap<String, List<JSONObject>> taskStatusCounters = new TreeMap<String, List<JSONObject>>(); for (int i = 0; i < tasks.length(); i++) { JSONObject task = tasks.getJSONObject(i); String taskStatus = task.getString("status"); List<JSONObject> taskList = taskStatusCounters.get(taskStatus); if (taskList == null) { taskList = new ArrayList<JSONObject>(); taskStatusCounters.put(taskStatus, taskList); } taskList.add(task); if (task.has("queueDepth")) { int d = task.getInt("queueDepth"); if (depth < d) { depth = d; } } } String depthMsg = (depth > 0 ? " (" + depth + " task" + (depth == 1 ? "" : "s") + " ahead of you)" : ""); for (String taskStatus : taskStatusCounters.keySet()) { if (taskStatus.equals("queued")) { sb.append(taskStatusCounters.get(taskStatus).size() + " " + taskStatus + depthMsg + ", "); } else { sb.append(taskStatusCounters.get(taskStatus).size() + " " + taskStatus + ", "); } } sb.setLength(sb.length() - 2); } return sb.toString(); } /* * @see IWorkbenchPart#setFocus() */ public void setFocus() { } }