summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/server/LegacyCommunicationManager.java4
-rw-r--r--server/src/com/vaadin/server/LocaleService.java20
-rw-r--r--server/src/com/vaadin/server/communication/AtmospherePushConnection.java2
-rw-r--r--server/src/com/vaadin/server/communication/ServerRpcHandler.java98
-rw-r--r--server/src/com/vaadin/server/communication/UIInitHandler.java2
-rw-r--r--server/src/com/vaadin/server/communication/UidlRequestHandler.java48
-rw-r--r--server/src/com/vaadin/server/communication/UidlWriter.java17
-rw-r--r--server/src/com/vaadin/ui/PushConfiguration.java24
-rw-r--r--server/src/com/vaadin/ui/ReconnectDialogConfiguration.java201
-rw-r--r--server/src/com/vaadin/ui/UI.java45
-rw-r--r--server/src/com/vaadin/ui/Upload.java5
-rw-r--r--server/tests/src/com/vaadin/ui/PushConfigurationTransportTest.java6
12 files changed, 412 insertions, 60 deletions
diff --git a/server/src/com/vaadin/server/LegacyCommunicationManager.java b/server/src/com/vaadin/server/LegacyCommunicationManager.java
index e982cdf10a..87b484a65f 100644
--- a/server/src/com/vaadin/server/LegacyCommunicationManager.java
+++ b/server/src/com/vaadin/server/LegacyCommunicationManager.java
@@ -353,6 +353,10 @@ public class LegacyCommunicationManager implements Serializable {
res.clear();
}
+ public boolean isEmpty() {
+ return res.isEmpty();
+ }
+
}
/**
diff --git a/server/src/com/vaadin/server/LocaleService.java b/server/src/com/vaadin/server/LocaleService.java
index 0274d227ab..ccdc49f690 100644
--- a/server/src/com/vaadin/server/LocaleService.java
+++ b/server/src/com/vaadin/server/LocaleService.java
@@ -23,6 +23,7 @@ import java.io.Serializable;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
+import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.logging.Logger;
@@ -120,9 +121,24 @@ public class LocaleService implements Serializable {
LocaleData localeData = new LocaleData();
localeData.name = locale.toString();
+ Calendar c = Calendar.getInstance(locale);
+ c.set(2015, 0, 1);
+ SimpleDateFormat shortMonthFormat = new SimpleDateFormat("MMM", locale);
+ SimpleDateFormat longMonthFormat = new SimpleDateFormat("MMMM", locale);
+
+ int monthsInYear = c.getMaximum(Calendar.MONTH) + 1;
+ localeData.shortMonthNames = new String[monthsInYear];
+ localeData.monthNames = new String[monthsInYear];
+ for (int month = 0; month < monthsInYear; month++) {
+ c.set(Calendar.MONTH, month);
+ String shortMonth = shortMonthFormat.format(c.getTime());
+ String longMonth = longMonthFormat.format(c.getTime());
+ localeData.shortMonthNames[month] = shortMonth;
+ localeData.monthNames[month] = longMonth;
+ }
+
final DateFormatSymbols dfs = new DateFormatSymbols(locale);
- localeData.shortMonthNames = dfs.getShortMonths();
- localeData.monthNames = dfs.getMonths();
+
// Client expects 0 based indexing, DateFormatSymbols use 1 based
localeData.shortDayNames = new String[7];
localeData.dayNames = new String[7];
diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
index 05e4f6479f..5c0d2e14d4 100644
--- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
+++ b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
@@ -165,7 +165,7 @@ public class AtmospherePushConnection implements PushConnection {
} else {
try {
Writer writer = new StringWriter();
- new UidlWriter().write(getUI(), writer, false, async);
+ new UidlWriter().write(getUI(), writer, async);
sendMessage("for(;;);[{" + writer.toString() + "}]");
} catch (Exception e) {
throw new RuntimeException("Push failed", e);
diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
index 65fb144810..f3d4b163ff 100644
--- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java
+++ b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
@@ -29,6 +29,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import com.vaadin.server.ClientConnector;
+import com.vaadin.server.Constants;
import com.vaadin.server.JsonCodec;
import com.vaadin.server.LegacyCommunicationManager;
import com.vaadin.server.LegacyCommunicationManager.InvalidUIDLSecurityKeyException;
@@ -40,6 +41,7 @@ import com.vaadin.server.VaadinService;
import com.vaadin.server.VariableOwner;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.Connector;
+import com.vaadin.shared.Version;
import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
import com.vaadin.shared.communication.MethodInvocation;
import com.vaadin.shared.communication.ServerRpc;
@@ -77,6 +79,8 @@ public class ServerRpcHandler implements Serializable {
private final int syncId;
private final JsonObject json;
private final boolean resynchronize;
+ private final int clientToServerMessageId;
+ private String widgetsetVersion = null;
public RpcRequest(String jsonString, VaadinRequest request) {
json = JsonUtil.parse(jsonString);
@@ -106,7 +110,19 @@ public class ServerRpcHandler implements Serializable {
} else {
resynchronize = false;
}
+ if (json.hasKey(ApplicationConstants.WIDGETSET_VERSION_ID)) {
+ widgetsetVersion = json
+ .getString(ApplicationConstants.WIDGETSET_VERSION_ID);
+ }
+ if (json.hasKey(ApplicationConstants.CLIENT_TO_SERVER_ID)) {
+ clientToServerMessageId = (int) json
+ .getNumber(ApplicationConstants.CLIENT_TO_SERVER_ID);
+ } else {
+ getLogger()
+ .warning("Server message without client id received");
+ clientToServerMessageId = -1;
+ }
invocations = json.getArray(ApplicationConstants.RPC_INVOCATIONS);
}
@@ -149,6 +165,15 @@ public class ServerRpcHandler implements Serializable {
}
/**
+ * Gets the id of the client to server message
+ *
+ * @return the server message id
+ */
+ public int getClientToServerId() {
+ return clientToServerMessageId;
+ }
+
+ /**
* Gets the entire request in JSON format, as it was received from the
* client.
* <p>
@@ -161,6 +186,17 @@ public class ServerRpcHandler implements Serializable {
public JsonObject getRawJson() {
return json;
}
+
+ /**
+ * Gets the widget set version reported by the client
+ *
+ * @since 7.6
+ * @return The widget set version reported by the client or null if the
+ * message did not contain a widget set version
+ */
+ public String getWidgetsetVersion() {
+ return widgetsetVersion;
+ }
}
private static final int MAX_BUFFER_SIZE = 64 * 1024;
@@ -199,8 +235,43 @@ public class ServerRpcHandler implements Serializable {
rpcRequest.getCsrfToken())) {
throw new InvalidUIDLSecurityKeyException("");
}
- handleInvocations(ui, rpcRequest.getSyncId(),
- rpcRequest.getRpcInvocationsData());
+
+ checkWidgetsetVersion(rpcRequest.getWidgetsetVersion());
+
+ int expectedId = ui.getLastProcessedClientToServerId() + 1;
+ if (rpcRequest.getClientToServerId() != -1
+ && rpcRequest.getClientToServerId() != expectedId) {
+ // Invalid message id, skip RPC processing but force a full
+ // re-synchronization of the client as it might have not received
+ // the previous response (e.g. due to a bad connection)
+
+ // Must resync also for duplicate messages because the server might
+ // have generated a response for the first message but the response
+ // did not reach the client. When the client re-sends the message,
+ // it would only get an empty response (because the dirty flags have
+ // been cleared on the server) and would be out of sync
+ ui.getSession().getCommunicationManager().repaintAll(ui);
+
+ if (rpcRequest.getClientToServerId() < expectedId) {
+ // Just a duplicate message due to a bad connection or similar
+ // It has already been handled by the server so it is safe to
+ // ignore
+ getLogger().fine(
+ "Ignoring old message from the client. Expected: "
+ + expectedId + ", got: "
+ + rpcRequest.getClientToServerId());
+ } else {
+ getLogger().warning(
+ "Unexpected message id from the client. Expected: "
+ + expectedId + ", got: "
+ + rpcRequest.getClientToServerId());
+ }
+ } else {
+ // Message id ok, process RPCs
+ ui.setLastProcessedClientToServerId(expectedId);
+ handleInvocations(ui, rpcRequest.getSyncId(),
+ rpcRequest.getRpcInvocationsData());
+ }
ui.getConnectorTracker().cleanConcurrentlyRemovedConnectorIds(
rpcRequest.getSyncId());
@@ -208,6 +279,29 @@ public class ServerRpcHandler implements Serializable {
if (rpcRequest.isResynchronize()) {
ui.getSession().getCommunicationManager().repaintAll(ui);
}
+
+ }
+
+ /**
+ * Checks that the version reported by the client (widgetset) matches that
+ * of the server.
+ *
+ * @param widgetsetVersion
+ * the widget set version reported by the client or null
+ */
+ private void checkWidgetsetVersion(String widgetsetVersion) {
+ if (widgetsetVersion == null) {
+ // Only check when the widgetset version is reported. It is reported
+ // in the first UIDL request (not the initial request as it is a
+ // plain GET /)
+ return;
+ }
+
+ if (!Version.getFullVersion().equals(widgetsetVersion)) {
+ getLogger().warning(
+ String.format(Constants.WIDGETSET_MISMATCH_INFO,
+ Version.getFullVersion(), widgetsetVersion));
+ }
}
/**
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index 3a6dc1e55f..f380a6df6e 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/com/vaadin/server/communication/UIInitHandler.java
@@ -282,7 +282,7 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
if (session.getConfiguration().isXsrfProtectionEnabled()) {
writer.write(getSecurityKeyUIDL(session));
}
- new UidlWriter().write(uI, writer, true, false);
+ new UidlWriter().write(uI, writer, false);
writer.write("}");
String initialUIDL = writer.toString();
diff --git a/server/src/com/vaadin/server/communication/UidlRequestHandler.java b/server/src/com/vaadin/server/communication/UidlRequestHandler.java
index 33a3669b7f..dda3d81453 100644
--- a/server/src/com/vaadin/server/communication/UidlRequestHandler.java
+++ b/server/src/com/vaadin/server/communication/UidlRequestHandler.java
@@ -22,7 +22,6 @@ import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
-import com.vaadin.server.Constants;
import com.vaadin.server.LegacyCommunicationManager.InvalidUIDLSecurityKeyException;
import com.vaadin.server.ServletPortletHelper;
import com.vaadin.server.SessionExpiredHandler;
@@ -32,9 +31,7 @@ import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinResponse;
import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinSession;
-import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.JsonConstants;
-import com.vaadin.shared.Version;
import com.vaadin.ui.UI;
import elemental.json.JsonException;
@@ -76,29 +73,12 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
return true;
}
- checkWidgetsetVersion(request);
- // repaint requested or session has timed out and new one is created
- boolean repaintAll;
-
- // TODO PUSH analyzeLayouts should be
- // part of the message payload to make the functionality transport
- // agnostic
-
- // Resynchronize is sent in the payload but will still support the
- // parameter also for compatibility reasons
- repaintAll = (request
- .getParameter(ApplicationConstants.URL_PARAMETER_REPAINT_ALL) != null);
-
StringWriter stringWriter = new StringWriter();
try {
rpcHandler.handleRpc(uI, request.getReader(), request);
- if (repaintAll) {
- session.getCommunicationManager().repaintAll(uI);
- }
-
- writeUidl(request, response, uI, stringWriter, repaintAll);
+ writeUidl(request, response, uI, stringWriter);
} catch (JsonException e) {
getLogger().log(Level.SEVERE, "Error writing JSON to response", e);
// Refresh on client side
@@ -119,28 +99,6 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
stringWriter.toString());
}
- /**
- * Checks that the version reported by the client (widgetset) matches that
- * of the server.
- *
- * @param request
- */
- private void checkWidgetsetVersion(VaadinRequest request) {
- String widgetsetVersion = request.getParameter("v-wsver");
- if (widgetsetVersion == null) {
- // Only check when the widgetset version is reported. It is reported
- // in the first UIDL request (not the initial request as it is a
- // plain GET /)
- return;
- }
-
- if (!Version.getFullVersion().equals(widgetsetVersion)) {
- getLogger().warning(
- String.format(Constants.WIDGETSET_MISMATCH_INFO,
- Version.getFullVersion(), widgetsetVersion));
- }
- }
-
private void writeRefresh(VaadinRequest request, VaadinResponse response)
throws IOException {
String json = VaadinService.createCriticalNotificationJSON(null, null,
@@ -149,10 +107,10 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
}
private void writeUidl(VaadinRequest request, VaadinResponse response,
- UI ui, Writer writer, boolean repaintAll) throws IOException {
+ UI ui, Writer writer) throws IOException {
openJsonMessage(writer, response);
- new UidlWriter().write(ui, writer, repaintAll, false);
+ new UidlWriter().write(ui, writer, false);
closeJsonMessage(writer);
}
diff --git a/server/src/com/vaadin/server/communication/UidlWriter.java b/server/src/com/vaadin/server/communication/UidlWriter.java
index a4797e49aa..25b1bdaaf9 100644
--- a/server/src/com/vaadin/server/communication/UidlWriter.java
+++ b/server/src/com/vaadin/server/communication/UidlWriter.java
@@ -63,8 +63,6 @@ public class UidlWriter implements Serializable {
* The {@link UI} whose changes to write
* @param writer
* The writer to use
- * @param repaintAll
- * Whether the client should re-render the whole UI.
* @param analyzeLayouts
* Whether detected layout problems should be logged.
* @param async
@@ -74,8 +72,7 @@ public class UidlWriter implements Serializable {
* @throws IOException
* If the writing fails.
*/
- public void write(UI ui, Writer writer, boolean repaintAll, boolean async)
- throws IOException {
+ public void write(UI ui, Writer writer, boolean async) throws IOException {
VaadinSession session = ui.getSession();
VaadinService service = session.getService();
@@ -86,6 +83,8 @@ public class UidlWriter implements Serializable {
Set<ClientConnector> processedConnectors = new HashSet<ClientConnector>();
LegacyCommunicationManager manager = session.getCommunicationManager();
+ ClientCache clientCache = manager.getClientCache(ui);
+ boolean repaintAll = clientCache.isEmpty();
// Paints components
ConnectorTracker uiConnectorTracker = ui.getConnectorTracker();
getLogger().log(Level.FINE, "* Creating response to client");
@@ -130,7 +129,14 @@ public class UidlWriter implements Serializable {
.getCurrentSyncId() : -1;
writer.write("\"" + ApplicationConstants.SERVER_SYNC_ID + "\": "
+ syncId + ", ");
-
+ if (repaintAll) {
+ writer.write("\"" + ApplicationConstants.RESYNCHRONIZE_ID
+ + "\": true, ");
+ }
+ int nextClientToServerMessageId = ui
+ .getLastProcessedClientToServerId() + 1;
+ writer.write("\"" + ApplicationConstants.CLIENT_TO_SERVER_ID
+ + "\": " + nextClientToServerMessageId + ", ");
writer.write("\"changes\" : ");
JsonPaintTarget paintTarget = new JsonPaintTarget(manager, writer,
@@ -202,7 +208,6 @@ public class UidlWriter implements Serializable {
Collection<Class<? extends ClientConnector>> usedClientConnectors = paintTarget
.getUsedClientConnectors();
boolean typeMappingsOpen = false;
- ClientCache clientCache = manager.getClientCache(ui);
List<Class<? extends ClientConnector>> newConnectorTypes = new ArrayList<Class<? extends ClientConnector>>();
diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java
index 90ad28542c..6eaf683d99 100644
--- a/server/src/com/vaadin/ui/PushConfiguration.java
+++ b/server/src/com/vaadin/ui/PushConfiguration.java
@@ -207,8 +207,14 @@ class PushConfigurationImpl implements PushConfiguration {
@Override
public Transport getTransport() {
try {
- return Transport
+ Transport tr = Transport
.getByIdentifier(getParameter(PushConfigurationState.TRANSPORT_PARAM));
+ if (tr == Transport.WEBSOCKET
+ && getState(false).alwaysUseXhrForServerRequests) {
+ return Transport.WEBSOCKET_XHR;
+ } else {
+ return tr;
+ }
} catch (IllegalArgumentException e) {
return null;
}
@@ -223,8 +229,16 @@ class PushConfigurationImpl implements PushConfiguration {
*/
@Override
public void setTransport(Transport transport) {
- setParameter(PushConfigurationState.TRANSPORT_PARAM,
- transport.getIdentifier());
+ if (transport == Transport.WEBSOCKET_XHR) {
+ getState().alwaysUseXhrForServerRequests = true;
+ // Atmosphere knows only about "websocket"
+ setParameter(PushConfigurationState.TRANSPORT_PARAM,
+ Transport.WEBSOCKET.getIdentifier());
+ } else {
+ getState().alwaysUseXhrForServerRequests = false;
+ setParameter(PushConfigurationState.TRANSPORT_PARAM,
+ transport.getIdentifier());
+ }
}
/*
@@ -251,6 +265,10 @@ class PushConfigurationImpl implements PushConfiguration {
*/
@Override
public void setFallbackTransport(Transport fallbackTransport) {
+ if (fallbackTransport == Transport.WEBSOCKET_XHR) {
+ throw new IllegalArgumentException(
+ "WEBSOCKET_XHR can only be used as primary transport");
+ }
setParameter(PushConfigurationState.FALLBACK_TRANSPORT_PARAM,
fallbackTransport.getIdentifier());
}
diff --git a/server/src/com/vaadin/ui/ReconnectDialogConfiguration.java b/server/src/com/vaadin/ui/ReconnectDialogConfiguration.java
new file mode 100644
index 0000000000..92eb1e785f
--- /dev/null
+++ b/server/src/com/vaadin/ui/ReconnectDialogConfiguration.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.ui;
+
+import java.io.Serializable;
+
+/**
+ * Provides method for configuring the reconnect dialog.
+ *
+ * @since 7.6
+ * @author Vaadin Ltd
+ */
+public interface ReconnectDialogConfiguration extends Serializable {
+ /**
+ * Gets the text to show in the reconnect dialog when trying to re-establish
+ * the server connection
+ *
+ * @return the text to show in the reconnect dialog
+ */
+ public String getDialogText();
+
+ /**
+ * Sets the text to show in the reconnect dialog when trying to re-establish
+ * the server connection
+ *
+ * @param dialogText
+ * the text to show in the reconnect dialog
+ */
+ public void setDialogText(String dialogText);
+
+ /**
+ * Gets the text to show in the reconnect dialog after giving up trying to
+ * reconnect ({@link #getReconnectAttempts()} reached)
+ *
+ * @return the text to show in the reconnect dialog after giving up
+ */
+ public String getDialogTextGaveUp();
+
+ /**
+ * Sets the text to show in the reconnect dialog after giving up trying to
+ * reconnect ({@link #getReconnectAttempts()} reached)
+ *
+ * @param dialogText
+ * the text to show in the reconnect dialog after giving up
+ */
+ public void setDialogTextGaveUp(String dialogTextGaveUp);
+
+ /**
+ * Gets the number of times to try to reconnect to the server before giving
+ * up
+ *
+ * @return the number of times to try to reconnect
+ */
+ public int getReconnectAttempts();
+
+ /**
+ * Sets the number of times to try to reconnect to the server before giving
+ * up
+ *
+ * @param reconnectAttempts
+ * the number of times to try to reconnect
+ */
+ public void setReconnectAttempts(int reconnectAttempts);
+
+ /**
+ * Gets the interval (in milliseconds) between reconnect attempts
+ *
+ * @return the interval (in ms) between reconnect attempts
+ */
+ public int getReconnectInterval();
+
+ /**
+ * Sets the interval (in milliseconds) between reconnect attempts
+ *
+ * @param reconnectInterval
+ * the interval (in ms) between reconnect attempts
+ */
+ public void setReconnectInterval(int reconnectInterval);
+
+ /**
+ * Gets the timeout (in milliseconds) between noticing a loss of connection
+ * and showing the dialog.
+ *
+ * @return the time to wait before showing a dialog
+ */
+ public int getDialogGracePeriod();
+
+ /**
+ * Sets the timeout (in milliseconds) between noticing a loss of connection
+ * and showing the dialog.
+ *
+ * @param dialogGracePeriod
+ * the time to wait before showing a dialog
+ */
+ public void setDialogGracePeriod(int dialogGracePeriod);
+
+ /**
+ * Sets the modality of the dialog.
+ * <p>
+ * If the dialog is set to modal, it will prevent the usage of the
+ * application while the dialog is being shown. If not modal, the user can
+ * continue to use the application as normally and all server events will be
+ * queued until connection has been re-established.
+ *
+ * @param dialogModal
+ * true to make the dialog modal, false otherwise
+ */
+ public void setDialogModal(boolean dialogModal);
+
+ /**
+ * Checks the modality of the dialog.
+ * <p>
+ *
+ * @see #setDialogModal(boolean)
+ * @return true if the dialog is modal, false otherwise
+ */
+ public boolean isDialogModal();
+}
+
+class ReconnectDialogConfigurationImpl implements ReconnectDialogConfiguration {
+ private UI ui;
+
+ public ReconnectDialogConfigurationImpl(UI ui) {
+ this.ui = ui;
+ }
+
+ @Override
+ public String getDialogText() {
+ return ui.getState(false).reconnectDialogConfiguration.dialogText;
+ }
+
+ @Override
+ public void setDialogText(String dialogText) {
+ ui.getState().reconnectDialogConfiguration.dialogText = dialogText;
+ }
+
+ @Override
+ public String getDialogTextGaveUp() {
+ return ui.getState(false).reconnectDialogConfiguration.dialogTextGaveUp;
+ }
+
+ @Override
+ public void setDialogTextGaveUp(String dialogTextGaveUp) {
+ ui.getState().reconnectDialogConfiguration.dialogTextGaveUp = dialogTextGaveUp;
+ }
+
+ @Override
+ public int getReconnectAttempts() {
+ return ui.getState(false).reconnectDialogConfiguration.reconnectAttempts;
+ }
+
+ @Override
+ public void setReconnectAttempts(int reconnectAttempts) {
+ ui.getState().reconnectDialogConfiguration.reconnectAttempts = reconnectAttempts;
+ }
+
+ @Override
+ public int getReconnectInterval() {
+ return ui.getState(false).reconnectDialogConfiguration.reconnectInterval;
+ }
+
+ @Override
+ public void setReconnectInterval(int reconnectInterval) {
+ ui.getState().reconnectDialogConfiguration.reconnectInterval = reconnectInterval;
+ }
+
+ @Override
+ public int getDialogGracePeriod() {
+ return ui.getState(false).reconnectDialogConfiguration.dialogGracePeriod;
+ }
+
+ @Override
+ public void setDialogGracePeriod(int dialogGracePeriod) {
+ ui.getState().reconnectDialogConfiguration.dialogGracePeriod = dialogGracePeriod;
+ }
+
+ @Override
+ public boolean isDialogModal() {
+ return ui.getState(false).reconnectDialogConfiguration.dialogModal;
+ }
+
+ @Override
+ public void setDialogModal(boolean dialogModal) {
+ ui.getState().reconnectDialogConfiguration.dialogModal = dialogModal;
+ }
+
+}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 2129db614b..90ae713746 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -255,11 +255,19 @@ public abstract class UI extends AbstractSingleComponentContainer implements
this);
private PushConfiguration pushConfiguration = new PushConfigurationImpl(
this);
+ private ReconnectDialogConfiguration reconnectDialogConfiguration = new ReconnectDialogConfigurationImpl(
+ this);
private NotificationConfiguration notificationConfiguration = new NotificationConfigurationImpl(
this);
/**
+ * Tracks which message from the client should come next. First message from
+ * the client has id 0.
+ */
+ private int lastProcessedClientToServerId = -1;
+
+ /**
* Creates a new empty UI without a caption. The content of the UI must be
* set by calling {@link #setContent(Component)} before using the UI.
*/
@@ -1640,6 +1648,16 @@ public abstract class UI extends AbstractSingleComponentContainer implements
}
/**
+ * Retrieves the object used for configuring the reconnect dialog.
+ *
+ * @since 7.6
+ * @return The instance used for reconnect dialog configuration
+ */
+ public ReconnectDialogConfiguration getReconnectDialogConfiguration() {
+ return reconnectDialogConfiguration;
+ }
+
+ /**
* Get the label that is added to the container element, where tooltip,
* notification and dialogs are added to.
*
@@ -1691,4 +1709,31 @@ public abstract class UI extends AbstractSingleComponentContainer implements
public String getEmbedId() {
return embedId;
}
+
+ /**
+ * Gets the last processed server message id.
+ *
+ * Used internally for communication tracking.
+ *
+ * @return lastProcessedServerMessageId the id of the last processed server
+ * message
+ * @since 7.6
+ */
+ public int getLastProcessedClientToServerId() {
+ return lastProcessedClientToServerId;
+ }
+
+ /**
+ * Sets the last processed server message id.
+ *
+ * Used internally for communication tracking.
+ *
+ * @param lastProcessedServerMessageId
+ * the id of the last processed server message
+ * @since 7.6
+ */
+ public void setLastProcessedClientToServerId(
+ int lastProcessedClientToServerId) {
+ this.lastProcessedClientToServerId = lastProcessedClientToServerId;
+ }
}
diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java
index 693bd74dbf..2da7db53b5 100644
--- a/server/src/com/vaadin/ui/Upload.java
+++ b/server/src/com/vaadin/ui/Upload.java
@@ -121,6 +121,11 @@ public class Upload extends AbstractComponent implements Component.Focusable,
public void change(String filename) {
fireEvent(new ChangeEvent(Upload.this, filename));
}
+
+ @Override
+ public void poll() {
+ // Nothing to do, called only to visit the server
+ }
});
}
diff --git a/server/tests/src/com/vaadin/ui/PushConfigurationTransportTest.java b/server/tests/src/com/vaadin/ui/PushConfigurationTransportTest.java
index 305b2e06cd..80e7dd9261 100644
--- a/server/tests/src/com/vaadin/ui/PushConfigurationTransportTest.java
+++ b/server/tests/src/com/vaadin/ui/PushConfigurationTransportTest.java
@@ -40,6 +40,12 @@ public class PushConfigurationTransportTest {
ui.getPushConfiguration().setTransport(transport);
Assert.assertEquals(ui.getPushConfiguration().getTransport(),
transport);
+
+ if (transport == Transport.WEBSOCKET_XHR) {
+ Assert.assertTrue(ui.getState().pushConfiguration.alwaysUseXhrForServerRequests);
+ } else {
+ Assert.assertFalse(ui.getState().pushConfiguration.alwaysUseXhrForServerRequests);
+ }
}
}