Merge "529600 - generate unique id if server name is not in use but id is"
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPlugin.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPlugin.java
index e1afbd3..faba637 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPlugin.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPlugin.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2018 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
@@ -424,18 +424,7 @@
 		}
 	}
 
-	/**
-	 * Returns true if a server or runtime exists with the given name.
-	 *
-	 * @param element an object
-	 * @param name a name
-	 * @return <code>true</code> if the name is in use, and <code>false</code>
-	 *    otherwise
-	 */
-	public static boolean isNameInUse(Object element, String name) {
-		if (name == null)
-			return true;
-		
+	private static List<Object> generateIsNameInUseList(Object element, String name) {
 		List<Object> list = new ArrayList<Object>();
 		
 		if (element == null || element instanceof IRuntime)
@@ -451,20 +440,96 @@
 			if (list.contains(element))
 				list.remove(element);
 		}
-		
+		return list;
+	}
+	
+	private static final int CHECK_ID = 0;
+	private static final int CHECK_NAME = 1;
+	private static final int CHECK_BOTH = 2;
+	
+	
+	/**
+	 * Returns true if a server or runtime exists with the given name.
+	 *
+	 * @param element an object
+	 * @param name a name
+	 * @return <code>true</code> if the name is in use, and <code>false</code>
+	 *    otherwise
+	 */
+	public static boolean isNameInUse(Object element, String name) {
+		return isNameInUse(element, name, CHECK_BOTH);
+	}
+	
+	/**
+	 * Returns true if a server or runtime exists with the given ID.
+	 *
+	 * @param element an object
+	 * @param name a name
+	 * @return <code>true</code> if the name is in use, and <code>false</code>
+	 *    otherwise
+	 */
+	public static boolean isIdInUse(Object element, String id) {
+		return isNameInUse(element, id, CHECK_ID);
+	}
+	
+	/**
+	 * Returns true if a server or runtime exists with the given name.
+	 *
+	 * @param element an object
+	 * @param name a name
+	 * @return <code>true</code> if the name is in use, and <code>false</code>
+	 *    otherwise
+	 */
+	public static boolean isNameOnlyInUse(Object element, String id) {
+		return isNameInUse(element, id, CHECK_NAME);
+	}
+	
+	/**
+	 * Returns true if a server or runtime exists with the given name only (ignoring id).
+	 *
+	 * @param element an object
+	 * @param name a name
+	 * @return <code>true</code> if the name is in use, and <code>false</code>
+	 *    otherwise
+	 */
+	private static boolean isNameInUse(Object element, String name, int type) {
+		if (name == null)
+			return true;
+		List<Object> list = generateIsNameInUseList(element, name);
 		Iterator iterator = list.iterator();
 		while (iterator.hasNext()) {
 			Object obj = iterator.next();
-			if (obj instanceof IServerAttributes && 
-					(name.equalsIgnoreCase(((IServerAttributes)obj).getName()) || name.equalsIgnoreCase(((IServerAttributes)obj).getId()))) 
-				return true;
-			if (obj instanceof IRuntime && name.equalsIgnoreCase(((IRuntime)obj).getName()))
-				return true;
+			if (obj instanceof IServerAttributes) {
+				if( type == CHECK_NAME ) {
+					if( name.equalsIgnoreCase(((IServerAttributes)obj).getName()) )
+						return true;
+				} else if( type == CHECK_ID) {
+					if( name.equalsIgnoreCase(((IServerAttributes)obj).getId()) ) 
+						return true;
+				} else { 
+					if( name.equalsIgnoreCase(((IServerAttributes)obj).getName()) || 
+							name.equalsIgnoreCase(((IServerAttributes)obj).getId()) ) 
+						return true;
+				}
+			}
+			if (obj instanceof IRuntime ) {
+				if( type == CHECK_NAME ) {
+					if( name.equalsIgnoreCase(((IRuntime)obj).getName()) )
+						return true;
+				} else if( type == CHECK_ID) {
+					if( name.equalsIgnoreCase(((IRuntime)obj).getId()) ) 
+						return true;
+				} else { /*if( type == CHECK_BOTH ) {*/
+					if( name.equalsIgnoreCase(((IRuntime)obj).getName()) || 
+							name.equalsIgnoreCase(((IRuntime)obj).getId()) )
+						return true;
+				}
+			}
 		}
 		
 		return false;
 	}
