[320687] Add resource listener to detect Tomcat configuration changes
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ConfigurationResourceListener.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ConfigurationResourceListener.java
new file mode 100644
index 0000000..2474b4a
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ConfigurationResourceListener.java
@@ -0,0 +1,88 @@
+/**********************************************************************
+ * Copyright (c) 2011 SAS Institute, Inc 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:
+ *    SAS Institute, Inc - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.jst.server.tomcat.core.internal;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.IServerType;
+import org.eclipse.wst.server.core.ServerCore;
+import org.eclipse.wst.server.core.internal.ServerType;
+
+public class ConfigurationResourceListener implements IResourceChangeListener {
+
+	private IProject serversProject;
+	
+	/**
+	 * Currently, only changes to Tomcat configuration files are detected and the associated
+	 * server's state updated.  This method needs to be as brief as possible if the change
+	 * is unrelated to server configuration changes.  Since the Servers project would change
+	 * so rarely, it is worth saving some cycles in the resource listener by caching this project.
+	 */
+	public void resourceChanged(IResourceChangeEvent event) {
+		if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+			IProject project = getServersProject();
+			if (project != null) {
+				IResourceDelta delta = event.getDelta();
+				if (delta != null) {
+					IResourceDelta serversProjectDelta = delta.findMember(project.getFullPath());
+					if (serversProjectDelta != null) {
+						// The change occurred within the Servers project.
+						IResourceDelta [] childDelta = serversProjectDelta.getAffectedChildren();
+						if (childDelta.length > 0) {
+							IServer [] servers = ServerCore.getServers();
+							for (int i = 0; i < childDelta.length; i++) {
+								// Check if this subfolder of the Servers folder matches a Tomcat configuration folder
+								for (int j = 0; j < servers.length; j++) {
+									IServerType serverType = servers[j].getServerType();
+									if (serverType.getId().startsWith("org.eclipse.jst.server.tomcat.")) {
+										IFolder configFolder = servers[j].getServerConfiguration();
+										if (configFolder != null) {
+											if (childDelta[i].getFullPath().equals(configFolder.getFullPath())) {
+												// Found a Tomcat server affected by this delta.  Update this server's publish state.
+												TomcatServerBehaviour tcServerBehaviour = (TomcatServerBehaviour)servers[j].loadAdapter(TomcatServerBehaviour.class, null);
+												if (tcServerBehaviour != null) {
+													// Indicate that this server needs to publish and restart if running
+													tcServerBehaviour.setTomcatServerPublishState(IServer.PUBLISH_STATE_INCREMENTAL);
+													tcServerBehaviour.setTomcatServerRestartState(true);
+												}
+												break;
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private IProject getServersProject() {
+		if (serversProject == null) {
+			IProject project;
+			try {
+				project = ServerType.getServerProject();
+				synchronized (this) {
+					serversProject = project;
+				}
+			} catch (CoreException e) {
+				// Ignore
+			}
+		}
+		return serversProject;
+	}
+}
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java
index b10d1ff..1df80c0 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * 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
@@ -18,11 +18,14 @@
 import java.util.Properties;
 import java.util.StringTokenizer;
 
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.FileLocator;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Plugin;
 import org.eclipse.core.runtime.Status;
+import org.osgi.framework.BundleContext;
 /**
  * The Tomcat plugin.
  */
@@ -52,6 +55,7 @@
 	protected static final IStatus wrongDirVersionStatus = new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorInstallDirWrongVersion, null);
 	protected static final IStatus installDirDoesNotExist = new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorInstallDirDoesNotExist, null);
 
+	private static ConfigurationResourceListener configurationListener;
 	/**
 	 * TomcatPlugin constructor comment.
 	 */
@@ -60,6 +64,19 @@
 		singleton = this;
 	}
 
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		configurationListener = new ConfigurationResourceListener();
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(configurationListener, IResourceChangeEvent.POST_CHANGE);
+	}
+
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		ResourcesPlugin.getWorkspace().removeResourceChangeListener(configurationListener);
+		super.stop(context);
+	}
+
 	/**
 	 * Returns the singleton instance of this plugin.
 	 * @return org.eclipse.jst.server.tomcat.internal.TomcatPlugin
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java
index e854c42..0fefc98 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java
@@ -1171,4 +1171,12 @@
 			}
 		}
 	}
+
+	public void setTomcatServerPublishState(int state) {
+		setServerPublishState(state);
+	}
+
+	public void setTomcatServerRestartState(boolean state) {
+		setServerRestartState(state);
+	}
 }
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/cnf/ServersView2.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/cnf/ServersView2.java
index 500cdd1..93014fe 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/cnf/ServersView2.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/cnf/ServersView2.java
@@ -230,7 +230,10 @@
 						}
 						refreshServerState(server);
 						refreshServerContent(server);
-					} 
+					}
+					else if ((eventKind & ServerEvent.PUBLISH_STATE_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) {