/******************************************************************************* * Copyright (c) 2008,2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.wst.server.ui.internal.cnf; import java.util.HashSet; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.navigator.*; import org.eclipse.ui.part.PageBook; import org.eclipse.wst.server.core.*; import org.eclipse.wst.server.core.internal.Server; import org.eclipse.wst.server.core.internal.UpdateServerJob; import org.eclipse.wst.server.core.util.PublishAdapter; import org.eclipse.wst.server.ui.internal.Messages; import org.eclipse.wst.server.ui.internal.ServerToolTip; import org.eclipse.wst.server.ui.internal.Trace; import org.eclipse.wst.server.ui.internal.wizard.NewServerWizard; /** * A view of servers, their modules, and status. */ public class ServersView2 extends CommonNavigator { private static final String SERVERS_VIEW_CONTEXT = "org.eclipse.ui.serverViewScope"; protected CommonViewer tableViewer; private Control mainPage; private Control noServersPage; PageBook book; protected IServerLifecycleListener serverResourceListener; protected IPublishListener publishListener; protected IServerListener serverListener; // servers that are currently publishing and starting protected static Set<String> publishing = new HashSet<String>(4); protected static Set<String> starting = new HashSet<String>(4); protected boolean animationActive = false; protected boolean stopAnimation = false; /** * ServersView constructor comment. */ public ServersView2() { super(); } @Override public void createPartControl(Composite parent) { // Add PageBook as parent composite FormToolkit toolkit = new FormToolkit(parent.getDisplay()); book = new PageBook(parent, SWT.NONE); super.createPartControl(book); // Main page for the Servers tableViewer mainPage = getCommonViewer().getControl(); // Page prompting to define a new server noServersPage = createDefaultPage(toolkit); book.showPage(mainPage); IContextService contextSupport = (IContextService)getSite().getService(IContextService.class); contextSupport.activateContext(SERVERS_VIEW_CONTEXT); deferInitialization(); } /** * Creates a page displayed when there are no servers defined. * * @param kit * @return Control */ private Control createDefaultPage(FormToolkit kit){ Form form = kit.createForm(book); Composite body = form.getBody(); GridLayout layout = new GridLayout(2, false); body.setLayout(layout); Link hlink = new Link(body, SWT.NONE); hlink.setText(Messages.ServersView2_noServers); hlink.setBackground(book.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); GridData gd = new GridData(SWT.LEFT, SWT.FILL, true, false); hlink.setLayoutData(gd); hlink.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { NewServerWizard wizard = new NewServerWizard(); WizardDialog wd = new WizardDialog(book.getShell(), wizard); if( wd.open() == Window.OK){ toggleDefultPage(); } } }); // Create the context menu for the default page final CommonViewer commonViewer = this.getCommonViewer(); if (commonViewer != null){ ICommonViewerSite commonViewerSite = CommonViewerSiteFactory .createCommonViewerSite(this.getViewSite()); if (commonViewerSite != null){ // Note: actionService cannot be null final NavigatorActionService actionService = new NavigatorActionService(commonViewerSite, commonViewer, commonViewer.getNavigatorContentService()); MenuManager menuManager = new MenuManager("#PopupMenu"); menuManager.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager mgr) { ISelection selection = commonViewer.getSelection(); actionService.setContext(new ActionContext(selection)); actionService.fillContextMenu(mgr); } }); Menu menu = menuManager.createContextMenu(body); // It is necessary to set the menu in two places: // 1. The white space in the server view // 2. The text and link in the server view. If this menu is not set, if the // user right clicks on the text or uses shortcut keys to open the context menu, // the context menu will not come up body.setMenu(menu); hlink.setMenu(menu); } else { if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "The commonViewerSite is null"); } } } else { if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "The commonViewer is null"); } } return form; } /** * Switch between the servers and default/empty page. * */ void toggleDefultPage(){ if(tableViewer.getTree().getItemCount() < 1){ book.showPage(noServersPage); } else{ book.showPage(mainPage); } } private void deferInitialization() { // TODO Angel Says: Need to do a final check on this line below. I don't think there is anything else // that we need from to port from the old Servers View //initializeActions(getCommonViewer()); Job job = new Job(Messages.jobInitializingServersView) { public IStatus run(IProgressMonitor monitor) { IServer[] servers = ServerCore.getServers(); int size = servers.length; for (int i = 0; i < size; i++) { ((Server)servers[i]).getAllModules().iterator(); } deferredInitialize(); return Status.OK_STATUS; } }; job.setSystem(true); job.setPriority(Job.SHORT); job.schedule(); } protected void deferredInitialize() { addListener(); Display.getDefault().asyncExec(new Runnable() { public void run() { try { tableViewer = getCommonViewer(); getSite().setSelectionProvider(tableViewer); // init the tooltip ServerToolTip toolTip = new ServerToolTip(tableViewer.getTree()); toolTip.setShift(new Point(10, 3)); toolTip.setPopupDelay(400); // in ms toolTip.setHideOnMouseDown(true); toolTip.activate(); } catch (Exception e) { // ignore - view has already been closed } } }); UpdateServerJob job = new UpdateServerJob(ServerCore.getServers()); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { Display.getDefault().asyncExec(new Runnable() { public void run() { try { if (tableViewer.getTree().getItemCount() > 0) { Object obj = tableViewer.getTree().getItem(0).getData(); tableViewer.setSelection(new StructuredSelection(obj)); } else{ toggleDefultPage(); } } catch (Exception e){ if (Trace.WARNING) { Trace.trace(Trace.STRING_WARNING, "Failed to update the server view.", e); } } } }); } }); job.schedule(); } protected void handlePublishChange(IServer server, boolean isPublishing) { String serverId = server.getId(); if (isPublishing) publishing.add(serverId); else publishing.remove(serverId); refreshServerState(server); } /** * @deprecated * @param server */ protected void refreshServer(final IServer server){ if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "Refreshing UI for server=" + server); } ServerDecoratorsHandler.refresh(tableViewer); } protected void refreshServerContent(final IServer server){ if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "Refreshing Content for server=" + server); } Display.getDefault().asyncExec(new Runnable() { public void run() { if(!tableViewer.getTree().isDisposed()) tableViewer.refresh(server, true); } }); } protected void refreshServerState(final IServer server){ if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "Refreshing UI for server=" + server); } ServerDecoratorsHandler.refresh(tableViewer); } protected void addListener(){ // To enable the UI updating of servers and its childrens serverResourceListener = new IServerLifecycleListener() { public void serverAdded(IServer server) { addServer(server); server.addServerListener(serverListener); ((Server) server).addPublishListener(publishListener); } public void serverChanged(IServer server) { refreshServerContent(server); } public void serverRemoved(IServer server) { removeServer(server); server.removeServerListener(serverListener); ((Server) server).removePublishListener(publishListener); } }; ServerCore.addServerLifecycleListener(serverResourceListener); // To enable the refresh of the State decorator publishListener = new PublishAdapter() { public void publishStarted(IServer server) { handlePublishChange(server, true); } public void publishFinished(IServer server, IStatus status) { handlePublishChange(server, false); } }; serverListener = new IServerListener() { public void serverChanged(ServerEvent event) { if (event == null) return; int eventKind = event.getKind(); IServer server = event.getServer(); if ((eventKind & ServerEvent.SERVER_CHANGE) != 0) { // server change event if ((eventKind & ServerEvent.STATE_CHANGE) != 0) { int state = event.getState(); String id = server.getId(); if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING) { boolean startThread = false; synchronized (starting) { if (!starting.contains(id)) { if (starting.isEmpty()) startThread = true; starting.add(id); } } if (startThread) startThread(); } else { boolean stopThread = false; synchronized (starting) { if (starting.contains(id)) { starting.remove(id); if (starting.isEmpty()) stopThread = true; } } if (stopThread) stopThread(); } refreshServerState(server); refreshServerContent(server); } else if ((eventKind & ServerEvent.PUBLISH_STATE_CHANGE) != 0 || (eventKind & ServerEvent.STATUS_CHANGE) != 0) { refreshServerState(server); } } else if ((eventKind & ServerEvent.MODULE_CHANGE) != 0) { // module change event if ((eventKind & ServerEvent.STATE_CHANGE) != 0 || (eventKind & ServerEvent.PUBLISH_STATE_CHANGE) != 0 || (eventKind & ServerEvent.STATUS_CHANGE) != 0) { refreshServerContent(server); } } // TODO Angel Says: I don't think we need this //refreshServer(server); } }; // add listeners to servers IServer[] servers = ServerCore.getServers(); if (servers != null) { int size = servers.length; for (int i = 0; i < size; i++) { servers[i].addServerListener(serverListener); ((Server) servers[i]).addPublishListener(publishListener); } } } protected void addServer(final IServer server) { Display.getDefault().asyncExec(new Runnable() { public void run() { tableViewer.add(tableViewer.getInput(), server); toggleDefultPage(); } }); } protected void removeServer(final IServer server) { Display.getDefault().asyncExec(new Runnable() { public void run() { tableViewer.remove(server); toggleDefultPage(); } }); } @Override public void dispose() { ServerCore.removeServerLifecycleListener(serverResourceListener); // remove listeners from servers IServer[] servers = ServerCore.getServers(); if (servers != null) { int size = servers.length; for (int i = 0; i < size; i++) { servers[i].removeServerListener(serverListener); ((Server) servers[i]).removePublishListener(publishListener); } } super.dispose(); } /** * Start the animation thread */ protected void startThread() { if (animationActive) return; stopAnimation = false; final Display display = tableViewer == null ? Display.getDefault() : tableViewer.getControl().getDisplay(); final int SLEEP = 200; final Runnable[] animator = new Runnable[1]; animator[0] = new Runnable() { public void run() { if (!stopAnimation) { try { int size = 0; String[] servers; synchronized (starting) { size = starting.size(); servers = new String[size]; starting.toArray(servers); } for (int i = 0; i < size; i++) { IServer server = ServerCore.findServer(servers[i]); if (server != null ) { ServerDecorator.animate(); tableViewer.update(server, new String[]{"ICON"}); } } } catch (Exception e) { if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "Error in Servers view animation", e); } } display.timerExec(SLEEP, animator[0]); } } }; Display.getDefault().asyncExec(new Runnable() { public void run() { display.timerExec(SLEEP, animator[0]); } }); } protected void stopThread() { stopAnimation = true; } }