-
+	
 	/**
 	 * Utility method to tokenize a string into an array.
 	 * 
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/editor/OverviewEditorPart.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/editor/OverviewEditorPart.java
index 93f9d8d..3663dc2 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/editor/OverviewEditorPart.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/editor/OverviewEditorPart.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2017 IBM Corporation and others.
+ * Copyright (c) 2003, 2018 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
@@ -1033,7 +1033,7 @@
 		MultiStatus ms = new MultiStatus(ServerUIPlugin.PLUGIN_ID, 0, "Validating Overview Part", null);
 		mForm.getMessageManager().removeMessage("name", serverName);
 		if (server != null && serverName != null) {
-			if (ServerPlugin.isNameInUse(server, serverName.getText().trim())) {
+			if (ServerPlugin.isNameOnlyInUse(server, serverName.getText().trim())) {
 				mForm.getMessageManager().addMessage("name", Messages.errorDuplicateName, null, IMessageProvider.ERROR, serverName);
 				ms.add(new Status(IStatus.ERROR, ServerUIPlugin.PLUGIN_ID,  Messages.errorDuplicateName));
 			}
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/view/servers/RenameAction.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/view/servers/RenameAction.java
index 1fd8de5..d3e4ac4 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/view/servers/RenameAction.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/view/servers/RenameAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2018 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
@@ -259,7 +259,7 @@
 			public void run() {
 				try {
 					if (!newName.equals(editedServer.getName())) {
-						if (ServerPlugin.isNameInUse(editedServer, newName)) {
+						if (ServerPlugin.isNameOnlyInUse(editedServer, newName)) {
 							MessageDialog.openError(shell, Messages.defaultDialogTitle, Messages.errorDuplicateName);
 						} else {
 							try {
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.java
index 2c723ad..86a9f6f 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2017 IBM Corporation and others.
+ * Copyright (c) 2003, 2018 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
@@ -263,6 +263,10 @@
 				
 				if (server != null) {
 					server.setName(name);
+					String base = serverName.getText().trim();
+					if( ServerPlugin.isIdInUse(server, base) ) {
+						server.setAttribute("id", generateUniqueId(base));
+					}
 					IRuntime runtime2 = server.getRuntime();
 					if (runtime2 != null && runtime2 instanceof IRuntimeWorkingCopy) {
 						IRuntimeWorkingCopy rwc = (IRuntimeWorkingCopy) runtime2;
@@ -353,6 +357,17 @@
 		Dialog.applyDialogFont(this);
 	}
 
+	String generateUniqueId(String base) {
+		// generate a temporary unique id
+		long time = System.currentTimeMillis();
+		String toTest = new StringBuilder(base).append("_").append(time).toString();
+		int num = 1;
+		while(ServerPlugin.isIdInUse(server, toTest) ) {
+			toTest = new StringBuilder(base).append("_").append(time).append("_").append(num++).toString();
+		}
+		return toTest;
+	}
+	
 	protected boolean showPreferencePage() {
 		String id = "org.eclipse.wst.server.ui.preferencePage";
 		String id2 = "org.eclipse.wst.server.ui.runtime.preferencePage";
@@ -1094,7 +1109,7 @@
 			// server name, check to see if the name is in use
 			if (!cacheServerNameCheck.equals(myServerName)){
 				cacheServerNameCheck = myServerName;
-				isServerNameInUse = ServerPlugin.isNameInUse(server, serverName.getText().trim());				
+				isServerNameInUse = ServerPlugin.isNameOnlyInUse(server, serverName.getText().trim());				
 			}
 			return isServerNameInUse;			
 		}