From edca4095d2e75d73f9d6a5acb2da9009129b4db2 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 5 Jun 2013 14:27:09 +0300 Subject: [PATCH] Allow customizing client-side push config on server side (#11867) Change-Id: I212067aa0bd04e3e73844ef57963b5622291986a --- .../vaadin/client/ApplicationConnection.java | 7 +- .../AtmospherePushConnection.java | 15 +- .../client/communication/PushConnection.java | 2 + .../com/vaadin/client/ui/ui/UIConnector.java | 5 +- .../src/com/vaadin/server/VaadinSession.java | 2 +- .../server/communication/PushHandler.java | 2 +- .../server/communication/UIInitHandler.java | 2 +- .../src/com/vaadin/ui/PushConfiguration.java | 282 ++++++++++++++++++ server/src/com/vaadin/ui/UI.java | 55 +--- .../com/vaadin/shared/ui/ui/Transport.java | 55 ++++ .../src/com/vaadin/shared/ui/ui/UIState.java | 22 +- .../vaadin/tests/push/PushConfiguration.html | 130 ++++++++ .../tests/push/PushConfigurationTest.java | 102 +++++++ .../vaadin/tests/push/PushConfigurator.java | 152 ++++++++++ .../src/com/vaadin/tests/push/TogglePush.java | 13 +- .../client/TestingPushConnection.java | 4 +- 16 files changed, 784 insertions(+), 66 deletions(-) create mode 100644 server/src/com/vaadin/ui/PushConfiguration.java create mode 100644 shared/src/com/vaadin/shared/ui/ui/Transport.java create mode 100644 uitest/src/com/vaadin/tests/push/PushConfiguration.html create mode 100644 uitest/src/com/vaadin/tests/push/PushConfigurationTest.java create mode 100644 uitest/src/com/vaadin/tests/push/PushConfigurator.java diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index a3279e5631..ac058b5536 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -95,6 +95,7 @@ import com.vaadin.shared.communication.LegacyChangeVariablesInvocation; import com.vaadin.shared.communication.MethodInvocation; import com.vaadin.shared.communication.SharedState; import com.vaadin.shared.ui.ui.UIConstants; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; /** * This is the client side communication "engine", managing client-server @@ -3359,9 +3360,11 @@ public class ApplicationConnection { * false to disable the push connection. */ public void setPushEnabled(boolean enabled) { + final PushConfigurationState pushState = uIConnector.getState().pushConfiguration; + if (enabled && push == null) { push = GWT.create(PushConnection.class); - push.init(this, new CommunicationErrorHandler() { + push.init(this, pushState, new CommunicationErrorHandler() { @Override public boolean onError(String details, int statusCode) { showCommunicationError(details, statusCode); @@ -3378,7 +3381,7 @@ public class ApplicationConnection { * the old connection to disconnect, now is the right time * to open a new connection */ - if (uIConnector.getState().pushMode.isEnabled()) { + if (pushState.mode.isEnabled()) { setPushEnabled(true); } diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java index 997e84145c..f7936f8717 100644 --- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java +++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java @@ -30,6 +30,7 @@ import com.vaadin.client.VConsole; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.communication.PushConstants; import com.vaadin.shared.ui.ui.UIConstants; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; /** * The default {@link PushConnection} implementation that uses Atmosphere for @@ -133,15 +134,22 @@ public class AtmospherePushConnection implements PushConnection { * (non-Javadoc) * * @see - * com.vaadin.client.communication.PushConenction#init(com.vaadin.client - * .ApplicationConnection) + * com.vaadin.client.communication.PushConnection#init(ApplicationConnection + * , Map, CommunicationErrorHandler) */ @Override public void init(final ApplicationConnection connection, + final PushConfigurationState pushConfiguration, CommunicationErrorHandler errorHandler) { this.connection = connection; this.errorHandler = errorHandler; + config = createConfig(); + for (String param : pushConfiguration.parameters.keySet()) { + config.setStringValue(param, + pushConfiguration.parameters.get(param)); + } + runWhenAtmosphereLoaded(new Command() { @Override public void execute() { @@ -216,9 +224,6 @@ public class AtmospherePushConnection implements PushConnection { } protected AtmosphereConfiguration getConfig() { - if (config == null) { - config = createConfig(); - } return config; } diff --git a/client/src/com/vaadin/client/communication/PushConnection.java b/client/src/com/vaadin/client/communication/PushConnection.java index a4a3bbc0cc..bc2af98f1a 100644 --- a/client/src/com/vaadin/client/communication/PushConnection.java +++ b/client/src/com/vaadin/client/communication/PushConnection.java @@ -19,6 +19,7 @@ package com.vaadin.client.communication; import com.google.gwt.user.client.Command; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ApplicationConnection.CommunicationErrorHandler; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; /** * Represents the client-side endpoint of a bidirectional ("push") communication @@ -39,6 +40,7 @@ public interface PushConnection { * The ApplicationConnection */ public void init(ApplicationConnection connection, + PushConfigurationState pushConfigurationState, CommunicationErrorHandler errorHandler); /** diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index 1c2c6ddeb8..45b0a7ab9d 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -644,8 +644,9 @@ public class UIConnector extends AbstractSingleComponentContainerConnector configurePolling(); } - if (stateChangeEvent.hasPropertyChanged("pushMode")) { - getConnection().setPushEnabled(getState().pushMode.isEnabled()); + if (stateChangeEvent.hasPropertyChanged("pushConfiguration")) { + getConnection().setPushEnabled( + getState().pushConfiguration.mode.isEnabled()); } if (stateChangeEvent.hasPropertyChanged("overlayContainerLabel")) { diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java index 889eadcd6f..e0a5b51baa 100644 --- a/server/src/com/vaadin/server/VaadinSession.java +++ b/server/src/com/vaadin/server/VaadinSession.java @@ -902,7 +902,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { getService().runPendingAccessTasks(this); for (UI ui : getUIs()) { - if (ui.getPushMode() == PushMode.AUTOMATIC) { + if (ui.getPushConfiguration().getPushMode() == PushMode.AUTOMATIC) { ui.push(); } } diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java index a44df79221..7efcb8fd8c 100644 --- a/server/src/com/vaadin/server/communication/PushHandler.java +++ b/server/src/com/vaadin/server/communication/PushHandler.java @@ -171,7 +171,7 @@ public class PushHandler implements AtmosphereHandler { PushEventCallback disconnectCallback = new PushEventCallback() { @Override public void run(AtmosphereResource resource, UI ui) throws IOException { - PushMode pushMode = ui.getPushMode(); + PushMode pushMode = ui.getPushConfiguration().getPushMode(); AtmospherePushConnection pushConnection = getConnectionForUI(ui); String id = resource.uuid(); diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java index 8507bf40cc..9807ea6a9f 100644 --- a/server/src/com/vaadin/server/communication/UIInitHandler.java +++ b/server/src/com/vaadin/server/communication/UIInitHandler.java @@ -209,7 +209,7 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { pushMode = session.getService().getDeploymentConfiguration() .getPushMode(); } - ui.setPushMode(pushMode); + ui.getPushConfiguration().setPushMode(pushMode); // Set thread local here so it is available in init UI.setCurrent(ui); diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java new file mode 100644 index 0000000000..a592b39bef --- /dev/null +++ b/server/src/com/vaadin/ui/PushConfiguration.java @@ -0,0 +1,282 @@ +/* + * Copyright 2000-2013 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; +import java.util.Collection; +import java.util.Collections; + +import com.vaadin.server.VaadinSession; +import com.vaadin.shared.communication.PushMode; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; + +/** + * Provides method for configuring the push channel. + * + * @since 7.1 + * @author Vaadin Ltd + */ +public interface PushConfiguration extends Serializable { + + /** + * Returns the mode of bidirectional ("push") communication that is used. + * + * @return The push mode. + */ + public PushMode getPushMode(); + + /** + * Sets the mode of bidirectional ("push") communication that should be + * used. + *

+ * Add-on developers should note that this method is only meant for the + * application developer. An add-on should not set the push mode directly, + * rather instruct the user to set it. + *

+ * + * @param pushMode + * The push mode to use. + * + * @throws IllegalArgumentException + * if the argument is null. + * @throws IllegalStateException + * if push support is not available. + */ + public void setPushMode(PushMode pushMode); + + /** + * Returns the primary transport type for push. + *

+ * Note that if you set the transport type using + * {@link #setParameter(String, String)} to an unsupported type this method + * will return null. Supported types are defined by {@link Transport}. + * + * @return The primary transport type + */ + public Transport getTransport(); + + /** + * Sets the primary transport type for push. + *

+ * Note that the new transport type will not be used until the push channel + * is disconnected and reconnected if already active. + * + * @param transport + * The primary transport type + */ + public void setTransport(Transport transport); + + /** + * Returns the fallback transport type for push. + *

+ * Note that if you set the transport type using + * {@link #setParameter(String, String)} to an unsupported type this method + * will return null. Supported types are defined by {@link Transport}. + * + * @return The fallback transport type + */ + public Transport getFallbackTransport(); + + /** + * Sets the fallback transport type for push. + *

+ * Note that the new transport type will not be used until the push channel + * is disconnected and reconnected if already active. + * + * @param fallbackTransport + * The fallback transport type + */ + public void setFallbackTransport(Transport fallbackTransport); + + /** + * Returns the given parameter, if set. + *

+ * This method provides low level access to push parameters and is typically + * not needed for normal application development. + * + * @since 7.1 + * @param parameter + * The parameter name + * @return The parameter value or null if not set + */ + public String getParameter(String parameter); + + /** + * Returns the parameters which have been defined. + * + * @since 7.1 + * @return A collection of parameter names + */ + public Collection getParameterNames(); + + /** + * Sets the given parameter. + *

+ * This method provides low level access to push parameters and is typically + * not needed for normal application development. + * + * @since 7.1 + * @param parameter + * The parameter name + * @param value + * The value + */ + public void setParameter(String parameter, String value); + +} + +class PushConfigurationImpl implements PushConfiguration { + private UI ui; + + public PushConfigurationImpl(UI ui) { + this.ui = ui; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.PushConfiguration#getPushMode() + */ + @Override + public PushMode getPushMode() { + return getState(false).mode; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.PushConfiguration#setPushMode(com.vaadin.shared.communication + * .PushMode) + */ + @Override + public void setPushMode(PushMode pushMode) { + if (pushMode == null) { + throw new IllegalArgumentException("Push mode cannot be null"); + } + + if (pushMode.isEnabled()) { + VaadinSession session = ui.getSession(); + if (session != null && !session.getService().ensurePushAvailable()) { + throw new IllegalStateException( + "Push is not available. See previous log messages for more information."); + } + } + + /* + * Client-side will open a new connection or disconnect the old + * connection, so there's nothing more to do on the server at this + * point. + */ + getState().mode = pushMode; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.PushConfiguration#getTransport() + */ + @Override + public Transport getTransport() { + try { + return Transport + .valueOf(getParameter(PushConfigurationState.TRANSPORT_PARAM)); + } catch (IllegalArgumentException e) { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.PushConfiguration#setTransport(com.vaadin.shared.ui.ui. + * Transport) + */ + @Override + public void setTransport(Transport transport) { + setParameter(PushConfigurationState.TRANSPORT_PARAM, + transport.getIdentifier()); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.PushConfiguration#getFallbackTransport() + */ + @Override + public Transport getFallbackTransport() { + try { + return Transport + .valueOf(getParameter(PushConfigurationState.FALLBACK_TRANSPORT_PARAM)); + } catch (IllegalArgumentException e) { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.PushConfiguration#setFallbackTransport(com.vaadin.shared + * .ui.ui.Transport) + */ + @Override + public void setFallbackTransport(Transport fallbackTransport) { + setParameter(PushConfigurationState.FALLBACK_TRANSPORT_PARAM, + fallbackTransport.getIdentifier()); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.PushConfiguration#getParameter(java.lang.String) + */ + @Override + public String getParameter(String parameter) { + return getState(false).parameters.get(parameter); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.PushConfiguration#setParameter(java.lang.String, + * java.lang.String) + */ + @Override + public void setParameter(String parameter, String value) { + getState().parameters.put(parameter, value); + + } + + private PushConfigurationState getState() { + return ui.getState().pushConfiguration; + } + + private PushConfigurationState getState(boolean markAsDirty) { + return ui.getState(markAsDirty).pushConfiguration; + } + + @Override + public Collection getParameterNames() { + return Collections + .unmodifiableCollection(ui.getState(false).pushConfiguration.parameters + .keySet()); + } + +} diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 2c6283377a..6159298a69 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -48,7 +48,6 @@ import com.vaadin.server.communication.PushConnection; import com.vaadin.shared.Connector; import com.vaadin.shared.EventId; import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.ui.ui.DebugWindowClientRpc; import com.vaadin.shared.ui.ui.DebugWindowServerRpc; import com.vaadin.shared.ui.ui.ScrollClientRpc; @@ -216,6 +215,8 @@ public abstract class UI extends AbstractSingleComponentContainer implements private TooltipConfiguration tooltipConfiguration = new TooltipConfigurationImpl( this); + private PushConfiguration pushConfiguration = new PushConfigurationImpl( + this); /** * Creates a new empty UI without a caption. The content of the UI must be @@ -1325,7 +1326,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements return; } - if (!getPushMode().isEnabled()) { + if (!getPushConfiguration().getPushMode().isEnabled()) { throw new IllegalStateException("Push not enabled"); } @@ -1353,7 +1354,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements */ public void setPushConnection(PushConnection pushConnection) { // If pushMode is disabled then there should never be a pushConnection - assert (getPushMode().isEnabled() || pushConnection == null); + assert (getPushConfiguration().getPushMode().isEnabled() || pushConnection == null); if (pushConnection == this.pushConnection) { return; @@ -1402,51 +1403,13 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** - * Returns the mode of bidirectional ("push") communication that is used in - * this UI. - * - * @return The push mode. - */ - public PushMode getPushMode() { - return getState(false).pushMode; - } - - /** - * Sets the mode of bidirectional ("push") communication that should be used - * in this UI. - *

- * Add-on developers should note that this method is only meant for the - * application developer. An add-on should not set the push mode directly, - * rather instruct the user to set it. - *

+ * Retrieves the object used for configuring the push channel. * - * @param pushMode - * The push mode to use. - * - * @throws IllegalArgumentException - * if the argument is null. - * @throws IllegalStateException - * if push support is not available. + * @since 7.1 + * @return The instance used for push configuration */ - public void setPushMode(PushMode pushMode) { - if (pushMode == null) { - throw new IllegalArgumentException("Push mode cannot be null"); - } - - if (pushMode.isEnabled()) { - VaadinSession session = getSession(); - if (session != null && !session.getService().ensurePushAvailable()) { - throw new IllegalStateException( - "Push is not available. See previous log messages for more information."); - } - } - - /* - * Client-side will open a new connection or disconnect the old - * connection, so there's nothing more to do on the server at this - * point. - */ - getState().pushMode = pushMode; + public PushConfiguration getPushConfiguration() { + return pushConfiguration; } /** diff --git a/shared/src/com/vaadin/shared/ui/ui/Transport.java b/shared/src/com/vaadin/shared/ui/ui/Transport.java new file mode 100644 index 0000000000..69d713bcca --- /dev/null +++ b/shared/src/com/vaadin/shared/ui/ui/Transport.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2013 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.shared.ui.ui; + +/** + * Transport modes for Push + * + * @since 7.1 + * @author Vaadin Ltd + */ +public enum Transport { + /** + * Websockets + */ + WEBSOCKET("websocket"), + /** + * HTTP streaming + */ + STREAMING("streaming"); + + /** + * The default transport mechanism for push + */ + public static final Transport DEFAULT = Transport.WEBSOCKET; + + /** + * The default fallback transport mechanism for push + */ + public static final Transport DEFAULT_FALLBACK = Transport.STREAMING; + + private String identifier; + + private Transport(String identifier) { + this.identifier = identifier; + } + + public String getIdentifier() { + return identifier; + } + +} diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java index 177fe2e7bd..e19a87ada9 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIState.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java @@ -17,7 +17,9 @@ package com.vaadin.shared.ui.ui; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.ui.TabIndexState; @@ -27,8 +29,6 @@ public class UIState extends TabIndexState { public LoadingIndicatorConfigurationState loadingIndicatorConfiguration = new LoadingIndicatorConfigurationState(); public int pollInterval = -1; - public PushMode pushMode = PushMode.DISABLED; - // Informing users of assistive devices, that the content of this container // is announced automatically and does not need to be navigated into public String overlayContainerLabel = "This content is announced automatically and does not need to be navigated into."; @@ -48,6 +48,19 @@ public class UIState extends TabIndexState { public int maxWidth = 500; } + public static class PushConfigurationState implements Serializable { + public static final String TRANSPORT_PARAM = "transport"; + public static final String FALLBACK_TRANSPORT_PARAM = "fallbackTransport"; + + public PushMode mode = PushMode.DISABLED; + public Map parameters = new HashMap(); + { + parameters.put(TRANSPORT_PARAM, Transport.DEFAULT.getIdentifier()); + parameters.put(FALLBACK_TRANSPORT_PARAM, + Transport.DEFAULT_FALLBACK.getIdentifier()); + } + } + /** * State related to the Page class. */ @@ -57,6 +70,11 @@ public class UIState extends TabIndexState { */ public LocaleServiceState localeServiceState = new LocaleServiceState(); + /** + * Configuration for the push channel + */ + public PushConfigurationState pushConfiguration = new PushConfigurationState(); + { primaryStyleName = "v-ui"; // Default is 1 for legacy reasons diff --git a/uitest/src/com/vaadin/tests/push/PushConfiguration.html b/uitest/src/com/vaadin/tests/push/PushConfiguration.html new file mode 100644 index 0000000000..c3786b1cc1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushConfiguration.html @@ -0,0 +1,130 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.push.PushConfigurationTest?debug&restartApplication
assertNotTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
selectvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]label=WEBSOCKET
assertNotTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
selectvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]label=AUTOMATIC
assertTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]*fallbackTransport: streaming*transport: websocket*
assertNotTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
waitForTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
assertTextPresentPush connection established using websocket
assertTextNotPresentPush connection established using streamingPush connection established using streaming
selectvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]label=DISABLED
open/run/com.vaadin.tests.push.PushConfigurationTest?debug&restartApplication
assertNotTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
selectvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]label=STREAMING
assertNotTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
selectvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]label=AUTOMATIC
assertNotTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
assertTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]*fallbackTransport: streaming*transport: streaming*
waitForTextvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]4
assertTextNotPresentPush connection established using websocket
assertTextPresentPush connection established using streaming
selectvaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]label=DISABLED
+ + diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java new file mode 100644 index 0000000000..b57e9732cc --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java @@ -0,0 +1,102 @@ +package com.vaadin.tests.push; + +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; + +public class PushConfigurationTest extends AbstractTestUI { + + private ObjectProperty counter = new ObjectProperty(0); + + private ObjectProperty counter2 = new ObjectProperty(0); + + private final Timer timer = new Timer(true); + + private final TimerTask task = new TimerTask() { + + @Override + public void run() { + access(new Runnable() { + @Override + public void run() { + counter2.setValue(counter2.getValue() + 1); + } + }); + } + }; + + @Override + protected void setup(VaadinRequest request) { + addComponent(new PushConfigurator(this)); + spacer(); + + /* + * Client initiated push. + */ + Label lbl = new Label(counter); + lbl.setCaption("Client counter (click 'increment' to update):"); + addComponent(lbl); + + addComponent(new Button("Increment", new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + counter.setValue(counter.getValue() + 1); + } + })); + + spacer(); + + /* + * Server initiated push. + */ + lbl = new Label(counter2); + lbl.setCaption("Server counter (updates each 1s by server thread) :"); + addComponent(lbl); + + addComponent(new Button("Reset", new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + counter2.setValue(0); + } + })); + } + + @Override + protected String getTestDescription() { + return "This test tests the very basic operations of push. " + + "It tests that client initiated changes are " + + "recieved back to the client as well as server " + + "initiated changes are correctly updated to the client."; + } + + @Override + protected Integer getTicketNumber() { + return 11494; + } + + private void spacer() { + addComponent(new Label("
", ContentMode.HTML)); + } + + @Override + public void attach() { + super.attach(); + timer.scheduleAtFixedRate(task, new Date(), 1000); + } + + @Override + public void detach() { + super.detach(); + timer.cancel(); + } +} diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurator.java b/uitest/src/com/vaadin/tests/push/PushConfigurator.java new file mode 100644 index 0000000000..6528366b59 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushConfigurator.java @@ -0,0 +1,152 @@ +/* + * Copyright 2000-2013 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.tests.push; + +import java.util.ArrayList; +import java.util.Collections; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.shared.communication.PushMode; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.PushConfiguration; +import com.vaadin.ui.TextField; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +/** + * + * @since 7.1 + * @author Vaadin Ltd + */ +public class PushConfigurator extends VerticalLayout { + private NativeSelect pushMode = new NativeSelect("Push mode"); + private NativeSelect transport = new NativeSelect("Transport"); + private NativeSelect fallbackTransport = new NativeSelect("Fallback"); + private TextField parameter = new TextField("Parameter"); + private TextField value = new TextField("Value"); + private Button set = new Button("Set"); + private HorizontalLayout paramValue = new HorizontalLayout(); + private VerticalLayout vl = new VerticalLayout(); + private UI ui; + + private Label status = new Label("", ContentMode.PREFORMATTED); + + public PushConfigurator(UI ui) { + this.ui = ui; + construct(); + refreshStatus(); + } + + /** + * @since + */ + private void refreshStatus() { + PushConfiguration pc = ui.getPushConfiguration(); + String value = ""; + ArrayList names = new ArrayList(); + names.addAll(pc.getParameterNames()); + Collections.sort(names); + for (String param : names) { + value += param + ": " + pc.getParameter(param) + "\n"; + } + status.setValue(value); + } + + /** + * @since + */ + private void construct() { + pushMode.addItem(PushMode.DISABLED); + pushMode.addItem(PushMode.MANUAL); + pushMode.addItem(PushMode.AUTOMATIC); + + for (Transport t : Transport.values()) { + transport.addItem(t.toString()); + fallbackTransport.addItem(t.toString()); + } + transport.addItem(""); + fallbackTransport.addItem(""); + + pushMode.setImmediate(true); + transport.setImmediate(true); + fallbackTransport.setImmediate(true); + + listeners(); + + paramValue.setDefaultComponentAlignment(Alignment.BOTTOM_RIGHT); + paramValue.addComponents(parameter, value, set); + vl.addComponents(pushMode, transport, fallbackTransport, paramValue, + new Label("
", ContentMode.HTML), status); + addComponent(vl); + + } + + /** + * @since + */ + private void listeners() { + pushMode.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + ui.getPushConfiguration().setPushMode( + (PushMode) pushMode.getValue()); + refreshStatus(); + } + }); + + transport.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + Transport t = Transport.valueOf((String) transport.getValue()); + ui.getPushConfiguration().setTransport(t); + refreshStatus(); + } + }); + + fallbackTransport.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + Transport t = Transport.valueOf((String) fallbackTransport + .getValue()); + ui.getPushConfiguration().setFallbackTransport(t); + refreshStatus(); + } + }); + + set.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + ui.getPushConfiguration().setParameter(parameter.getValue(), + value.getValue()); + refreshStatus(); + } + }); + + } +} diff --git a/uitest/src/com/vaadin/tests/push/TogglePush.java b/uitest/src/com/vaadin/tests/push/TogglePush.java index 37687260dd..c0bdc54ee0 100644 --- a/uitest/src/com/vaadin/tests/push/TogglePush.java +++ b/uitest/src/com/vaadin/tests/push/TogglePush.java @@ -22,19 +22,22 @@ public class TogglePush extends AbstractTestUI { updateCounter(); addComponent(counterLabel); - setPushMode("disabled".equals(request.getParameter("push")) ? PushMode.DISABLED - : PushMode.AUTOMATIC); + getPushConfiguration() + .setPushMode( + "disabled".equals(request.getParameter("push")) ? PushMode.DISABLED + : PushMode.AUTOMATIC); CheckBox pushSetting = new CheckBox("Push enabled"); - pushSetting.setValue(Boolean.valueOf(getPushMode().isEnabled())); + pushSetting.setValue(Boolean.valueOf(getPushConfiguration() + .getPushMode().isEnabled())); pushSetting.setImmediate(true); pushSetting.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { if (event.getProperty().getValue() == Boolean.TRUE) { - setPushMode(PushMode.AUTOMATIC); + getPushConfiguration().setPushMode(PushMode.AUTOMATIC); } else { - setPushMode(PushMode.DISABLED); + getPushConfiguration().setPushMode(PushMode.DISABLED); } } }); diff --git a/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java b/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java index e255a5f95a..4dae8892e7 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java @@ -4,6 +4,7 @@ import com.google.gwt.user.client.Window; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ApplicationConnection.CommunicationErrorHandler; import com.vaadin.client.communication.AtmospherePushConnection; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; public class TestingPushConnection extends AtmospherePushConnection { @@ -11,8 +12,9 @@ public class TestingPushConnection extends AtmospherePushConnection { @Override public void init(ApplicationConnection connection, + PushConfigurationState pushConfiguration, CommunicationErrorHandler errorHandler) { - super.init(connection, errorHandler); + super.init(connection, pushConfiguration, errorHandler); transport = Window.Location.getParameter("transport"); } -- 2.39.5