package rhogenwizard.editors; import java.io.DataInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.Observable; import java.util.Observer; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.FillLayout; 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.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.progress.UIJob; import rhogenwizard.sdk.task.JobNotificationMonitor; import rhogenwizard.sdk.task.liveupdate.DiscoverTask; import rhogenwizard.sdk.task.liveupdate.LUDevice; import rhogenwizard.sdk.task.liveupdate.LiveUpdateTask; import rhogenwizard.sdk.task.liveupdate.PrintSubnetsTask; /* ---------------------------------------------------------------------- */ class NetworkListener { private String m_networkAddess = null; public NetworkListener(String address) { m_networkAddess = address; } public boolean waitServer() { try { URL url; URLConnection urlConn; DataInputStream dis; url = new URL(m_networkAddess); urlConn = url.openConnection(); urlConn.setDoInput(true); urlConn.setUseCaches(false); dis = new DataInputStream(urlConn.getInputStream()); byte[] data = new byte[100]; dis.read(data); return true; } catch (MalformedURLException mue) { } catch (IOException ioe) { } return false; } } /* ---------------------------------------------------------------------- */ class LiveUpdateObserver extends Observable { public void notifyUi(Object arg) { this.setChanged(); this.notifyObservers(arg); } } /* ---------------------------------------------------------------------- */ class CancelLiveUpdateUIJob extends UIJob { private Button m_enableBtn = null; public CancelLiveUpdateUIJob(Button enableBtn) { super("Update UI"); m_enableBtn = enableBtn; } @Override public IStatus runInUIThread(IProgressMonitor monitor) { Job[] runningJobs = Job.getJobManager().find(null); for (Job job : runningJobs) { if (job.getName().equals(LiveUpdateEditor.liveUpdateJobName)) { job.cancel(); break; } } if (!m_enableBtn.isDisposed()) m_enableBtn.setEnabled(true); return Status.OK_STATUS; } } /* ---------------------------------------------------------------------- */ class CloseEditorUIJob extends UIJob { private IEditorPart m_editor = null; public CloseEditorUIJob(IEditorPart editor) { super("Update UI"); m_editor = editor; } @Override public IStatus runInUIThread(IProgressMonitor monitor) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } m_editor.getEditorSite().getPage().closeEditor(m_editor, false); return Status.OK_STATUS; } } /* ---------------------------------------------------------------------- */ class TableItemUpdateUIJob extends UIJob { private int m_showIndex = 0; private TableItem m_item = null; public TableItemUpdateUIJob(TableItem item, int showIndex) { super("Update UI"); m_showIndex = showIndex; m_item = item; } @Override public IStatus runInUIThread(IProgressMonitor monitor) { if (!m_item.isDisposed()) m_item.setText(1, LiveUpdateEditor.discoverStatus[m_showIndex]); return Status.OK_STATUS; } } /* ---------------------------------------------------------------------- */ class DevicesTableFillUIJob extends UIJob { private Table m_table = null; private IProject m_project = null; public DevicesTableFillUIJob(IProject project, Table table) { super("Update UI"); m_table = table; m_project = project; } @Override public IStatus runInUIThread(IProgressMonitor monitor) { if (m_table.isDisposed()) return Status.OK_STATUS; m_table.removeAll(); IPath path = m_project.getLocation(); path = path.append(LUDevice.configFileName); try { List<LUDevice> devices = LUDevice.load(path); if (devices != null && devices.size() != 0) { for (LUDevice itemDev : devices) { TableItem item = new TableItem(m_table, SWT.NONE); item.setText(0, itemDev.Name); item.setText(1, itemDev.URI); item.setText(2, itemDev.Application); item.setText(3, itemDev.Platfrom); } } } catch (FileNotFoundException e) { e.printStackTrace(); } return Status.OK_STATUS; } } /* ---------------------------------------------------------------------- */ class SearchProgressMonitor implements Runnable { private static final int updateUiSleep = 1000; private TableItem m_item = null; private IProject m_project = null; private String m_subnetMask = null; public SearchProgressMonitor(IProject project, String subnetMask, TableItem item) { m_item = item; m_project = project; m_subnetMask = subnetMask; } @Override public void run() { try { new TableItemUpdateUIJob(m_item, LiveUpdateEditor.searchId).schedule(); DiscoverTask task = new DiscoverTask(m_project.getLocation().toOSString(), m_subnetMask); Job taskJob = task.makeJob("Discover devices in " + m_subnetMask + " subnet"); taskJob.schedule(); int searchIdx = 0; int maxSearchAnimSteps = 2; while(true) { if(searchIdx >= maxSearchAnimSteps) searchIdx = 0; else searchIdx++; new TableItemUpdateUIJob(m_item, LiveUpdateEditor.searchId + searchIdx).schedule(); if (taskJob.getResult() != null) break; if (m_item.isDisposed()) { taskJob.cancel(); break; } Thread.sleep(updateUiSleep); } if (task.isOk()) { new TableItemUpdateUIJob(m_item, LiveUpdateEditor.foundId).schedule(); } else { new TableItemUpdateUIJob(m_item, LiveUpdateEditor.notFoundId).schedule(); } LiveUpdateEditor.eventHandler.notifyUi("update"); } catch (InterruptedException e) { e.printStackTrace(); } } } /* ---------------------------------------------------------------------- */ class DiscoverSubnet implements Runnable { private List<String> m_subnets = null; private String m_pathToProject = null; public DiscoverSubnet(IProject project) { m_pathToProject = project.getLocation().toOSString(); } @Override public void run() { PrintSubnetsTask task = new PrintSubnetsTask(m_pathToProject); task.run(); if (task.isOk()) { m_subnets = task.getSubnets(); } } public List<String> getSubnets() { return m_subnets; } } /* ---------------------------------------------------------------------- */ class LUJobNotifications implements JobNotificationMonitor { IProject m_project = null; final Button m_btn; class StopUiJob extends UIJob { public StopUiJob(String name) { super(name); } @Override public IStatus runInUIThread(IProgressMonitor monitor) { try { m_project.setSessionProperty(LiveUpdateEditor.isLiveUpdateEnableTag, true); if (!m_btn.isDisposed()) { m_btn.setEnabled(true); m_btn.setText(LiveUpdateEditor.switchLUButtonText[LiveUpdateEditor.liveUpdateEnableId]); } } catch (CoreException e) { e.printStackTrace(); } return Status.OK_STATUS; } } class OnStartUiJob extends UIJob { public OnStartUiJob(String name) { super(name); } @Override public IStatus runInUIThread(IProgressMonitor monitor) { try { m_project.setSessionProperty(LiveUpdateEditor.isLiveUpdateEnableTag, m_btn.getEnabled()); } catch (CoreException e) { e.printStackTrace(); } return Status.OK_STATUS; } } public LUJobNotifications(IProject project, final Button btn) { m_project = project; m_btn = btn; } @Override public void onJobStop() { LiveUpdateTask task = new LiveUpdateTask(m_project.getLocation(), false); task.run(); if (task.isOk()) { new StopUiJob("update ui").schedule(); } } @Override public void onJobStart() { try { OnStartUiJob job = new OnStartUiJob("update ui"); job.schedule(); job.join(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void onJobFinished() { } } /* ---------------------------------------------------------------------- */ public class LiveUpdateEditor extends EditorPart implements Observer { public static QualifiedName isLiveUpdateEnableTag = new QualifiedName(null, "is-live-update-ebnable"); public static String[] discoverStatus = {"Found", "Not Found", "Empty", "Search.", "Search..", "Search..."}; public static String[] switchLUButtonText = {"Enable live update", "Disable live update"}; private static final String webrickCommandLineTag = "http://127.0.0.1:3000/auto_update_pid"; //"dev:webserver:privateStart"; public static final String liveUpdateJobName = "live update is running"; public static LiveUpdateObserver eventHandler = new LiveUpdateObserver(); private static Thread webrickWatcherThread = null; public static int liveUpdateEnableId = 0; public static int liveUpdateDisableId = 1; public static int foundId = 0; public static int notFoundId = 1; public static int emptyId = 2; public static int searchId = 3; private static GridData textAligment = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL); private IProject m_project = null; private Table m_devicesTable = null; private Job m_liveUpdateTaskJob = null; @Override public void doSave(IProgressMonitor monitor) { } @Override public void doSaveAs() { } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { if (input instanceof FileEditorInput) { FileEditorInput fileInput = (FileEditorInput)input; m_project = (IProject)fileInput.getFile().getParent(); } setSite(site); setInput(input); eventHandler.addObserver(this); } @Override public boolean isDirty() { return false; } @Override public boolean isSaveAsAllowed() { return false; } @Override public void setFocus() { } @Override public void createPartControl(Composite parent) { if (m_project == null) return; Composite area = parent; Composite container = new Composite(area, SWT.NONE); container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); container.setLayoutData(new GridData(GridData.FILL_BOTH)); container.setLayout(new GridLayout(2, false)); // row 0 createTitleLabel(container, "Common:"); // row 1 new Label(container, SWT.NONE).setText(""); createLUSwitchButton(container); // row 2 new Label(container, SWT.NONE).setText("Subnets: "); new Label(container, SWT.NONE).setText("(for discover make double click on the item of the table)"); // row 3 new Label(container, SWT.NONE).setText(""); createSubnetsTable(container); // row 4 createTitleLabel(container, "Found devices:"); // row 5 new Label(container, SWT.NONE).setText(""); createDevicesTable(container); } private void createLUSwitchButton(Composite container) { try { final Boolean isEnable = (Boolean)m_project.getSessionProperty(isLiveUpdateEnableTag); final Button liveUpdateSwitchButton = new Button(container, SWT.PUSH); LiveUpdateTask task = new LiveUpdateTask(m_project.getLocation(), true); m_liveUpdateTaskJob = task.makeJob(liveUpdateJobName, new LUJobNotifications(m_project, liveUpdateSwitchButton)); liveUpdateSwitchButton.setText(switchLUButtonText[liveUpdateEnableId]); liveUpdateSwitchButton.setLayoutData(textAligment); liveUpdateSwitchButton.setEnabled(isEnable != null ? isEnable.booleanValue() : true); liveUpdateSwitchButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { final Button enableBtn = (Button)e.widget; enableBtn.setEnabled(false); m_liveUpdateTaskJob.schedule(); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }); webrickWatcherThread = new Thread(new Runnable() { @Override public void run() { try { NetworkListener listener = new NetworkListener(webrickCommandLineTag); while(true) { while(!listener.waitServer()) { Thread.sleep(1000); } while(listener.waitServer()) { Thread.sleep(1000); } CancelLiveUpdateUIJob job = new CancelLiveUpdateUIJob(liveUpdateSwitchButton); job.schedule(); job.join(); } } catch (InterruptedException e) { } } }); webrickWatcherThread.start(); } catch (CoreException e2) { e2.printStackTrace(); } } @Override public void dispose() { if (webrickWatcherThread != null) { webrickWatcherThread.interrupt(); webrickWatcherThread = null; } super.dispose(); } private void createDevicesTable(Composite container) { Composite tblContainer = new Composite(container, SWT.NONE); tblContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); tblContainer.setLayout(new FillLayout()); m_devicesTable = new Table(tblContainer, SWT.SINGLE | SWT.FULL_SELECTION); m_devicesTable.setHeaderVisible(true); m_devicesTable.setLinesVisible(true); TableColumn columnSubnetIp = new TableColumn(m_devicesTable, SWT.NONE); columnSubnetIp.setText("Device name"); columnSubnetIp.setWidth(100); final TableColumn column2 = new TableColumn(m_devicesTable, SWT.CENTER); column2.setText("URI"); column2.setWidth(200); final TableColumn column3 = new TableColumn(m_devicesTable, SWT.CENTER); column3.setText("Application name"); column3.setWidth(200); final TableColumn column4 = new TableColumn(m_devicesTable, SWT.CENTER); column4.setText("Device platform"); column4.setWidth(200); fillDevicesTable(container, m_devicesTable); } private void fillDevicesTable(Composite container, Table table) { new DevicesTableFillUIJob(m_project, table).schedule(); } private void createSubnetsTable(Composite container) { Composite tblContainer = new Composite(container, SWT.NONE); tblContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); tblContainer.setLayout(new FillLayout()); final Table subnetTable = new Table(tblContainer, SWT.SINGLE | SWT.FULL_SELECTION); subnetTable.setHeaderVisible(true); subnetTable.setLinesVisible(true); TableColumn columnSubnetIp = new TableColumn(subnetTable, SWT.NONE); columnSubnetIp.setText("Subnet"); columnSubnetIp.setWidth(100); final TableColumn column2 = new TableColumn(subnetTable, SWT.CENTER); column2.setText("Status"); column2.setWidth(300); fillSubnetsTable(container, subnetTable); subnetTable.addListener(SWT.MouseDoubleClick, new Listener() { @Override public void handleEvent(Event event) { dblClickHandler((TableItem)subnetTable.getSelection()[0]); } }); } private void createTitleLabel(Composite container, String title) { new Label(container, SWT.NONE).setText(title); new Label(container, SWT.NONE).setText(""); } private void dblClickHandler(TableItem item) { new Thread(new SearchProgressMonitor(m_project, item.getText(0), item)).start(); } private void fillSubnetsTable(Composite container, Table table) { table.clearAll(); DiscoverSubnet discoverJob = new DiscoverSubnet(m_project); BusyIndicator.showWhile(container.getShell().getDisplay(), discoverJob); if (discoverJob.getSubnets() != null) { for (String itemName : discoverJob.getSubnets()) { TableItem item = new TableItem(table, SWT.NONE); item.setText(itemName); item.setText(1, discoverStatus[emptyId]); } } } @Override public void update(Observable o, Object arg) { fillDevicesTable(null, m_devicesTable); } }