| /******************************************************************************* |
| * 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; |
| } |
| } |