blob: d767685ffcc06bccfd0205999b4ce89709aa2eee [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2011 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.view.servers;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.viewers.*;
import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.internal.Server;
import org.eclipse.wst.server.core.util.PublishAdapter;
import org.eclipse.wst.server.ui.internal.Trace;
import org.eclipse.wst.server.ui.internal.viewers.BaseContentProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.PlatformUI;
/**
* Tree view showing servers and their associations.
*/
public class ServerTableViewer extends TreeViewer {
protected static final String ROOT = "root";
protected static Color color;
protected static Font font;
protected Clipboard clipboard;
protected IServerLifecycleListener serverResourceListener;
protected IPublishListener publishListener;
protected IServerListener serverListener;
protected static Object deletedElement = null;
// 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 ServerTableLabelProvider labelProvider;
//protected ISelectionListener dsListener;
protected ServersView view;
protected boolean animationActive = false;
protected boolean stopAnimation = false;
public class ServerContentProvider extends BaseContentProvider implements ITreeContentProvider {
public Object[] getElements(Object element) {
List<IServer> list = new ArrayList<IServer>();
IServer[] servers = ServerCore.getServers();
if (servers != null) {
int size = servers.length;
for (int i = 0; i < size; i++) {
if (!((Server)servers[i]).isPrivate())
list.add(servers[i]);
}
}
return list.toArray();
}
public Object[] getChildren(Object element) {
if (element instanceof ModuleServer) {
ModuleServer ms = (ModuleServer) element;
try {
IModule[] children = ms.server.getChildModules(ms.module, null);
int size = children.length;
ModuleServer[] ms2 = new ModuleServer[size];
for (int i = 0; i < size; i++) {
int size2 = ms.module.length;
IModule[] module = new IModule[size2 + 1];
System.arraycopy(ms.module, 0, module, 0, size2);
module[size2] = children[i];
ms2[i] = new ModuleServer(ms.server, module);
}
return ms2;
} catch (Exception e) {
return null;
}
}
IServer server = (IServer) element;
IModule[] modules = server.getModules();
int size = modules.length;
ModuleServer[] ms = new ModuleServer[size];
for (int i = 0; i < size; i++) {
ms[i] = new ModuleServer(server, new IModule[] { modules[i] });
}
return ms;
}
public Object getParent(Object element) {
if (element instanceof ModuleServer) {
ModuleServer ms = (ModuleServer) element;
return ms.server;
}
return null;
}
public boolean hasChildren(Object element) {
if (element instanceof ModuleServer) {
// Check if the module server has child modules.
ModuleServer curModuleServer = (ModuleServer)element;
IServer curServer = curModuleServer.server;
IModule[] curModule = curModuleServer.module;
if (curServer != null && curModule != null) {
IModule[] curChildModule = curServer.getChildModules(curModule, null);
if (curChildModule != null && curChildModule.length > 0)
return true;
return false;
}
return false;
}
IServer server = (IServer) element;
return server.getModules().length > 0;
}
}
protected void startThread() {
if (animationActive)
return;
stopAnimation = false;
final Display display = getTree().getDisplay();
final int SLEEP = 200;
final Runnable[] animator = new Runnable[1];
animator[0] = new Runnable() {
public void run() {
if (!stopAnimation) {
try {
labelProvider.animate();
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 && getTree() != null && !getTree().isDisposed())
updateAnimation(server);
}
} 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;
}
/**
* ServerTableViewer constructor comment.
*
* @param view the view
* @param tree the tree
*/
public ServerTableViewer(final ServersView view, final Tree tree) {
super(tree);
this.view = view;
clipboard = new Clipboard(tree.getDisplay());
}
protected void initialize() {
ColumnViewerToolTipSupport.enableFor(this);
setContentProvider(new ServerContentProvider());
labelProvider = new ServerTableLabelProvider();
setLabelProvider(labelProvider);
setComparator(new ServerViewerComparator(labelProvider));
setInput(ROOT);
addListeners();
/*dsListener = new ISelectionListener() {
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
if (!(selection instanceof IStructuredSelection))
return;
IStructuredSelection sel = (IStructuredSelection) selection;
final Object obj = sel.getFirstElement();
IProject proj = null;
if (obj instanceof IResource) {
IResource res = (IResource) obj;
proj = res.getProject();
}
if (proj == null && obj != null) {
try {
IResource res = (IResource) Platform.getAdapterManager().getAdapter(obj, IResource.class);
if (res != null)
proj = res.getProject();
} catch (Exception e) {
// ignore
}
}
if (proj != null) {
final IProject project = proj;
final IModule module = ServerUtil.getModule(project);
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (getTree() == null || getTree().isDisposed())
return;
IServer defaultServer = null;
if (module != null)
defaultServer = ServerCore.getDefaultServer(module);
IServer oldDefaultServer = labelProvider.getDefaultServer();
if ((oldDefaultServer == null && defaultServer == null)
|| (oldDefaultServer != null && oldDefaultServer.equals(defaultServer)))
return;
labelProvider.setDefaultServer(defaultServer);
if (oldDefaultServer != null)
refresh(oldDefaultServer);
if (defaultServer != null)
refresh(defaultServer);
}
});
}
}
};
view.getViewSite().getPage().addSelectionListener(dsListener);*/
if (color == null) {
Display display = getControl().getDisplay();
color = display.getSystemColor(SWT.COLOR_DARK_GRAY);
FontData[] fd = getControl().getFont().getFontData();
int size = fd.length;
for (int i = 0; i < size; i++)
fd[i].setStyle(SWT.ITALIC);
font = new Font(display, fd);
}
}
protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
Object[] obj = event.getElements();
if (obj == null)
refresh(true);
else {
obj = adaptLabelChangeObjects(obj);
int size = obj.length;
for (int i = 0; i < size; i++)
update(obj[i], null);
}
}
/**
* Resort the table based on field.
*
* @param column the column being updated
* @param col
*/
protected void resortTable(final TreeColumn column, int col) {
ServerViewerComparator sorter = (ServerViewerComparator) getComparator();
if (col == sorter.getTopPriority())
sorter.reverseTopPriority();
else
sorter.setTopPriority(col);
PlatformUI.getWorkbench().getDisplay().asyncExec(
new Runnable() {
public void run() {
refresh();
updateDirectionIndicator(column);
}
});
}
/**
* Update the direction indicator as column is now the primary column.
*
* @param column
*/
protected void updateDirectionIndicator(TreeColumn column) {
getTree().setSortColumn(column);
if (((ServerViewerComparator) getComparator()).getTopPriorityDirection() == ServerViewerComparator.ASCENDING)
getTree().setSortDirection(SWT.UP);
else
getTree().setSortDirection(SWT.DOWN);
}
protected Object[] adaptLabelChangeObjects(Object[] obj) {
if (obj == null)
return obj;
List<Object> list = new ArrayList<Object>();
int size = obj.length;
for (int i = 0; i < size; i++) {
if (obj[i] instanceof IModule) {
list.add(obj[i]);
} else if (obj[i] instanceof IServer) {
list.add(obj[i]);
} else if (obj[i] instanceof ModuleServer) {
list.add(obj[i]);
} else if (obj[i] instanceof IProject) {
IProject proj = (IProject) obj[i];
List<Object> list2 = new ArrayList<Object>();
getTreeChildren(list2, view.treeTable);
Iterator iterator = list2.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof ModuleServer) {
ModuleServer ms = (ModuleServer) o;
if (proj.equals(ms.module[ms.module.length - 1].getProject()))
list.add(ms);
}
}
}
}
Object[] o = new Object[list.size()];
list.toArray(o);
return o;
}
private void getTreeChildren(List<Object> list, Widget widget) {
Item[] items = getChildren(widget);
for (int i = 0; i < items.length; i++) {
Item item = items[i];
Object data = item.getData();
if (data != null)
list.add(data);
if (getExpanded(item)) {
// only recurse if it is expanded - if
// not then the children aren't visible
getTreeChildren(list, item);
}
}
}
protected void addListeners() {
serverResourceListener = new IServerLifecycleListener() {
public void serverAdded(IServer server) {
addServer(server);
server.addServerListener(serverListener);
((Server) server).addPublishListener(publishListener);
}
public void serverChanged(IServer server) {
refreshServer(server);
}
public void serverRemoved(IServer server) {
removeServer(server);
server.removeServerListener(serverListener);
((Server) server).removePublishListener(publishListener);
}
};
ServerCore.addServerLifecycleListener(serverResourceListener);
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) {
refreshServer(server);
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();
}
} else
refreshServer(server);
} else if ((eventKind & ServerEvent.MODULE_CHANGE) != 0) {
// module change event
if ((eventKind & ServerEvent.STATE_CHANGE) != 0 || (eventKind & ServerEvent.PUBLISH_STATE_CHANGE) != 0) {
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);
}
}
}
/**
* @param server
* @deprecated With the introduction of the CNF this method shouldn't be called
*/
protected void refreshServer(final IServer server) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
try {
refresh(server);
ISelection sel = ServerTableViewer.this.getSelection();
ServerTableViewer.this.setSelection(sel);
} catch (Exception e) {
// ignore
}
}
});
}
protected void handleDispose(DisposeEvent event) {
stopThread();
//if (dsListener != null)
// view.getViewSite().getPage().removeSelectionListener(dsListener);
ServerCore.removeServerLifecycleListener(serverResourceListener);
// remove listeners from server
IServer[] servers = ServerCore.getServers();
if (servers != null) {
int size = servers.length;
for (int i = 0; i < size; i++) {
if (serverListener != null)
servers[i].removeServerListener(serverListener);
if (publishListener != null)
((Server) servers[i]).removePublishListener(publishListener);
}
}
clipboard.dispose();
super.handleDispose(event);
}
/**
* Called when the publish state changes.
* @param server org.eclipse.wst.server.core.IServer
*/
protected void handlePublishChange(IServer server, boolean isPublishing) {
String serverId = server.getId();
if (isPublishing)
publishing.add(serverId);
else
publishing.remove(serverId);
refreshServer(server);
}
/**
*
*/
protected void handleServerModulesChanged(IServer server2) {
if (server2 == null)
return;
IServer[] servers = ServerCore.getServers();
if (servers != null) {
int size = servers.length;
for (int i = 0; i < size; i++) {
if (server2.equals(servers[i]))
refresh(servers[i]);
}
}
}
/**
* Called when an element is added.
* @param server org.eclipse.wst.server.core.IServer
*/
protected void handleServerResourceAdded(IServer server) {
add(null, server);
}
/*protected void handleServerResourceAdded(IServerConfiguration configuration) {
configurationChange(configuration, true);
}*/
/**
* Called when an element is changed.
* @param server org.eclipse.wst.server.core.IServer
*/
protected void handleServerResourceChanged(IServer server) {
refresh(server);
}
/*protected void handleServerResourceChanged(IServerConfiguration configuration) {
IServer[] servers = ServerCore.getServers();
if (servers != null) {
int size = servers.length;
for (int i = 0; i < size; i++) {
IServerConfiguration config = servers[i].getServerConfiguration();
if (configuration.equals(config))
refresh(servers[i]);
}
}
}*/
/**
* Called when an element is removed.
* @param server org.eclipse.wst.server.core.IServer
*/
protected void handleServerResourceRemoved(IServer server) {
remove(server);
String serverId = server.getId();
publishing.remove(serverId);
view.getViewSite().getActionBars().getStatusLineManager().setMessage(null, null);
}
/*protected void handleServerResourceRemoved(IServerConfiguration configuration) {
configurationChange(configuration, false);
}*/
protected void addServer(final IServer server) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
add(ROOT, server);
}
});
}
protected void removeServer(final IServer server) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
remove(server);
}
});
}
public void doUpdateItem(Widget widget, Object element, boolean fullMap) {
if (widget instanceof TreeItem && color != null) {
TreeItem item = (TreeItem) widget;
if (element instanceof ModuleServer) {
ModuleServer ms = (ModuleServer) element;
IModule m = ms.module[ms.module.length-1];
if (m.isExternal())
item.setForeground(color);
else
item.setForeground(null);
if (ms.server.getModulePublishState(ms.module) != IServer.PUBLISH_STATE_NONE)
item.setFont(0, font);
else
item.setFont(0, null);
}
}
super.doUpdateItem(widget, element, fullMap);
}
protected void updateAnimation(IServer server) {
try {
Widget widget = doFindItem(server);
TreeItem item = (TreeItem) widget;
item.setText(1, labelProvider.getColumnText(server, 1));
item.setImage(1, labelProvider.getColumnImage(server, 1));
} catch (Exception e) {
if (Trace.WARNING) {
Trace.trace(Trace.STRING_WARNING, "Error in optimized animation", e);
}
}
}
}