[386718] Fix propagation of server change events

Patch by Vasili Gulevich <vasili.gulevich@xored.com>"

Change-Id: I26303a98d9016b0315a01d6cd5f0fda9ffc82fa4
Signed-off-by: Daniel Johnson <danijoh2@cisco.com>
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/ServerEvent.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/ServerEvent.java
index ac71a4b..616c788 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/ServerEvent.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/ServerEvent.java
@@ -77,6 +77,13 @@
 	 * @see #getKind()
 	 */
 	public static final int MODULE_CHANGE = 0x0020;
+	
+	/**
+	 *  For event on server saves.
+	 *  
+     * @see #getKind()
+	 * **/	
+	public static final int ATTRIBUTE_CHANGE = 0x0040;
 
 	/**
 	 * Create a new server event for server change events.
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
index 940f0ef..0e81122 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
@@ -772,7 +772,7 @@
 			return;
 		
 		notificationManager.broadcastChange(
-			new ServerEvent(ServerEvent.SERVER_CHANGE, this, getServerState(), 
+			new ServerEvent(ServerEvent.SERVER_CHANGE | ServerEvent.ATTRIBUTE_CHANGE, this, getServerState(), 
 				getServerPublishState(), getServerRestartState()));
 	}
 
diff --git a/tests/org.eclipse.wst.server.core.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.wst.server.core.tests/META-INF/MANIFEST.MF
index d2515a8..c4cf3e8 100644
--- a/tests/org.eclipse.wst.server.core.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.wst.server.core.tests/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: org.eclipse.wst.server.core.tests
-Bundle-SymbolicName: org.eclipse.wst.server.core.tests
+Bundle-SymbolicName: org.eclipse.wst.server.core.tests;singleton:=true
 Bundle-Version: 1.1.200.qualifier
 Bundle-ClassPath: servertests.jar
 Bundle-Activator: org.eclipse.wst.server.core.tests.TestsPlugin
diff --git a/tests/org.eclipse.wst.server.core.tests/build.properties b/tests/org.eclipse.wst.server.core.tests/build.properties
index 0754108..ff5985f 100644
--- a/tests/org.eclipse.wst.server.core.tests/build.properties
+++ b/tests/org.eclipse.wst.server.core.tests/build.properties
@@ -15,4 +15,5 @@
 bin.includes = servertests.jar,\
                test.xml,\
                META-INF/,\
-               about.html
+               about.html,\
+               plugin.xml
diff --git a/tests/org.eclipse.wst.server.core.tests/plugin.xml b/tests/org.eclipse.wst.server.core.tests/plugin.xml
new file mode 100644
index 0000000..60d79b4
--- /dev/null
+++ b/tests/org.eclipse.wst.server.core.tests/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.wst.server.core.serverTypes">
+      <serverType
+            class="org.eclipse.wst.server.core.tests.internal.EmptyDelegate"
+            description="Server type without extensions"
+            id="org.eclipse.wst.server.core.tests.empty"
+            name="Empty server type"
+            runtimeTypeId="org.eclipse.wst.server.core.tests.serverType1">
+      </serverType>
+   </extension>
+
+</plugin>
diff --git a/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/AllTests.java b/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/AllTests.java
index e853f5e..64b0e3a 100644
--- a/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/AllTests.java
+++ b/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/AllTests.java
@@ -78,6 +78,7 @@
 		suite.addTestSuite(PublishListenerTestCase.class);
 		suite.addTestSuite(ServerListenerTestCase.class);
 		suite.addTestSuite(ServerEventTestCase.class);
+		suite.addTestSuite(ServerTestCase.class);
 		
 		suite.addTestSuite(ClientDelegateTestCase.class);
 		suite.addTestSuite(RuntimeLocatorDelegateTestCase.class);
diff --git a/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/ServerTestCase.java b/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/ServerTestCase.java
new file mode 100644
index 0000000..9cd3ac8
--- /dev/null
+++ b/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/ServerTestCase.java
@@ -0,0 +1,35 @@
+package org.eclipse.wst.server.core.tests;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.IServerListener;
+import org.eclipse.wst.server.core.IServerType;
+import org.eclipse.wst.server.core.IServerWorkingCopy;
+import org.eclipse.wst.server.core.ServerCore;
+import org.eclipse.wst.server.core.ServerEvent;
+
+import junit.framework.TestCase;
+
+public class ServerTestCase extends TestCase {
+    public void testServerChangeNotification() throws CoreException {
+        IServerType type = ServerCore.findServerType("org.eclipse.wst.server.core.tests.empty");
+        IServerWorkingCopy workingCopy = type.createServer("test_server", null, null);
+        IServer saved = workingCopy.saveAll(true, null);
+        class Listener implements IServerListener {
+            public volatile boolean hit = false; 
+            public void serverChanged(ServerEvent event) {
+                hit = true;
+            }
+        }
+        
+        Listener listener1 = new Listener();
+        Listener listener2 = new Listener();
+        saved.addServerListener(listener1);
+        saved.addServerListener(listener2, ServerEvent.SERVER_CHANGE | ServerEvent.ATTRIBUTE_CHANGE);
+        workingCopy = saved.createWorkingCopy();
+        workingCopy.setHost("host");
+        workingCopy.saveAll(true, null);
+        assertTrue(listener1.hit);
+        assertTrue(listener2.hit);
+    }
+}
diff --git a/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/internal/EmptyDelegate.java b/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/internal/EmptyDelegate.java
new file mode 100644
index 0000000..499e277
--- /dev/null
+++ b/tests/org.eclipse.wst.server.core.tests/src/org/eclipse/wst/server/core/tests/internal/EmptyDelegate.java
@@ -0,0 +1,38 @@
+package org.eclipse.wst.server.core.tests.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.model.ServerDelegate;
+
+final class EmptyDelegate extends ServerDelegate {
+
+    public EmptyDelegate() {
+    }
+
+    @Override
+    public IStatus canModifyModules(IModule[] add, IModule[] remove) {
+        return new Status(IStatus.ERROR, "org.eclipse.wst.server.core.tests", "No modifications are allowed on this dummy server");
+    }
+
+    @Override
+    public IModule[] getChildModules(IModule[] module) {
+        return new IModule[0];
+    }
+
+    @Override
+    public IModule[] getRootModules(IModule module) throws CoreException {
+        return new IModule[0];
+    }
+
+    /** Should not be called
+     * @see {@link #canModifyModules(IModule[], IModule[])} 
+    **/
+    @Override
+    public void modifyModules(IModule[] add, IModule[] remove, IProgressMonitor monitor) throws CoreException {
+        throw new CoreException(canModifyModules(add, remove));
+    }
+
+}