[323750] Hostname entry is very slow in New Server Wizard
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Timer.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Timer.java
new file mode 100644
index 0000000..ae6d51a
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Timer.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 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;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Manages a single timer that will run and notify an ActionListener when the
+ * timer expires. The dispose() method should be called before the timer object
+ * is taken down in order to safely bring down the executor and any associated threads.
+ */
+public class Timer {
+
+ private ExecutorService executor = Executors.newSingleThreadExecutor();
+ private TimerRunnable timerRunnable = new TimerRunnable();
+ protected ActionListener listener = null;
+ private long delay;
+
+ public Timer(long delay, ActionListener curListener) {
+ super();
+ this.delay = delay;
+ listener = curListener;
+ }
+
+ /**
+ * Runs the timer if it is stopped or updates the stop time directly
+ * to effectively restart the timer.
+ */
+ public void runTimer(){
+ timerRunnable.setStopTime(System.currentTimeMillis() + delay);
+
+ if(!timerRunnable.isRunning()){
+ timerRunnable.setIsScheduled(true);
+ executor.execute(timerRunnable);
+ }
+ }
+
+ /**
+ * Cancels the timer and then kills the executor which brings down the thread.
+ */
+ public void dispose(){
+ if(timerRunnable.isRunning()) {
+ timerRunnable.setIsCancelled(true);
+ }
+ killExecutor();
+ }
+
+ public void killExecutor(){
+ executor.shutdown();
+ }
+
+ public boolean isRunning(){
+ return timerRunnable.isRunning();
+ }
+
+ public boolean isScheduled(){
+ return timerRunnable.isScheduled();
+ }
+
+ /**
+ * This is the Runnable that is called by the executor each time we want to
+ * run the timer.
+ */
+ class TimerRunnable implements Runnable {
+
+ private boolean isScheduled = false;
+ private boolean isRunning = false;
+ private boolean isCancelled = false;
+ private long stopTime = 0;
+ // default is 50 ms
+ private long waitTime = 50;
+
+ public void run() {
+ isRunning = true;
+ isScheduled = false;
+ try {
+ while (stopTime - System.currentTimeMillis() > 0 && isRunning && !isCancelled) {
+ try {
+ synchronized (this) {
+ wait(waitTime);
+ }
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
+ }
+ if (!isCancelled) {
+ if (listener != null) {
+ listener.actionPerformed(new ActionEvent(Timer.this, 0, "", System.currentTimeMillis(), 0));
+ }
+ } else {
+ setIsCancelled(false);
+ }
+ } finally {
+ isRunning = false;
+ }
+ }
+
+ public synchronized boolean isRunning() {
+ return isRunning;
+ }
+
+ public synchronized void setRunning(boolean setting) {
+ isRunning = setting;
+ }
+
+ public synchronized long getStopTime() {
+ return stopTime;
+ }
+
+ public synchronized void setStopTime(long time) {
+ stopTime = time;
+ }
+
+ public synchronized long getWaitTime() {
+ return waitTime;
+ }
+
+ public synchronized void setIsCancelled(boolean cancelled) {
+ isCancelled = cancelled;
+ }
+
+ public boolean isScheduled() {
+ return isScheduled;
+ }
+
+ public void setIsScheduled(boolean isScheduled) {
+ this.isScheduled = isScheduled;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.java
index b7797f2..eb93cae 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.java
@@ -17,6 +17,7 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.internal.ServerWorkingCopy;
@@ -159,8 +160,11 @@
if(comp != null){
Composite composite = comp.getNewManualServerComposite();
if(composite != null && composite instanceof NewManualServerComposite){
- NewManualServerComposite manualComp = (NewManualServerComposite)composite;
-
+ NewManualServerComposite manualComp = (NewManualServerComposite) composite;
+ if (manualComp.isTimerRunning() || manualComp.isTimerScheduled()) {
+ return false;
+ }
+
if(!supportsRemote && !SocketUtil.isLocalhost(manualComp.getCurrentHostname())){
isComplete = false;
}if (!manualComp.canSupportModule() ){
@@ -180,4 +184,18 @@
return null;
}
}
+
+ public void performCancel(IProgressMonitor monitor) throws CoreException {
+ if(comp != null) {
+ comp.getNewManualServerComposite().dispose();
+ }
+ super.performCancel(monitor);
+ }
+
+ public void performFinish(IProgressMonitor monitor) throws CoreException {
+ if(comp != null) {
+ comp.getNewManualServerComposite().dispose();
+ }
+ super.performFinish(monitor);
+ }
}
\ No newline at end of file
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 4d575af..05765ee 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
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.wst.server.ui.internal.wizard.page;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
@@ -104,6 +106,9 @@
private IServerType oldServerType;
+ HostnameChangedAction hostnameChangeAction;
+ Timer timer = null;
+
private boolean canSupportModule=true;
/**
@@ -192,7 +197,7 @@
hostname.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
- hostnameChanged(hostname.getText());
+ setHostnameChangeTimer(hostname.getText());
}
});
@@ -775,14 +780,82 @@
}
}
}
-
- public String getCurrentHostname(){
- if(hostname != null)
+
+ public String getCurrentHostname() {
+ if (hostname != null)
return hostname.getText();
return null;
}
public boolean canSupportModule() {
return canSupportModule;
- }
+ }
+
+ void setHostnameChangeTimer(String hostName) {
+ if (hostnameChangeAction == null) {
+ hostnameChangeAction = new HostnameChangedAction(hostName);
+ } else {
+ hostnameChangeAction.setHostName(hostName);
+ }
+
+ if (timer == null) {
+ timer = new Timer(300, hostnameChangeAction);
+ }
+ /*
+ * Kick off the timer and then call setMessage if the Timer wasn't
+ * previously running because we want to trigger the isComplete on the page
+ * so that it stops the user from proceeding to the next page while the
+ * timer is running.
+ */
+ if (!timer.isRunning()) {
+ timer.runTimer();
+ wizard.setMessage(null, IMessageProvider.NONE);
+ } else {
+ timer.runTimer();
+ }
+ }
+
+ public boolean isTimerRunning() {
+ if (timer == null) {
+ return false;
+ }
+ return timer.isRunning();
+ }
+
+ public boolean isTimerScheduled() {
+ if (timer == null) {
+ return false;
+ }
+ return timer.isScheduled();
+ }
+
+ /**
+ * Disposes the timer when the wizard is disposed.
+ */
+ public void dispose() {
+ if (timer != null) {
+ timer.dispose();
+ }
+ }
+
+ private class HostnameChangedAction implements ActionListener {
+
+ String hostName;
+
+ public HostnameChangedAction(String name) {
+ hostName = name;
+ }
+
+ public void actionPerformed(ActionEvent a) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ hostnameChanged(hostName);
+ }
+ });
+ }
+
+ void setHostName(String host) {
+ hostName = host;
+ }
+ }
}
\ No newline at end of file