import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.logging.Logger;
import com.google.gwt.aria.client.LiveValue;
import com.google.gwt.aria.client.RelevantValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConfiguration.ErrorMessage;
+import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadListener;
import com.vaadin.client.communication.HasJavaScriptConnectorHelper;
}
@Override
- public com.google.gwt.event.shared.GwtEvent.Type<CommunicationHandler> getAssociatedType() {
+ public Type<CommunicationHandler> getAssociatedType() {
return TYPE;
}
}
@Override
- public com.google.gwt.event.shared.GwtEvent.Type<CommunicationHandler> getAssociatedType() {
+ public Type<CommunicationHandler> getAssociatedType() {
return TYPE;
}
public static Type<CommunicationHandler> TYPE = new Type<CommunicationHandler>();
@Override
- public com.google.gwt.event.shared.GwtEvent.Type<CommunicationHandler> getAssociatedType() {
+ public Type<CommunicationHandler> getAssociatedType() {
return TYPE;
}
}
}
+ /**
+ * Event triggered when a application is stopped by calling
+ * {@link ApplicationConnection#setApplicationRunning(false)}.
+ *
+ * To listen for the event add a {@link ApplicationStoppedHandler} by
+ * invoking
+ * {@link ApplicationConnection#addHandler(ApplicationStoppedEvent.Type, ApplicationStoppedHandler)}
+ * to the {@link ApplicationConnection}
+ *
+ * @since 7.1.8
+ * @author Vaadin Ltd
+ */
+ public static class ApplicationStoppedEvent extends
+ GwtEvent<ApplicationStoppedHandler> {
+
+ public static Type<ApplicationStoppedHandler> TYPE = new Type<ApplicationStoppedHandler>();
+
+ @Override
+ public Type<ApplicationStoppedHandler> getAssociatedType() {
+ return TYPE;
+ }
+
+ @Override
+ protected void dispatch(ApplicationStoppedHandler listener) {
+ listener.onApplicationStopped(this);
+ }
+ }
+
/**
* Allows custom handling of communication errors.
*/
public boolean onError(String details, int statusCode);
}
+ /**
+ * A listener for listening to application stopped events. The listener can
+ * be added to a {@link ApplicationConnection} by invoking
+ * {@link ApplicationConnection#addHandler(ApplicationStoppedEvent.Type, ApplicationStoppedHandler)}
+ *
+ * @since 7.1.8
+ * @author Vaadin Ltd
+ */
+ public interface ApplicationStoppedHandler extends EventHandler {
+
+ /**
+ * Triggered when the {@link ApplicationConnection} marks a previously
+ * running application as stopped by invoking
+ * {@link ApplicationConnection#setApplicationRunning(false)}
+ *
+ * @param event
+ * the event triggered by the {@link ApplicationConnection}
+ */
+ void onApplicationStopped(ApplicationStoppedEvent event);
+ }
+
private CommunicationErrorHandler communicationErrorDelegate = null;
private VLoadingIndicator loadingIndicator;
showCommunicationError(details, statusCode);
}
endRequest();
+
+ // Consider application not running any more and prevent all
+ // future requests
+ setApplicationRunning(false);
}
@Override
VConsole.log("JSON parsing took "
+ (new Date().getTime() - start.getTime()) + "ms");
- if (applicationRunning) {
+ if (isApplicationRunning()) {
handleReceivedJSONMessage(start, jsonText, json);
} else {
- applicationRunning = true;
+ setApplicationRunning(true);
handleWhenCSSLoaded(jsonText, json);
}
}
retryCanceledActiveRequest = false;
webkitMaybeIgnoringRequests = false;
- if (applicationRunning) {
+ if (isApplicationRunning()) {
checkForPendingVariableBursts();
runPostRequestHooks(configuration.getRootPanelId());
}
error.getString("message"),
error.getString("url"));
- applicationRunning = false;
+ setApplicationRunning(false);
}
Profiler.leave("Error handling");
}
*/
public void addMethodInvocationToQueue(MethodInvocation invocation,
boolean delayed, boolean lastOnly) {
+ if (!isApplicationRunning()) {
+ getLogger()
+ .warning(
+ "Trying to invoke method on not yet started or stopped application");
+ return;
+ }
String tag;
if (lastOnly) {
tag = invocation.getLastOnlyTag();
private boolean deferedSendPending = false;
private void doSendPendingVariableChanges() {
- if (applicationRunning) {
+ if (isApplicationRunning()) {
if (hasActiveRequest() || (push != null && !push.isActive())) {
// skip empty queues if there are pending bursts to be sent
if (pendingInvocations.size() > 0 || pendingBursts.size() == 0) {
} else {
buildAndSendVariableBurst(pendingInvocations);
}
+ } else {
+ getLogger()
+ .warning(
+ "Trying to send variable changes from not yet started or stopped application");
+ return;
}
}
}
public void setApplicationRunning(boolean running) {
+ if (applicationRunning && !running) {
+ eventBus.fireEvent(new ApplicationStoppedEvent());
+ }
applicationRunning = running;
}
}
}
+ private static Logger getLogger() {
+ return Logger.getLogger(ApplicationConnection.class.getName());
+ }
+
}
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
.getPaintableAttribute("focused", getConnection());
if (paintable == null) {
- // Do not try to focus invisible components which not present in UIDL
+ // Do not try to focus invisible components which not
+ // present in UIDL
return;
}
// side-effects from focusing (scrollIntoView).
getWidget().getElement().focus();
}
+
+ applicationConnection.addHandler(
+ ApplicationConnection.ApplicationStoppedEvent.TYPE,
+ new ApplicationConnection.ApplicationStoppedHandler() {
+
+ @Override
+ public void onApplicationStopped(
+ ApplicationStoppedEvent event) {
+ // Stop any polling
+ if (pollTimer != null) {
+ pollTimer.cancel();
+ pollTimer = null;
+ }
+ }
+ });
}
private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
pollTimer = new Timer() {
@Override
public void run() {
+ if (getState().pollInterval < 0) {
+ // Polling has been cancelled server side
+ pollTimer.cancel();
+ pollTimer = null;
+ return;
+ }
getRpcProxy(UIServerRpc.class).poll();
// Send changes even though poll is @Delayed
getConnection().sendPendingVariableChanges();